普誠創智(成都)科技有限公司-论坛

标题: 关于使用PT32U301的IIC模块与TM1650进行通信 [打印本页]

作者: Dooo.    时间: 2021-4-20 17:10
标题: 关于使用PT32U301的IIC模块与TM1650进行通信
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);

然后,就可以开始显示了(6A6C对应显存地址,可看为位选,数字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;
    }
}


作者: James_Jiang    时间: 2021-4-21 10:55
牛!




欢迎光临 普誠創智(成都)科技有限公司-论坛 (https://princeton.com.cn/) Powered by Discuz! X3.2