1.如何用IIC和TM1650进行通信
2.对程序的优化
1.如何用IIC和TM1650进行通信
TM1650采用2 线串行传输协议通讯,但该数据传输协议不是标准的I2C协议,所以需要将数据命令和显存地址作为从机地址使用。模式命令(0x48)和显存地址(0x68、0x6A、0x6C、0x6E)都是8位,而从机地址为7位。IIC发送从机地址时为8位,7位地址+读写位,刚好'0'为写,模式命令(0x48)和显存地址(0x68、0x6A、0x6C、0x6E)的bit0也都为0,使用TM1650驱动数码管为写操作,所以将数据命令和显存地址的高7位作为地址写入从机地址寄存器。
例:I2CMDevAddr(I2C0,0x48>>1);
I2CMDevAddr(I2C0,0x6a>>1);
此时,便可以通过TM1650的写显示时序驱动数码管了。
首先,对数码管亮度进行设置
I2CMDevAddr(I2C0,0x48>>1);//模式命令 I2CMDevEn(I2C0,ENABLE); I2CMByteWr(I2C0,0x71);//7级亮度+8段显示+开显示 I2CMPktDone(I2C0);
然后,就可以开始显示了(6A、6C对应显存地址,可看为位选,数字0-7对应段选a(bit0) b(bit2) c(bit3) d(bit6) e(bit7) f(bit1) g(bit5) ) uCHAR display_0_9_DATA[11] = {0xcf,0x0c,0xe5,0x6d,0x2e,0x6b,0xeb,0x0d,0xef,0x6f,0x00};//对应数码管0-9显示以及关
//两位数显示,6A对应十位,6C对应个位,显示0-99例程如下: while(1) { I2CMDevAddr(I2C0,0x6a>>1); I2CMDevEn(I2C0,ENABLE); I2CMByteWr(I2C0,display_0_9_DATA[data/10]); I2CMPktDone(I2C0); // I2CMDevAddr(I2C0,0x6c>>1); I2CMDevEn(I2C0,ENABLE); I2CMByteWr(I2C0,display_0_9_DATA[data%10]); I2CMPktDone(I2C0); // if(data >= 99) { data = 0; } else { data++; } }
2.对程序的优化
上面程序简单的显示是没问题了,但是仔细观察I2CMPktDone(I2C0);函数,它里面内容为:
while (!(pI2CxCtrl[i2cx]->I2C_STATUS&I2CSTS_TFE));
while(pI2CxCtrl[i2cx]->I2C_STATUS&I2CSTS_ACTIVITY);
两个while意味着在将数据写入I2C_DATA_CMD寄存器后,必须等到发送FIFO为空并且IIC处于空闲状态时,才会进行下一步操作。发送一次address+data时间约为180us(IIC速度设置为100K),如果显示两位数,则需等待约360us,在电机驱动中,这么长的一段等待时间已经能够影响驱动了。
此时如果把while改成if,在判断发送FIFO为空并且IIC处于空闲状态时,再写字节I2CMByteWr(I2C0,DATA); 此时需要的时间便只有将数据写入寄存器的时间,等待完成的时间就空出来了,而这段时间就可以去运行其他的程序了。
优化后程序如下:
while(1)
{
switch(AddressIndex)
{
case 0:
if((pI2C0Ctrl->I2C_STATUS&I2CSTS_TFE) && !(pI2C0Ctrl->I2C_STATUS&I2CSTS_ACTIVITY))
{
I2CMDevAddr(I2C0,0x6a>>1);
I2CMDevEn(I2C0,ENABLE);
//
if(Ten != 0)
{
I2CMByteWr(I2C0,display_0_9_DATA[Ten]);
}
else
{
I2CMByteWr(I2C0,display_0_9_DATA[10]);
}
AddressIndex = 1;
}
break;
case 1:
if((pI2C0Ctrl->I2C_STATUS&I2CSTS_TFE) && !(pI2C0Ctrl->I2C_STATUS&I2CSTS_ACTIVITY))
{
I2CMDevAddr(I2C0,0x6c>>1);
I2CMDevEn(I2C0,ENABLE);
//
I2CMByteWr(I2C0,display_0_9_DATA[Unit]);
AddressIndex = 0xFF;
}
break;
default:
if(data >= 99)
{
data = 0;
}
else
{
data++;
}
Ten = data/10;
Unit = data%10;
AddressIndex = 0;
break;
}
}
|