资讯详情

MicroPython-On-ESP8266——数码管的使用,2片HC595驱动四位数码管

MicroPython-On-ESP8266——数码管的使用,2片HC595驱动四位数字管

1. 背景

在前面使用四位数字管时,需要12个GPIO接口,结果我们micropython能驱动的esp8266开发板只能用9个口,只能驱动两位数字管。幸运的是,使用了动态扫描机制。

回来学习第三个数字管,两个72HC四位数码管由595位移寄存器芯片驱动。

在这里插入图片描述

2. 74位移寄存器芯片HC595

先了解一下这74HC595芯片(以下简称595)是什么,是如何工作的。

2.1. 595原理图

符号 引脚 描述
Q0–Q7 第15脚,第1-7脚 8位并行数据输出 (DS引脚发送的位数据可以依次推入这8个位,达到串入并出的效果。8个输出可用于控制数字管或位码(理论上可控制8位数字管)的8个段码
GND 第8脚
Q7’ 第9脚 串行数据输出(只有8个移位寄存器,当数据继续发送到内部时,引脚会溢出到初始位置。溢出位置可以发送到下一个595芯片,以实现无限串联。
/MR 第10脚 主复位(低电平清零数据通常收到VCC防止数据被清除)
SH_CP 第11脚 时钟线的数据输入
ST_CP 第12脚 输出存储器定时钟线
/OE 第13脚 输出有效(低电平有效,数码管闪烁的效果可以通过控制这个引脚(一开一关就是闪烁)
DS 第14脚 串行数据输入(接收数据位的引脚,如果是串联,则按595芯片Q7’引脚)
VCC 第16脚 电源

2.2. 595使用流程

在上面的引脚说明中,除了上面的引脚说明之外,已经把除了 SH_CP 和 ST_CP 其他引脚注意事项写进去,核心两个单独说明:

首先,595芯片有两个寄存器:

  • :负责将DS引脚的当前数据状态已推入Q同时,0数据位Q0->Q1->Q2–>Q3–>…–>Q7会依次向后推一个,可以想象成左轮手枪。如果你塞子弹,你必须轮子,然后塞子弹。每轮子弹的位置都会顺移。
  • :锁定当前输出到位移寄存器的数据Qx保持引脚不变。就像你把左轮子弹装满或者不填满后,把轮子推到枪体上,位置就固定了。

问题来了,DS引脚用用来塞子弹的。什么时候转一轮(产生位移),什么时候推左轮(锁定)?这需要另外两个595芯片的引脚。

  • :沿时数据寄存器的数据移位引脚上升。
  • :沿时移位寄存器的数据上升到数据存储寄存器,沿时存储寄存器的数据保持不变。

也就是说,当我们需要移位时,我们通常会把这两个引脚的电平放低SH_CP拉需要锁定时,把它拉高ST_CP拉高引脚,只需要很长时间。短到微秒,我们在micropython没有微秒级的延迟函数,直接不延迟。

3. 两片595驱动数码管的原理

让我们从数字管模块的原理图中分析 1)首先,它对引脚名的定义与以上不同,没关系,仔细对比就能看清楚:

  • SER引脚就是DS引脚,用来装子弹,在包装模块上引出弯头,丝印名称是DIO
  • SCLK引脚用于控制位移
  • RCLK引脚用于控制锁定Qx数据口
  • QA-QH共有8个数据输出(跟上)Q0-Q7一样的)

2)上半部分数码管的引脚图不用理会,段码A到DP,从左到右分别有四个数字管DIG0到DIG3.下半部分有两片595片。从蓝色圈的部分可以看出,左边的第一片芯片只有四个位置来控制DIGx,指定的管道位置可以用高电平点亮;右侧的第二个芯片,用满8个位置输出,正好对应数字管的段码。

3)右边的595芯片的数据输入是由左边芯片溢出得到的(SER引脚接入左侧QH’输出)。那咱们要想驱动数码管点亮,就要先将显示数字的段码输出到DIO引脚,然后输出数字显示在哪个管位上的位码DIO引脚,然后一锁就一起工作。

4)还应强调,根据目前的驱动模式,为了在数字管的不同位置显示不同的数字,仍然需要使用动态扫描的原理,即利用人眼视觉暂留机制快速更改不同的位码。但我们不需要手动控制DIGx开关,直接输入不断变化的位码到595。

4. 实验:点亮数字管并显示自增长的数字

4.1. 接线图

4.2. 实验代码

from machine import Pin # import utime  # 准备数据引脚 pin_sclk = Pin(4, Pin.OUT); pin_sclk.off()  # 上升跳变时锁存
pin_rlck = Pin(0, Pin.OUT); pin_rlck.off()  # 上升跳变时数据位移
pin_dio = Pin(2, Pin.OUT); pin_dio.off()    # 待移入数据位

mapper = { 
          # 共阳方式段码对照
    '0': 0xC0, '1': 0xF9, '2': 0xA4, '3': 0xB0,
    '4': 0x99, '5': 0x92, '6': 0x82, '7': 0xF8,
    '8': 0x80, '9': 0x90, 'A': 0x88, 'B': 0x83,
    'C': 0xA7, 'D': 0xA1, 'E': 0x86, 'F': 0x8E,
}

def jump_up(pin):
    pin.on()  # 产生跳变
    # utime.sleep_ms(1)
    pin.off()  # 保持一段时间后关闭

def send_data(num, is_position=False, has_point=False):
    '向位称寄存器送数据'
    if is_position:  # 位码处理( 1~4位)
        value = { 
        1:0x01, 2:0x02, 3:0x04, 4:0x08}.get(num, 0)
    else:  # 段码处理
        value = mapper.get(str(num), 0)
        value = value & 0x7F if has_point else value  # 共阳方式
        # value = (~value | 0x80) if has_point else ~value # 共阴方式
    for i in range(8):
        pin_dio.value(1 if (value << i) & 0x80 else 0)  # 从最高位开始送数据
        jump_up(pin_sclk)  # 每送完一位后就让位移寄存器跳变一下

num = 0
step = 1
while True:
    # 显示千位
    send_data(int(num/1000))
    send_data(4, is_position=True)
    jump_up(pin_rlck)
    # 显示百位
    send_data(int(num / 100 % 10))
    send_data(3, is_position=True)
    jump_up(pin_rlck)
    # 显示十位
    send_data(int(num / 10 % 10))
    send_data(2, is_position=True)
    jump_up(pin_rlck)
    # 显示个位
    send_data(int(num % 10))
    send_data(1, is_position=True)
    jump_up(pin_rlck)

    if step%100==0:
        num += 1
        if num>9999: num=0
    step += 1

4.3. 效果

5. 后记

我手上有的数码管至此已经全部能点亮驱动了,也算能交个差了。当然了,数码管的驱动方式还有很多,网上也能查到一些专用的驱动芯片,每种芯片都有其独特的电路原理。 等实际遇到这些东西时再研究了,路漫漫其修远,共勉!

标签: hc319变送器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台