接口说明
微处理器的数据通过两线总线接口和 TM1637 通信,在输入数据时当 CLK 是高电平时,DIO 上的信号必须保持不变;只有 CLK 上的时钟信号为低电平时,DIO 上的信号才能改变。数据输入的开始条件是 CLK 为高电平时,DIO 由高变低;结束条件是 CLK 为高时,DIO 由低电平变为高电平。
TM1637 的数据传输带有应答信号 ACK,当传输数据正确时,会在第八个时钟的下降沿,芯片内部会产生一个应答信号 ACK 将 DIO 管脚拉低,在第九个时钟结束之后释放 DIO 口线。
指令数据传输过程如下图(读按键数据时许)
Command:读按键指令;
S0、S1、S2、K1、K2 组成按键信息编码,S0、S1、S2 为 SGn 的编码,K1、K2 为 K1 和 K2 键的编码,读按键时,时钟频率应小于 250K,先读低位、后读高位。
数据命令设置
该指令用来设置数据写和读,B1 和 B0 位不允许设置 01
或者 11
。
地址命令设置
该指令用来设置显示寄存器的地址;如果地址设为 0C6H
或更高,数据被忽略,直到有效地址被设定;上电时地址默认设置为 00H
。
显示控制
代码实现
#encoding:utf-8
import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
CLK=17 #时钟引脚
DIO=18 #数据引脚
segdata=[0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f]#1--9
segdatadp=[0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef]#带小数点
#发送起始位,时钟为高的时候,数据线需要一个高低的跳变
def tm1637_start():
GPIO.output(CLK,1) #时钟打高电平
GPIO.output(DIO,1)
GPIO.output(DIO,0)
GPIO.output(CLK,0) #时钟打低电平
#发送停止位,数据线拉低,时钟线由低到高的跳变,产生一个停止信号给TM1637
def tm1637_stop():
GPIO.output(DIO,0) #数据线打低电平
GPIO.output(CLK,0) #clk 0->1
GPIO.output(CLK,1)
GPIO.output(DIO,1) #数据线线打高电平
#-----写位------
def write_bit(bit):
GPIO.output(CLK,0) #设置时钟位拉低电平,为了准备数据
if bit:
GPIO.output(DIO,1) #如果要发送的数据位是1,则打高电平
else:
GPIO.output(DIO,0) #如果要发送的数据位是0,则打低电平
GPIO.output(CLK,1)
#------写字节(8个二进制位的发送)
def write_byte(data):
for i in range(0,8): #发送8个二进制位
write_bit((data >> i)&0x01) #先发送低位
GPIO.output(CLK,0) #CLK打出下降沿,准备接受TM1637的应答信号
GPIO.output(DIO,1) #拉高DIO
GPIO.output(CLK,1) #拉高CLK
GPIO.setup(DIO,GPIO.IN)#设置数据线输入,释放总线
while(GPIO.input(DIO)): #等待TM1637拉低===发送ACK,确认信号给树莓派
pass #占位行
GPIO.setup(DIO,GPIO.OUT)#设置DIO位输出,恢复到默认状态
#----------写命令,写命令只有一个参数,就是命令本身----
def write_command(cmd):
tm1637_start() #发送起始位
write_byte(cmd) #发送命令
tm1637_stop() #发送停止位
#----写数据,两个参数,第一个参数数据写入的位置,第二个参数要写入的数据内容----
def write_data(addr,data):
tm1637_start() #发送起始位
write_byte(addr) #先写地址
write_byte(data) #再写数据
tm1637_stop() #发送停止位
#----显示数据:时 分---------
def time_display(h_shi,h_ge,m_shi,m_ge,f_dp):
write_command(0x40) #写数据
write_command(0x44) #固定地址
write_data(0xc0,segdata[h_shi]) #写第一个数码管--小时的十位
if(f_dp):
write_data(0xc1,segdatadp[h_ge]) #写第二个数码管---小时的个位,带小数点
else:
write_data(0xc1,segdata[h_ge]) #写第三个数码管---分钟的十位
write_data(0xc2,segdata[m_shi]) #写第四个数码管---分钟的个位
write_data(0xc3,segdata[m_ge])
write_command(0x88) #显示开
def tm1637_init():
GPIO.setup(CLK,GPIO.OUT)
GPIO.setup(DIO,GPIO.OUT)
#========main函数==========
tm1637_init() #初始化数码管
FLAGDP=1 #数点标志
while 1:
now_time=time.localtime(time.time()) #取得当前的时间
hour_shi=now_time[3]/10 #十分位
hour_ge=now_time[3]%10 #个位
min_shi=now_time[4]/10 #十分位
min_ge=now_time[4]%10 #十分位
FLAGDP=FLAGDP^1 #每一秒冒号跳一次,异或相同为0,不同为1
time_display(hour_shi,hour_ge,min_shi,min_ge,FLAGDP)
time.sleep(1)