天微TM1650数码管驱动IC新旧版 驱动和注意事项
项目场景:
项目需要一个控制板和显示,通过一条1米数据线连接主控制
TM1650市面上多,价格便宜,使用简单, 相对于用逻辑门或单片机做,开发简单维护生产简单
问题描述:
在获取按键时发0X49指令,容易被识别为0X48,这样就造成之后的显示和获取按键异常,而旧版就暂没出现这种情况
原因分析:
TM1650目前分了2个版本, 只在丝印的批号注明(1开头为旧版, 2开头为新版), 说明书和个别供应商没注明…
问题就出了这里,一开始用旧版量产了正常没问题,后面再次量产供应商给的是新版,造成大量反工退货…
问了厂家客服才知分新旧版,
主要问题是新版通信容易出错, 而且处理程序没处理好的话只能重启,
解决方案:
由于是数码管驱动IC接收出错(差不多寄存器设置错误),但不是死机,重新设置就可以救回
由于通信没有做校准操作, 所以通信容易出现错误, 只需定时将每个寄存器发一次,就算有一次出错,但最后肯定会修正,而按键值则需要多次读取以排除偶然性错误, 还有在驱动IC的通信口附近加电容,减低速率
定时执行官方的整个操作流程:
附上官方给的驱动, N76E003测试可以用(TM多款数码芯片的通信是差不多的,驱动可以共用)
#include<reg52.h> //MCU头文件
#include<intrins.h> //包含nop指令头文件
#define uint unsigned int //数据类型宏定义
#define uchar unsigned char //数据类型宏定义
#define nop _nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //宏定义
/********************定义控制端口**********************/
sbit SCL=P2^1; //时钟线
sbit SDA=P2^0; //数据线
uchar keya; //定义读出按键返回值
/*************1ms延时*晶振11.0592M********************/
void delay(uint n)
{
uint i;
while(n--)
for(i=0;i<550;i++);
}
/**************共阴数码管显示0-F**********************/
uchar display[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71}; //共阴极字段码
/************ START信号*******************************/
void TM1650_START()
{
SCL=1;
SDA=1;
nop;
SDA=0;
nop;
SCL=0;
}
/******************** STOP信号************************/
void TM1650_STOP()
{
SDA=0;
nop;
SCL=1;
nop;
SDA=1;
nop;
SCL=0;
SDA=0;
}
/****************写1个字节给TM1650********************/
void write_8bit( uchar dat)
{
uchar i;
SCL=0;
for(i=0;i<8;i++)
{
if(dat&0x80)
{
SDA=1;
nop;
nop;
SCL=1;
nop;
nop;
nop;
nop;
nop;
SCL=0;
}
else
{
SDA=0;
nop;
nop;
SCL=1;
nop;
nop;
nop;
nop;
nop;
SCL=0;
}
dat<<=1;
}
SDA=1; //ACK信号
nop;
nop;
nop;
nop;
SCL=1;
nop;
nop;
nop;
nop;
nop;
SCL=0;
nop;
nop;
}
/**********************读8bit**************************/
uchar read_8bit()
{
uchar dat,i;
SDA=1;
dat=0;
for(i=0;i<8;i++)
{
SCL=1; //时钟上沿
nop;
nop;
nop;
dat<<=1;
if(SDA)
dat++;
SCL=0;
nop;
nop;
nop;
nop;
}
SDA=0; //ACK信号
nop;
nop;
nop;
SCL=1;
nop;
nop;
nop;
nop;
SCL=0;
nop;
return dat ;
}
/*******************读按键命令************************/
uchar TM1650_read()
{
uchar key;
TM1650_START();
write_8bit(0x49);//读按键指令
key=read_8bit();
TM1650_STOP();
return key;
}
/*****************发送命令信号***********************/
void TM1650_send(uchar date1,uchar date2)
{
TM1650_START();
write_8bit(date1);
write_8bit(date2);
TM1650_STOP();
}
/*****************显示函数***********************/
void disp()
{
TM1650_send(0x48,0x01); // 开启显示模式:8段显示,8级亮度
TM1650_send(0X68,display[1]); //GID1
TM1650_send(0X6A,display[2]); //GID2
TM1650_send(0X6C,display[3]); //GID3
TM1650_send(0X6E,display[4]); //GID4
}
/**************主函数**************************/
void main(void)
{
disp(); //上电显示1、2、3、4
delay(1);
while(1)
{
keya=TM1650_read();
delay(50);
if (keya!=0)
{
switch(keya) //控制数码管显示数字
{
case 0x44:TM1650_send(0X68,display[5]); break; //K11与DIG1
case 0x4D:TM1650_send(0X68,display[6]); break; //K12与DIG2
case 0x56:TM1650_send(0X68,display[7]); break; //K13与DIG3
default: break;
}
}
}
}