资讯详情

MicroPython-On-ESP8266——数码管的使用,四位数码管及动态扫描显示

MicroPython-On-ESP使用8266-数字管,四位数字管和动态扫描显示

1. 介绍四位数码管

在这里插入图片描述 上一节介绍了数字管的分类,初步学习了一个数字管的驱动模式。一个8段数字管需要8个IO接口驱动每个段位的接口led灯,这次我们升级到4位8段数字管学习,需要4吗?*8=32个IO口头驱动呢?

显然,这样做太愚蠢了。从上图可以看出,这个HS420361K-32数码管只引出12个引脚,上下各6个。这个数码管是共阴型的,后面的学习都是按照共阴模式(公共端接地)进行的。如果是共阳型,只需要反过来控制,要好好学习原理图和驱动逻辑。

2. 四位数字管原理及驱动模式

2.1. 电路原理图

我没有找到制造商和官方电路原理图。我只能在淘宝上查看这个模型,然后看看商品宣传中是否有信息,只找到其他类似模型的原理图,但实际结构是一致的。 老规矩,我们来分析一下这个原理图: 1) 和同一个数码管一样,不管规格大小,只看右边三个。右上角是单位数码管各段的名称,与上节课一致; 2 )右中间是引脚图,也是正面俯视,逆时针从左下角依次为1~12号引脚; 3 )底部的布线图更重要,依次排列32个led二极管和对接线。这个要仔细看:

3-1)只看最左边的8个二极管,对应的是四位数码管的第一位。如果只看这个,和上节那个单位的数码管一样,但不同的是这里标有12个引脚的地方都收到了。led二极管负极,正极按A~DP在这八段中,依次接到了11/7/4/2/1/10/5/3的引脚。在最后一篇文章的最后一个实验部分,我连接了这些地方来显示效果,也就是说,当共阳和共极处理时,16进制的编码部分应该被逆转。 3-2)向右延伸,后三组8个led二极管,同名段并联,接到同一个引脚。每个数字管只是一个共阴的公共端,对应一个引脚。这样下来8段对应8个引脚,4个引脚4个,所以从外观上看,4个数字管下有12只脚。

2.2. 驱动原理分析

如果电路结构已经清晰,则取决于驱动四位数字管显示,因为每个相同名称段led并联,也就是说,如果按照上节课学到的16进制方法来控制段位引脚的高低电平,这四个显示的值是一样的(前提是这四个公共端都是接地的)

然后解决两个问题:1。如何控制每个人是否打开(公共端和公共端)esp在8266之间增加一个可控开关);2是如何让这四个人同时显示不同的值,毕竟,如果它们都显示相同,就会失去多个人的意义。

2.2.1. 每个独立开关的方式

在电路原理图中,数字管的12/9/8/6引脚是每个管道位置的公共端,接收单片机负极,然后在段位引脚上给出高电平led段。四个公共端连接负极,四个管位显示相同的内部,哪个不连接负极,哪个不显示。

是否需要一个开关意味着,它需要使用三极管来实现,这里只粘贴三极管使用的接线原理,具体为什么可以使用三极管控制,三极管通过什么原理来控制,这足以显示一个主题来写。我不精通数字模型电,所以我不会出丑。

采用S9013三极管用作开关io口控三极管的基极,io口输出高电时,右侧垂直线路通过,相应led也可以点亮。 ESP8266的IO口的输出电压为3.3V,因此,我们在测试时不必考虑增加电阻。简化可以更好地理解原理。

2.2.2. 各位数码管显示不同数值的方式(动态扫描)

因为数码管的同名段位led并联并联的,所以在你身上显示的值是一样的,如果你想要不同,实际上使用的是人类的视觉暂留机制。 例如,我只是想显示0361,实际做法是做一个死循环,然后控制段显示第一个数字0只打开第一个三极管,一段时间后关闭;然后控制段显示第二个数字3只打开第二个三极管,然后关闭三极管;然后显示6,打开第三个三极管,显示1和第四个三极管。 这样,经过一轮显示,然后从头开始连续循环。就像电影一样,不同的数字不断地在不同的位置上来回显示,并以更高的频率不断刷新,让人们认为这四个数字管将显示四个不同的值。 人眼视觉暂留频率为24帧,每帧超过40毫秒。我们有4个数字管,每个都要考虑,所以每个刷新速度应该在10毫秒以下,具体的速度可以稍后测量。

