赞
踩
这段时间一直在忙其他项目,基于esp8266的micropython学习搁置好久了。应网友要求,要写一篇数据管的学习教程,那咱就安排上。
什么是数码管,这个我都没有去查百科什么的,不做官方回答啊,只是告诉大家,他里面就是几个led灯组合在一起,摆成个8字型,这样点亮不同部位的led灯就能组合出需要的数字出来了。
因为是组全了多个led灯,要接线在一起又要独立控制,就有了两种接线方式。
看图更好理解,下图是共阴的连接方式,led全都反过来的话就是共阳。
另外说明一下,从图上看A~G一共7个led二极管组成个8字型,只有这7个时就是7段,而8段数码管是多出了右下角一个小数点位。
东拼西凑地找来了几个不同类型的数码管。因为我也是头次学习,上网查资料找手册,过程中难免会有些岔路,最终效果能出来,但实现上可能不是最优解,所以看官们发现有错误的地方欢迎指正啊,先谢过!
看上图,我拿到手有三种数码管,按从左到右依次是:
准备依次学习,难度逐步升级!
YH5611BH一位8段共阳型数码管,原理图直接找过来了,咱们分析一下:
其实把引脚按顺序对应到A~G/DP不是更好嘛,直观又清晰。应该是内部走线决定不能直接对应吧。。。
为了验证上面的对应关系,我把数码管插面包板上,然后用跳线直接把各个引脚怼到5V电源上试,结果啪啪响了几下,有些段位先是点亮然后就是点响,给烧穿了。。。
妈呀出师未捷身先死,不过好歹算是验证了人家那引脚真的就是那么对应的。
如果我要让数码管显示一个数字,那点亮组成该数字的段位led就行嘛。比如我要显示数字”0“,那就是要将A/B/C/D/E/F这几个段位对应的引脚置为低电平,将不需要点亮的G/DP置为高电平,那就能得到想要的效果了。
但是总不能每次想要一个数字,就要编写8行代码,一个个处理引脚吧。8个段位刚好可以对应到计算机一个字节的8位,那咱们就可以用一个字节来存储8段led的整体状态了。
网上大把51单片机教程在处理数码管时都是这样操作P0/P1之类,因为51单片机一个IO口刚好用8位寄存器来存储8个引脚的值。虽然咱们ESP8266不是这样的机制,但这种操作方式咱们也学过来。
我用表格整理出来显示各种字段对应的段位高低电平值,和用十六进制表达出来的数值。
小数点位比较特殊,一般需要单独处理一下。其实从上面表格来看也很容易实现,只需要把十六进制数的最高位置为低电平即可,那就是把原数值”&0x7F“一下就可以了(二进制 0111 1111,与任何数都可以实现最高位清0,其余位保持不变)。比较显示”3“时,用十六进制表示为0xB0,那显示”3.“则是 0xB0 & 0x7F = 0x30
那咱们基本就能确定驱动一个8段数码管的流程了:
STEP 1、准备工作,定义好引脚与段名的对应关系(主要由实际接线决定),
STEP 2、定义好待显示字符与十六进制数值的对照字典,
STEP 3、将十六进制数值转换为引脚电平值,输出GPIO电平状态即可。
接线我是按D0到D7顺序来接,主要是考虑走线走线方便,接好后关键是找出上面STEP1中提到的对照关系。
写起来有点啰嗦,不展示了,直接看下面代码里面注释吧
这里比较简单,就直接贴完整代码,不分段讲解了。
''' 8段数码管点亮实验 接线图 数码管引脚 ESP8266 数码管段位 10 -> D0(GPIO 16) -> G 10 9 8 7 6 9 -> D1(GPIO 5) -> F | | | | | 8 -> 3.3V ---A--- |-----------| 7 -> D2(GPIO 4) -> A F| |B | YH5611BH | 6 -> D3(GPIO 0) -> B |--G--| |-----------| 5 -> D7(GPIO 13) -> DP E| |C | | | | | 4 -> D6(GPIO 12) -> C ---D--- *DP 1 2 3 4 5 2 -> D5(GPIO 14) -> D 1 -> D4(GPIO 2) -> E 要根据实际接线来调整顺序 ''' from machine import Pin import utime leds = [] for p in [4,0,12,14,2,5,16,13]: # 需要根据实际接线,依次放入A/B/C/D/E/F/G/DP这8个段位led灯对应到esp8266的GPIO引脚 _pin = Pin(p, Pin.OUT) leds.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): led.value((value >> i) & 0x01) while True: # 从0开始显示0~9加A~F字符 for num in '0123456789ABCDEF': show_num(num) utime.sleep_ms(500) # 再显示一轮带小数点的 for num in '0123456789ABCDEF': show_num(num, True) utime.sleep_ms(500)
代码里面依次展示一轮从0到f的显示,和一轮带小数点的0到F的显示。上效果。
后记1:眼尖的应该能从图上看出来,这个效果图跟上面接线图里面的数码管不一样,额。。。 前面提到了,那个一位的数码管被我点爆了。。。 只能先用四位的数码管展示效果出来了。
这个四位的数码管是共阴型的,所以代码show_num
函数里面我注释掉的地方是按共阴方式处理的,其实原理就是把现在算出来的每一位都取反。
后记2:一位数码管相对是最简单的,们先掌握了再说,下一步准备进阶4位数码管。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。