目录
实验目的:
问题总结:
实验目的:
作为一个共享项目中的一部分,采用四位数码管实现时间的倒计时。
问题总结:
- 因为赠送的资料是arduino的程序,所以需要自己移植到stm32中。一开始以为TM1637用的是IIC通信协议,就在IIC的基础上进行更改。在csdn中找到的程序存在少许错误,如:
两处的引脚定义不同(也不知道是不是故意的)
- 经过修改后,修改的程序可以正常显示(成为程序A),但是自己基于IIC协议和TM1637数据手册编写的却无法显示(称为程序B),通过逻辑分析仪分析,程序A的时序图为 程序B一条读写命令的时序图为: 比较发现,程序B无法正常显示的原因在于——TM1637采用的并不是标准的IIC协议,标准的IIC在传输数据时,是高位在前,低位在后;而TM1637在传输数据时,是低位在前,高位在后。导致指令无法识别。例如:0x44=0x01000100、0x22=0x00100010。此特点,在技术手册中已经注明,只不过自己一开始没有注意。(以后一定要仔细看技术手册)
代码区别:
//程序A发送字节部分
void TM1637_WriteByte(unsigned char oneByte)
{
unsigned char i;
TM1637_DIO_OUT();
for(i=0;i<8;i++)
{
TM1637_CLK = 0;
if(oneByte&0x01)
{
TM1637_DIO = 1;
}
else
{
TM1637_DIO = 0;
}
TM1637_Delay_us(3);
oneByte=oneByte>>1;
TM1637_CLK = 1;
TM1637_Delay_us(3);
}
}
//程序B发送字节部分
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;
for(t=0;t<8;t++)
{
//IIC_SDA=(txd&0x80)>>7;
if((txd&0x80)>>7)
IIC_SDA=1;
else
IIC_SDA=0;
txd<<=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
- 在计时过程中还需要冒号闪烁的功能,因为数码管是共阴极,故只需对第二个数码管的最高位定时置一即可。但在实现过程中出现了x小bug,第二个数码管会在两个字符之间闪烁,放慢程序后可看出闪烁的字符。即为:0x01000100=0x44
猜想可能是下一个数码管的写数据指令对其造成影响,通过逻辑分析仪可见:
在第二个数码管传输完数据后,SDA处于空闲的高点平状态,误将下一位的写数据指令认为是上次指令的数据。在显示字符函数中最后添加stop()后解决。
void TM1637_NixieTubeDisplayChar(unsigned char ch,unsigned char p)
{
//if(ch>23)ch=0;
TM1637_Start();
TM1637_WriteByte(0x44);
TM1637_Ack();
TM1637_Stop();
TM1637_Start();
TM1637_WriteByte(0xC0+p);
TM1637_Ack();
TM1637_WriteByte(NumDis[ch]);
TM1637_Ack();
TM1637_Stop();
}
在文章末尾附上修正后的程序,需要的可以下载
https://download.csdn.net/download/qq_33231144/11470474