七段显示译码器
在我还是小学生的时候,就对时间这个东西比较好奇.对数码表和机械表是如何工作的,也是满头的问号.后来分别看见了机械表和数码表的内部构造,对于机械表,内部虽说有无数的齿轮,但是一个带动一个,基本的原理还是了解一点点.而对于数码表的内部,就一块七段数码管接一块板子.完全看不懂.对于是如何显示时间的,还是比较好奇.好了,废话少说.
七段数码管其实非常的简单,就是七个LED灯按照一定的顺序排列而成的.既然能点亮一个LED,那么点亮七个也就没有问题了.
需要注意的是,一个LED需要两个引脚才能点亮,七段数码管有七个LED灯,那么就需要14个引脚才能做到.其实可以把其中的N或P接在一起,这样的话就只需要8个引脚就可以了.
而把N接在一起的就为共阳极,把P接在一起的为共阴极.但是七段数码管一般右下角一般还有一个小点,所以一般情况下,一位的七段数码管有9个引脚,如下图:
2位七段数码管我手边没有1位,只有2/4位的.就先拿2位的实验.
1位的需要9个引脚,那么2位的就要18个引脚.4位就要36的引脚了.为了节省引脚,可以把每一位的各段都接在一起,如下图:
从图中可以看出,我这个号2位数码管是共阴极的.其中2针脚的接的是DP,就是那两个小圆点.
一共有十个针脚,具体的接GPIO如下:
# 针脚位
25 = DP
21 = A
20 = B
16 = C
12 = D
26 = E
19 = F
13 = G
23 = DIG1
24 = DIG2
# 2位七段数码管
# 3621AS-1
# 共阴
好啦.先点个灯试一试.让所有的灯闪烁起来.
# s设置各个针脚并分组
12,26,19,21]
21,20,16,12]
21,20,16,12,26,19,13,25]
23,24,21,20,16,12,26,19,13,25]
23
24
# 设置模式
# 所有节点打开,并且设置为HIGH
for pin in allpins:
def one():
for i in range(3):
time.sleep(0.4)
time.sleep(0.4)
one()
好简单,对吧.继续,转一个圈圈.
def two():
def circle(bit_start,bit_end,pin,n):
GPIO.output(bit_start,GPIO.LOW)
for i in pin:
time.sleep(n)
k = 0.07
1
while a < 6:
circle(bit0,bit1,pin_0,k)
1
好玩吧,继续.来个倒计时.
def three():
num_1 = [20,16]
21,20,12,26,13]
21,20,16,12,13]
20,16,19,13]
21,16,12,19,13]
21,16,12,26,19,13]
21,20,16]
21,20,16,12,26,19,13]
21,20,16,12,19,13]
for num in nums:
time.sleep(1)
three()
最后显示一个ASCII字符HI.
def four():
20,16,26,19,13]
20,16]
1
while n < 999:
GPIO.output(H,GPIO.HIGH)
0.01)
GPIO.output(H,GPIO.LOW)
GPIO.output(bit1,GPIO.LOW)
time.sleep(0.01)
GPIO.output(I,GPIO.LOW)
n += 1
小玩意搞定了,接下来开始进入正题.
四位七段数码管的应用-时钟本来有一个4041AH-33中间有秒表计数的数码管的,但是被我玩坏了,BIT0在我测试的过程中有几段被我烧坏了.
其中的A,D,E,F段被烧掉了.所以就换了读秒点的4041AS,问题不大,原理其实是一样的.
OK,这个数码管所有段都正常工作.显示数字试一试.
注意到4位全部显示的数字都是一样的,这是因为节约引脚,把每一位的各个段都接在了一起.还把每一位的阴极全部都接在了一起.
这个四位数码管由个灯组成,每个灯都需要两个引脚接正负极,这样子一共就需要个针脚.这也太费针脚了.所以就想了个办法来节约针脚.来看看是如何节约的.
先把每一位的阴极都接在了一起,这样阴极本来需要32个针脚的,现在只需要4个了.这样子的话就只需要个了.在把各个位的各个段连接在一起,这样子阳极就只有8个针脚了.阳极的8个和阴极的4个,一共只需要个针脚.这样子就大大的节约了针脚数,但是问题来了,从上面的GIF图片可以看到.连接A段和BIT0时,第一位会亮.如果在连接BIT1时,第二位也会亮.但两个位显示的二极管是一样的.也就是没办法同时显示不同的数字.可以时间显示并不会每一位都是显示同一个数字.解决这个问题的方法为动态扫描
动态扫描数码管动态扫描利用了人类视觉系统的暂留性.
类似于看电影,经常会说60帧,表示的含义就是每秒显示60张不同的画面.人的眼睛是看不出的这是由60张图片在播放,只会觉得这是在看一段连续的视频.这就是人类视觉的暂留性.
同理,只要LED灯闪烁的时间少于20ms,人眼就不会感觉到灯在闪烁.4位数码管每一位显示0.05ms的话, 不停的循环.对于人类来说,是看不出来的.当然,正是这个原因,所以导致长期看显示器等电子设备,会导致视力下降.
import RPi.GPIO as GPIO
import time
pins = [27,17,4,12,16,5,6,20]
21,13,19,26]
allpins = pins + bitpins
GPIO.setmode(GPIO.BCM)
GPIO.output(bitpins,GPIO.LOW)
i = 0.05
while i > 0.005:
for k in range(3):
| time.sleep(i)
| time.sleep(i)
0.001
for k in range(300):
time.sleep(i)
time.sleep(i)
这里我写了写了个循环,使LED闪烁的频率越来越快,到0.005s停止减少,继续循环300次,可以看到,此时,已经无法识别到LED灯闪烁了.
利用这个效果,试一试让BIT0显示1,BIT1显示2,BIT2显示3,BIT3显示4.就不贴代码,写的没法入眼.
读取时间显示搞定了,只需要读取需要显示的数字就可以了.也就是具体需要显示的时间.读取时间有两种方法:
联网读取网络上的时间.网络上有很多NTP读取时间的服务器,找到api即可.使用时钟模块RTC(real-time clock)得到时间.这里我模拟第一种方式,直接调用time函数得到计算机的localtime时间,格式化后得到时分秒.
def nowTime():
tm_hour = all_time.tm_hour
tm_sec = all_time.tm_se
creturn tm_hour,tm_min,tm_se
c显示时间最后一步,显示时间.
这里我在第一位和第二位显示的分钟数,第三位和第四位显示的秒钟数.因为只有4位,所以小时位就没有显示.
done好啦,关于七段数码管的原理就掌握的差不多了.在下一篇中,终于可以开始接触屏幕,虽然是点正品,但好歹可以显示字符了.
你可以点击下方的阅读原文,查看驱动显示时间的程序源代码.