74HC595是一个8位串行输入、并行输出的位移缓存器:并行输出为三态输出。在SCK 的上升沿,串行数据由SDL输入到内部的8位位移缓存器,并由Q7'输出,而并行输出则是在LCK的上升沿将在8位位移缓存器的数据存入到8位并行输出缓存器。当串行数据输入端OE的控制信号为低使能时,并行输出端的输出值等于并行输出缓存器所存储的值。
通过此便可看出74HC595的工作原理。
但是,八位数码管,怎么区分显示位置呢?
在这里,一共需要16位数据,前8位是显示数据,后8位是显示位置。
显示位置的格式:01000000{第二位}
01100000{二三位}
但是,此时会发现,它只能显示一种数字,这就导致用途狭窄,所以,我们可以使用人眼的视觉暂留效应。
就是在循环中不断重复这些数字,让数码管以高频率扇动,看起来就像同时显示。
以下就是0-9的代码(请确认您的数码管是共阴极还是共阳极):
共阳极:
def sn(value):
dio.value(value)
sleep_us(2)
sclk.value(0)
sleep_us(2)
sclk.value(1)
sleep_us(2)
def show(dig,num,point_value):#dig是位数,num是数字,point_value为0或1,0时不显示点,1时显示点
value = 1 - str(point_value)
if num == 0 :
sn(value)
sn(1)
sn(0)
sn(0)
sn(0)
sn(0)
sn(0)
sn(0)
elif num == 1 :
sn(value)
sn(1)
sn(1)
sn(1)
sn(1)
sn(0)
sn(0)
sn(1)
elif num == 2 :
sn(value)
sn(0)
sn(1)
sn(0)
sn(0)
sn(1)
sn(0)
sn(0)
elif num == 3 :
sn(value)
sn(0)
sn(1)
sn(1)
sn(0)
sn(0)
sn(0)
sn(0)
elif num == 4 :
sn(value)
sn(0)
sn(0)
sn(1)
sn(1)
sn(0)
sn(0)
sn(1)
elif num == 5 :
sn(value)
sn(0)
sn(0)
sn(1)
sn(0)
sn(0)
sn(1)
sn(0)
elif num == 6 :
sn(value)
sn(0)
sn(0)
sn(0)
sn(0)
sn(0)
sn(1)
sn(0)
elif num == 7 :
sn(value)
sn(1)
sn(1)
sn(1)
sn(1)
sn(0)
sn(0)
sn(0)
elif num == 8 :
sn(value)
sn(0)
sn(0)
sn(0)
sn(0)
sn(0)
sn(0)
sn(0)
elif num == 9 :
sn(value)
sn(0)
sn(0)
sn(1)
sn(0)
sn(0)
sn(0)
sn(0)
for x in range(1,9):
if (x == dig):
sn(1)
else:
sn(0)
rclk.value(1)
sleep_ms(2)
rclk.value(0)
共阴极就是把共阳极的0和1调换
共阴极(未测试):
def sn(value):
dio.value(value)
sleep_us(2)
sclk.value(0)
sleep_us(2)
sclk.value(1)
sleep_us(2)
def show(dig,num,point_value):#dig是位数,num是数字,point_value为0或1,0时不显示点,1时显示点
value = 1 - str(point_value)
if num == 0 :
sn(value)
sn(0)
sn(1)
sn(1)
sn(1)
sn(1)
sn(1)
sn(1)
elif num == 1 :
sn(value)
sn(0)
sn(0)
sn(0)
sn(0)
sn(1)
sn(1)
sn(0)
elif num == 2 :
sn(value)
sn(1)
sn(0)
sn(1)
sn(1)
sn(0)
sn(1)
sn(1)
elif num == 3 :
sn(value)
sn(1)
sn(0)
sn(0)
sn(1)
sn(1)
sn(1)
sn(1)
elif num == 4 :
sn(value)
sn(1)
sn(1)
sn(0)
sn(0)
sn(1)
sn(1)
sn(0)
elif num == 5 :
sn(value)
sn(1)
sn(1)
sn(0)
sn(1)
sn(1)
sn(0)
sn(1)
elif num == 6 :
sn(value)
sn(1)
sn(1)
sn(1)
sn(1)
sn(1)
sn(0)
sn(1)
elif num == 7 :
sn(value)
sn(0)
sn(0)
sn(0)
sn(0)
sn(1)
sn(1)
sn(1)
elif num == 8 :
sn(value)
sn(1)
sn(1)
sn(1)
sn(1)
sn(1)
sn(1)
sn(1)
elif num == 9 :
sn(value)
sn(1)
sn(1)
sn(0)
sn(1)
sn(1)
sn(1)
sn(1)
for x in range(1,9):
if (x == dig):
sn(1)
else:
sn(0)
rclk.value(1)
sleep_ms(2)
rclk.value(0)
在此强烈建议使用sleep,否则树莓派与74HC595的通信可能会发生错误。
然后,可以浅试一下:
for dig in range(1,9):
show(dig,9-dig,0)
sleep_ms(2)
如果显示87654321,那么恭喜您已经驱动成功了。
代码:
from utime import localtime
from machine import Pin
from utime import sleep_us,sleep_ms
dio = Pin(0,Pin.OUT,value=0)#串行数据输入
sclk = Pin(1,Pin.OUT,value=0)#移位寄存器输入
rclk = Pin(2,Pin.OUT,value=0)#锁存器输入
def sn(value):
dio.value(value)
sleep_us(2)
sclk.value(0)
sleep_us(2)
sclk.value(1)
sleep_us(2)
def show(dig,num,point_value):
value = 1 - int(point_value)
if num == 0 :
sn(value)
sn(1)
sn(0)
sn(0)
sn(0)
sn(0)
sn(0)
sn(0)
elif num == 1 :
sn(value)
sn(1)
sn(1)
sn(1)
sn(1)
sn(0)
sn(0)
sn(1)
elif num == 2 :
sn(value)
sn(0)
sn(1)
sn(0)
sn(0)
sn(1)
sn(0)
sn(0)
elif num == 3 :
sn(value)
sn(0)
sn(1)
sn(1)
sn(0)
sn(0)
sn(0)
sn(0)
elif num == 4 :
sn(value)
sn(0)
sn(0)
sn(1)
sn(1)
sn(0)
sn(0)
sn(1)
elif num == 5 :
sn(value)
sn(0)
sn(0)
sn(1)
sn(0)
sn(0)
sn(1)
sn(0)
elif num == 6 :
sn(value)
sn(0)
sn(0)
sn(0)
sn(0)
sn(0)
sn(1)
sn(0)
elif num == 7 :
sn(value)
sn(1)
sn(1)
sn(1)
sn(1)
sn(0)
sn(0)
sn(0)
elif num == 8 :
sn(value)
sn(0)
sn(0)
sn(0)
sn(0)
sn(0)
sn(0)
sn(0)
elif num == 9 :
sn(value)
sn(0)
sn(0)
sn(1)
sn(0)
sn(0)
sn(0)
sn(0)
for x in range(1,9):
if (x == dig):
sn(1)
else:
sn(0)
rclk.value(1)
sleep_us(2)
rclk.value(0)
while True:
times = localtime()
hq = str(times[3])
mq = str(times[4])
sq = str(times[5])
if len(hq) == 1:
h = str("0"+hq)
elif len(hq) == 0:
h = str("00"+hq)
else:
h = hq
if len(mq) == 1:
m = str("0"+mq)
elif len(mq) == 0:
m = str("00"+mq)
else:
m = mq
if len(sq) == 1:
s = str("0"+sq)
elif len(sq) == 0:
s = str("00"+sq)
else:
s = sq
t = h + m + s
n = 1
for i in t:
show(n,int(i),0)
n = n + 1
本示例基于树莓派pi pico运行。
如果有问题欢迎各位大佬指教