3. 实验:四位数字管显示不断增长的数字

3.1. 接线图

根据前面的原理和驱动分析,我们可以跟踪数字管ESP8266开发板连接起来了,需要用到12个GPIO口头控制8段 需要4个管道位置的帮助NPN用小三极管做大家的开关。

傻了,事情发生了。 这时候用ampy任何指令都被卡住了

我按照图GPIO接线的顺序有几个意思~

重要烧录固件包,还好esptool工具也可以正常工作,过程不表。顺便说一句,刷了最新的esp8266-20210902-v1.17.bin固件。

回到micropython官网查,汗~ 只有9个IO我们还期待着用12个嘴来动态扫描。

既然只有9个GPIO如果可以用,那就凑合着用7个段(不显示小数点)。 控制管位用2个。也就是实际效果只能点亮两位数码管,显示不带小数点的数字。最终接线如下:

3.2. 测试代码

这个测试代码是阉割版,只能驱动两位数码管。

from machine import Pin import utime  leds = [] # 需要根据实际接线,依次放入A/B/C/D/E/F/G/DP这8个段位led灯对应到esp8266的GPIO引脚
for p in [4,0,12,14,2,5,16,13]:
    _pin = Pin(p, Pin.OUT)
    leds.append(_pin)

digs = []
# 根据实际接线,依次控制1~4四个位置的数码管
for p in [13,15]:  # 实际目前只控制两位,还借用了原DP引脚的接线
    _pin = Pin(p, Pin.OUT)
    digs.append(_pin)

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 show_num(num, has_point=False):
    '写入显示字符,转换为十六进制数值并按位点亮'
    value = mapper.get(num, 0)
    if not value: return
    # value = value & 0x7F if has_point else value # 共阳方式
    value = (~value | 0x80) if has_point else ~value  # 共阴方式
    for i,led in enumerate(leds):
        if i==7: continue  # !!!临时屏蔽最高位(转为控制管位开关)
        led.value((value >> i) & 0x01)

num = 0
while True:
    if num>99: num=0
    for i in range(50):
        # 显示十位
        show_num(str(int(num/10)))
        digs[0].on()
        utime.sleep_ms(5)
        digs[0].off()
        utime.sleep_ms(5)
        # 显示个位
        show_num(str(num%10))
        digs[1].on()
        utime.sleep_ms(5)
        digs[1].off()
        utime.sleep_ms(5)
    num += 1

3.2.1. 消抖与消影

show_num(str(num%10))
digs[1].on()
utime.sleep_ms(5)
digs[1].off()
utime.sleep_ms(5)

最后面的while循环里面,用法比较怪异,看上面的片段: 1)先是按待显示数字驱动段位led二极管 2)然后把要将数字显示到的管位三极管打开,这样数字就会显示出来了,且只在指定的一个管位上显示 3)保持一段时间(这里用了5毫秒) 4)然后关闭刚才的管位,并且再保持一段时间(又是用了5毫秒)

其实这里这样写,是使用到了消抖和消影的手法,先保持一段时间是为了让人产生视觉暂留,但时间又不能长,我原来写的10毫秒,都会有抖动的现象。后面关闭管位后,又保持了一段时间,其实这也是利用了视觉暂留,不加这一段时间而直接显示下一轮数字时,后面出现的数字还有叠加上一轮数字的轮廓,看起来像是上一轮数字有影子一样的。

大家拿到代码,把sleep_ms里面的参数调一调,自己体会一下。调得不好,要不就是数字在抖动,要不就是有重影。

3.3. 实验效果

唉,这效果只能看到两位管,太打击人了,不过正好,也为咱们下一节学习由两片595位移寄存器驱动的数码管打下基础,到时候就不用为IO口不够用发愁了。

标签: 三极管dp3080

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

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