天天看点

TM1637数码管实验总结

目录

实验目的:

问题总结:

实验目的:

作为一个共享项目中的一部分,采用四位数码管实现时间的倒计时。

问题总结:

  • 因为赠送的资料是arduino的程序,所以需要自己移植到stm32中。一开始以为TM1637用的是IIC通信协议,就在IIC的基础上进行更改。在csdn中找到的程序存在少许错误,如:
TM1637数码管实验总结
TM1637数码管实验总结

两处的引脚定义不同(也不知道是不是故意的)

  • 经过修改后,修改的程序可以正常显示(成为程序A),但是自己基于IIC协议和TM1637数据手册编写的却无法显示(称为程序B),通过逻辑分析仪分析,程序A的时序图为
    TM1637数码管实验总结
    程序B一条读写命令的时序图为:
    TM1637数码管实验总结
    比较发现,程序B无法正常显示的原因在于——TM1637采用的并不是标准的IIC协议,标准的IIC在传输数据时,是高位在前,低位在后;而TM1637在传输数据时,是低位在前,高位在后。导致指令无法识别。例如:0x44=0x01000100、0x22=0x00100010。此特点,在技术手册中已经注明,只不过自己一开始没有注意。(以后一定要仔细看技术手册)
    TM1637数码管实验总结

代码区别:

//程序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
TM1637数码管实验总结

猜想可能是下一个数码管的写数据指令对其造成影响,通过逻辑分析仪可见:

TM1637数码管实验总结

在第二个数码管传输完数据后,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

继续阅读