我们学习了如何利用74hc595这块显示驱动芯片来驱动1位8段数码管的方法。并逐一讲解了该芯片各引脚的功能。细心的童鞋可能注意到了,上次我们有一个q7s引脚没有用到。这一篇我们就用这个引脚来级联两块74hc595芯片同时驱动8个8段数码管。在两块74hc595芯片的配合下,同样只需要3个gpio口就能驱动八只8段数码管。而如果直接用gpio驱动则需要至少16个gpio口,节省了13个gpio!而且按照本文的方法,你还可以级联更多的74hc595芯片,每多级联一片就能多驱动8只数码管,而需要的io口仍然只有3个!妈妈再也不用担心我的io口不够用了。
最终效果视频演示
硬件74hc595显示芯片 x 2共阳(或共阴)4位数码管 x 2
硬件图 由于大面包板已经被我插满了,所以用另一块小面包板来安放第二片74hc595原理说明我们已经知道,每次制造一次移位寄存器时钟引脚的上升沿,74hc595都会在这个上升沿将ds引脚上的数据存入内部的移位寄存器d0,同时d0原来的数据会顺移到d1,d1的数据位移到d2。。。d6的数据位移到d7。而d7的数据会被输出到引脚q7s上,如果q7s引脚没有被使用,那么这一位数据就被丢掉了。如果我们将q7s引脚连接上另一块74hc595的ds引脚并保证两块芯片上的移位时钟的上升沿同时发生(将两块芯片的shcp连在一起即可)的话,第一块74hc595的串行输出引脚q7s就变成了第二块74hc595的串行输入数据源。q7s上的数据会继续移位到第二块74hc595芯片的移位寄存器d0里(同样的,d0→d1→d2→…→d6→d7→q7s)。16位数据全部这样串行传输完毕后,制造两块芯片的锁存时钟stcp的上升沿(跟shcp一样,两块芯片的stcp连在一起即可)即可同时输出16位数据。利用上述级联原理加上前一篇学习的内容,我们可以这样静态驱动2只数码管:两只数码管的共阳(阴)极连接vcc(gnd),第一片595的q0-q7连到第一个数码管的a-g,dp上,级联的第二片595的q0-q7连到第二只数码管的a-g,dp上,然后用3根gpio口驱动两片级联的74hc595芯片,连续串行输入两个数字的显示码共16位数据,然后同时制造锁存上升沿,将两个数字的显示码分别输出到两只数码管上即可。这样连接的话,n片级联的74hc595就能驱动n只数码管了。(咦,说好的驱动8位数码管的呢)上面的做法当然没问题,而且有一个优点是静态显示所以显示很稳定,有兴趣自己试着做一下。缺点是浪费芯片,价格倒不贵可是连线复杂,占用电路板面积太多。本文采用动态扫描(原理参见本系列第5篇)的方式来使用两块级联的74hc595芯片驱动8位数码管。原理也很简单,稍微调整一下硬件的连接方式和传输数据的方式即可。依然是两块74hc595级联,第一块595的输出引脚连到所有数码管的段引脚上(8只数码管的a-g,dp引脚连在一起),第二块595的输出引脚q0-q7分别连上8只数码管的共阳(阴)极上。第一块芯片的输出决定了数码管上显示什么数字。而8只数码管中哪一只会被点亮则取决于第二块芯片哪只数码管的共阳(阴)端是高(低)电平。由于在我的硬件连接里,级联的第二块74hc595是负责位选的,所以应该先发送8位位选信号,再发送8位段选信号,在连续发完了16位数据以后,第一块74hc595的移位寄存器里保存着8位的段选信息,而在第二块74hc595的移位寄存器里保存着8位的位选信息。由于两片芯片的stcp是连在同一个gpio口的,这个时候如果制造一次stcp的上升沿,两块595的位移寄存器里的数据会同时保存到自己的锁存器里,由于我的使能端oe连在gnd始终有效,锁存器里的数据就直接输出到了芯片的输出引脚上。第二块芯片的8根输出引脚连接的是8位数码管的共阳端。只有输出高电平的引脚连接的数码管才会被点亮。当然如果你喜欢,你也可以让8个数码管全部同时点亮,你只要让第二块595输出11111111就行了。不过显示的数字都是一样的。想显示不同的数字就要进行动态扫描,每次输出一个数字的显示码跟一个位选码,快速循环切换显示即可。跟上一篇一样,我也做了一个动画帮助你理解级联的过程。这个动画一开始已经是传输完前8位位选数据的状态了,动画里的位选数据是1000000,点亮第一个数码管,显示的内容由后8位段选数据决定,动画里是数字5。
74hc595
硬件连接模块1引脚模块2引脚74hc595_1q0数码管1/2dp74hc595_1q1数码管1/2g74hc595_1q2数码管1/2f74hc595_1q3数码管1/2e74hc595_1q4数码管1/2d74hc595_1q5数码管1/2c74hc595_1q6数码管1/2b74hc595_1q7数码管1/2a74hc595_1q7s74hc595_2ds74hc595_2q0数码管1dig1的共阳极74hc595_2q1数码管1dig2的共阳极74hc595_2q2数码管1dig3的共阳极74hc595_2q3数码管1dig4的共阳极74hc595_2q4数码管2dig1的共阳极74hc595_2q5数码管2dig2的共阳极74hc595_2q6数码管2dig3的共阳极74hc595_2q7数码管2dig4的共阳极树莓派gpio1374hc595_1ds树莓派gpio1974hc595_1/2shcp树莓派gpio2674hc595_1/2shtp树莓派vcc74hc595_1/2vcc,mr树莓派gnd74hc595_1/2gnd,oe代码(python)123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172#!/usr/bin/env python# encoding: utf-8import rpi.gpioimport time# 串行数据输入引脚连接的gpio口ds = 13# 移位寄存器时钟控制引脚连接的gpio口——上升沿有效shcp = 19# 数据锁存器时钟控制引脚连接的gpio口——上升沿有效stcp = 26rpi.gpio.setmode(rpi.gpio.bcm)rpi.gpio.setup(ds, rpi.gpio.out)rpi.gpio.setup(stcp, rpi.gpio.out)rpi.gpio.setup(shcp, rpi.gpio.out)rpi.gpio.output(stcp, false)rpi.gpio.output(shcp, false)# 通过串行数据引脚向74hc595的传送一位数据def setbitdata(data):# 准备好要传送的数据rpi.gpio.output(ds, data)# 制造一次移位寄存器时钟引脚的上升沿(先拉低电平再拉高电平)# 74hc595会在这个上升沿将ds引脚上的数据存入移位寄存器d0# 同时d0原来的数据会顺移到d1,d1的数据位移到d2。。。d6的数据位移到d7# 而d7的数据已经没有地方储存了,这一位数据会被输出到引脚q7s上# 如果q7s引脚没有被使用,那么这一位的数据就被丢掉了。# 而如果将q7s引脚连接到另一块74hc595上的ds引脚,# 那么这一位数据就会继续位移到第二块595芯片的位移寄存器里去。# 这就是多块595芯片级联的原理。rpi.gpio.output(shcp, false)rpi.gpio.output(shcp, true)# 指定第dig位(1-8)数码管显示数字num(0-9),参数showdotpoint是显示不显示小数点(true/false)# 由于我使用的数码管是共阳数码管,所以设置为低电平的段才会被点亮# 如果你用的是共阴数码管,那么要将下面的true和false全部颠倒过来,或者统一在前面加上notdef showdigit(dig, num, showdotpoint):# 由于在我的硬件连接里,级联的第二块74hc595是负责位选的,# 所以应该先发送8位位选信号,再发送8位段选信号,在连续发完了16位数据以后,# 第一块74hc595的移位寄存器里保存着8位的段选信息,而在第二块74hc595的移位寄存器里保存着8位的位选信息。# 由于两片芯片的stcp是连在同一个gpio口的,这个时候如果制造一次stcp的上升沿,# 两块595的位移寄存器里的数据会同时保存到自己的锁存器里,由于我的使能端oe连在gnd始终有效,锁存器里的数据就直接输出到了芯片的输出引脚上。# 第一块芯片的8根输出引脚连接的是所有数码管共用的abcdefg,dp引脚,决定了数码管上显示什么数字。而8只数码管中哪一只会被点亮则取决于哪只数码管的共阳端是高电平。# 第二块芯片的8根输出引脚连接的是8位数码管的共阳端。只有输出高电平的引脚连接的数码管会点亮。# 当然如果你喜欢,你也可以让8个数码管全部同时点亮,你只要让第二块595输出11111111就行了。不过显示的数字都是一样的。# 想显示不同的数字就要进行动态扫描,原理不再说明请参考本系列教程第5篇。for x in range(1,9):if (x == dig):setbitdata(true)else:setbitdata(false)if (num == 0) :setbitdata(not showdotpoint) # dpsetbitdata(true) # gsetbitdata(false) # fsetbitdata(false) # esetbitdata(false) # dsetbitdata(false) # csetbitdata(false) # bsetbitdata(false) # aelif (num == 1) :setbitdata(not showdotpoint)setbitdata(true)setbitdata(true)setbitdata(true)setbitdata(true)setbitdata(false)setbitdata(false)setbitdata(true)elif (num == 2) :setbitdata(not showdotpoint)setbitdata(false)setbitdata(true)setbitdata(false)setbitdata(false)setbitdata(true)setbitdata(false)setbitdata(false)elif (num == 3) :setbitdata(not showdotpoint)setbitdata(false)setbitdata(true)setbitdata(true)setbitdata(false)setbitdata(false)setbitdata(false)setbitdata(false)elif (num == 4) :setbitdata(not showdotpoint)setbitdata(false)setbitdata(false)setbitdata(true)setbitdata(true)setbitdata(false)setbitdata(false)setbitdata(true)elif (num == 5) :setbitdata(not showdotpoint)setbitdata(false)setbitdata(false)setbitdata(true)setbitdata(false)setbitdata(false)setbitdata(true)setbitdata(false)elif (num == 6) :setbitdata(not showdotpoint)setbitdata(false)setbitdata(false)setbitdata(false)setbitdata(false)setbitdata(false)setbitdata(true)setbitdata(false)elif (num == 7) :setbitdata(not showdotpoint)setbitdata(true)setbitdata(true)setbitdata(true)setbitdata(true)setbitdata(false)setbitdata(false)setbitdata(false)elif (num == 8) :setbitdata(not showdotpoint)setbitdata(false)setbitdata(false)setbitdata(false)setbitdata(false)setbitdata(false)setbitdata(false)setbitdata(false)elif (num == 9) :setbitdata(not showdotpoint)setbitdata(false)setbitdata(false)setbitdata(true)setbitdata(false)setbitdata(false)setbitdata(false)setbitdata(false)# 移位寄存器的8位数据全部传输完毕后,制造一次锁存器时钟引脚的上升沿(先拉低电平再拉高电平)# 74hc595会在这个上升沿将移位寄存器里的8位数据复制到8位的锁存器中(锁存器里原来的数据将被替换)# 到这里为止,这8位数据还只是被保存在锁存器里,并没有输出到数码管上。# 决定锁存器里的数据是否输出是由“输出使能端口”oe决定的。当oe设置为低电平时,锁存器里数据才会被输出到q0-q7这8个输出引脚上。# 在我的硬件连接里,oe直接连接在了gnd上,总是保持低电平,所以移位寄存器的数据一旦通过时钟上升沿进入锁存器,也就相当于输出到led上了。rpi.gpio.output(stcp, true)rpi.gpio.output(stcp, false)try:# 测试代码while (true):# 8位数码管显示1-8,不显示小数点for dig in range(1,9):showdigit(dig, 9-dig, false)time.sleep(0.001)except keyboardinterrupt:pass# 最后清理gpio口rpi.gpio.cleanup()
星河亮点推出5G毫米波综测仪原型系统,符合3GPP标准规范要求
超频三收购圣比和49.5%股权 进军锂电池领域
检修中细漆包线头上锡小经验,Enameled wire
简易AM信号调制的FPGA实现过程简单讲解
关于智能大棚控制系统,它是由哪些设备组成的
树莓派GPIO入门08-使用74HC595芯片驱动数码管(二)
美光斥资30亿美元扩建汽车芯片工厂!
传英特尔与风投合作组建20亿美元投资基金
airpods蓝牙耳机评测 最配苹果手机的一款真无线蓝牙耳机
低ESR钽电容器使电路设计与众不同
论绿色变换的发展
第一代GalaxyWatchActive正在接受一系列更新
千元内有什么性价比蓝牙耳机?盘点几款平价好用的蓝牙耳机
iphone xr分辨率真的很低?还是你愿意将就?
区块链钱包的基本类型和特点以及工作原理介绍
三星Galaxy C8正式开售,双摄、面部识别打造超酷中端机
OLED关键技术及特征说明
太阳能电池板利用理想二极管给12V电池充电
VR未来的市场将比AR大1000倍
从“达芬奇项目”看华为进军AI的“蒙娜丽莎微笑”