因为一个项目要使用到数码管,所以今天研究了一下TM1637这款数码管驱动芯片,在这里做个记录,方便以后使用时参考。
最初以为芯片是I2C通信,想将几块不同的芯片挂在同一个I2C总线上,然后开始了研究。
开始先用arduino nano用一个芯片驱动一个数码管,按照上方电路图连接,得到一个奇怪的信号,无法正常点亮数码管,然后无意间发现将DIO的10k上拉电阻去掉就可以了。问题解决。
然后开始研究如何将两个芯片按照i2c的SCK/SDA的方式连接在一起,发现不成功,总是有一个芯片不亮,思考可能是地址设置的不正确,然后开始读数据手册,以及arduino的.cpp库文件
发现里面有一个自动地址增加模式和固定地址模式,就以为通过设置这个地址,我就可以在iic总线上找到对应的芯片并且显示出相应的数字了,然而事实并不是这样。
经过了一番搜索之后呢,发现全网都没有人尝试过将多个TM1637芯片挂在一个IIC bus上,而且有一个人说“TM1637不算iic通信,是自定义的2线通讯而已”,虽然都是两根线,都有开始信号、结束信号、应答…但却不是IIC, 这时才意识到这个芯片就没有这个功能。
然后开始研究替代方案,在arduino论坛 [1] 看到有一个人尝试利用多颗该芯片驱动大于4位的数码管,而他的方法是每多一个芯片就多接两个i/o口,虽然很笨,但却有效,因此最终采用了这个方案。
然后开始仔细读数据手册 [2],并且利用示波器认真分析该芯片的时序。
下方是程序内容:
#include "TM1637.h"
TM1637 tm1637A(2,3);//CLK , DIO
void setup()
{tm1637A.init();//初始化tm1637A.set(7);//亮度最高
}
void loop()
{tm1637A.display(0,8);//在第0位显示数字8delay(100);
}
运行该程序后示波器捕捉到的信号:
里面的1、2、3、4正好就对应我们时序图中的四组数据。
因为我在程序里只设置了第0位点亮,所以第三组”Data1~n”数据中只有1组8位数据。如果是同时点亮4位数码管,则这里的数据就是32位。
首先我们来看第一组数据【设置数据】
我们在示波器上读取到的8位数据是“00100010”,查找数据手册中对应的说明,分别是写数据到显示寄存器、固定地址、普通模式
对应程序中()是这行代码0x44 ADDR_FIXED
然后是下一组【设置地址】
我们读到”00000011″,也就是说显示地址位00H,就意味着我要显示的数位是第0位数码管。
因此这里的地址并不是说I2C的地址,而是位选地址,这也就是为什么这里只有6个值的原因,因为这个芯片最多只支持同时驱动6位数码管。
下一组是【传输显示数据】
读到的是”11110010″,这里的值就表示了我们数码管要点亮哪些led,顺序是A,B,C,D,E,F,G,DP,显示出来后就是数字3,经过转换,我们可以得到十六进制的4F,也可以从TM1637.cpp文件中查看到这个值。
第四组是【显示控制】
读到的值是”11110001″,代表的含义是显示打开,并且亮度最高。
也就是在程序中setup()函数中的TM1637A.set(7)的功能,将数码管的亮度调至最高。
这就是这四组数据的含义分析,我们其实还可以直接打开TM1637.cpp文件,看到display中的这四部分数据的传输过程。
经过今天的研究,对这个芯片比较熟悉了,以后要点亮数码管,除了直接用I/O口驱动、利用有点小贵的MAX7219驱动,又多了一个便宜且好用的选择!
参考资料:
[1] 《How to connect multiple tm1637 based 7 segment display in one arduino 》
[2] 《LED Drive Control Special Circuit TM1637》