最近,在学习stm32f103芯片的使用,发现单片机很多东西,必须亲力亲为去写一遍才会明白里面的坑!第一次写,有问题请大佬指出。
之前学习了一下TM1640芯片,一直没有时间在开发板上实践,直到最近才写了一下代码,接下来分享一下我敲TM1640底层驱动的过程,以及遇到的坑。
先放一下我使用的硬件原理图(基于洋桃一号开发板)
其实和我们51学习过程中数码管的段选、位选很相似(SEG就好比段选,GRID就如同位选),废话不多说,先上一下TM1640的数据手册
由这个数据传输图,可以知道我们需要有启动代码和结束代码以及数据发送代码(这里有点类似与iic)接下来是这三部分的代码
上图的数据手册说明的很清楚,数据输入的开始条件:CLK为高电平时,DIN由高变低。
数据结束的条件是:CLK为高电平时,DIN由低变高。解答一下两点疑惑之处:一、为什么要在信号变化后加入延时函数?答:根据下图的时序特性可知,需要一定的等待时间,数据建立及保持时间(严格来说大于1us即可)。二、结束函数为什么要先将两根线拉低?答:首先我们根据时序图即可知,结束信号之前都是从低电平开始操作,之所以为什么要人为拉低,这要结合数据发送阶段的代码来说,因为DIN电平是根据数据变化的,可能为高电平,所以是需要人为拉低,确保信号正确。
由数据传输格式的图,我们知道需要一位一位的传输数据,8位数据通过一个for循环发送,数据手册上清楚说明:CLK为低电平时,才能变化DIN上的数据(高低),CLK为高电平时不能改变DIN(发送阶段)。
前面这三步走好了,就可以开始跑了,先说如何实现自动地址写数据模式
很简单就根据这个顺序写,当然要看数据手册,知道command咋设置,此外,为什么要叫做自动地址模式,等后面和固定地址模式对比后就显而易见了。
举例说明,数据命令设置,我们现在需要地址自动加一模式(即0x40);地址设置,如第一位数码管连接的是GRID1(显存地址00H),00H对照上上图即0xc0,直接上代码(搞忘了,我没用这个模式hhhh,但是在初始化里面用了,将就初始化里面的讲一下)
这个图片中第一部分是最基础的IO口的初始化(特此说明,我的两个IO口进行了宏定义)然后就是TM1640自动地址模式的使用部分,发送首地址0x40!!!!写到这里猛然发现代码里面写成了0x44,居然没有影响结果。此处利用自动地址加一模式对每位数码管进行赋初值0x00(熄灭操作),因为之前发现,如果使用固定地址模式,未被使用的位会任意赋值出现乱码,暂时还未分析是代码还是硬件的问题。
在初始化中,你会发现还有一段代码,即时序中的控制显示,主要是用了设置亮度和开关数码管(其实仔细会发现设置亮度后数码管自然是处于打开状态)
简而言之,自动地址模式,即发送一个首地址,后面直接发需要的数据,每发一个数据地址自动加一
接下来重点说一下固定地址模式,与自动地址不同的是,固定地址需要发送一个地址再发送数据,每个地址对应一个数据。
直接说一下我踩的坑,看中间显示数据部分,每一组地址和数据都要加start和end函数,不能直接command1、data1+command2、data2·······而是start、command1、data1、end+start、command2、data2、end·······直接上代码,这里提出我的疑问:为什么不明确标出start、end?
差不多就是这样,在使用数码管的过程中,我还想了利用flash存数据,多次调试发现只能存第一个数,最后发现是flash写入函数的问题,下次再说。
如有错误,敬请指正!在错误中进步嘛。