This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C129 I2C控制器问题

最近调测I2C遇到一些问题,对比了例程和手册没找到合适的答案,请教一下:

1. I2C控制器使能之后发现CLK速率示波器实测并不是如标称的一样是100k or 400k而是几十mhz的速度....代码如下:

    I2CMasterInitExpClk(I2C0_BASE,SysCtlClockGet(), false);
    I2CMasterEnable(I2C0_BASE);

    我的SysCtlClockGet()是120MHZ,查看手册发现MTPR值越大I2C时钟会越小,于是将120M直接*20后配进去发现I2C的CLK能降到60kbps

    这个现象感觉特别诡异啊...

2. I2C在master连续写入+读取的过程中会出现丢失读周期或者写周期的情况....我试过很多次,只有在读写之间加延时才能解决这个问题,不知道是不是用法的错误,我阅读过TI给的示例代码...里面都是通过查询busy状态来等待的...不加就丢...完全无解...

while(1)

{

    ROM_I2CMasterSlaveAddrSet(I2C3_BASE, SLAVE_ADDRESS, false);

    ROM_I2CMasterDataPut(I2C3_BASE, reg_addr);

    ROM_I2CMasterControl(I2C3_BASE, I2C_MASTER_CMD_BURST_SEND_START);

    while(ROM_I2CMasterBusBusy(I2C3_BASE))
    {
    }
    while(ROM_I2CMasterBusy(I2C3_BASE))
    {
    }

    //这里如果不加200us时延就会出现读周期丢失的情况....

    ROM_I2CMasterSlaveAddrSet(I2C3_BASE, SLAVE_ADDRESS, true);

    ROM_I2CMasterControl(I2C3_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);

    while(ROM_I2CMasterBusBusy(I2C3_BASE))
    {
    }
    while(ROM_I2CMasterBusy(I2C3_BASE))
    {
    }

    G_u32Data = ROM_I2CMasterDataGet(I2C3_BASE);

    //这里如果不加200us时延就会出现写周期丢失的情况....

}

  • 1.几十M的速度clock,有点大吧,I2C最大才是2-3M的速度。

    2.你直接放while循环中,肯定是需要判断的,直接判断是否忙呢,不忙继续,忙了返回重新搜索。这个直接重新写个函数就好了。

  • 补充一下,经过查看手册,严格按照手册18-12的表格进行了程序修改,我按照REPEAT_START的方式读取了一个2字节的寄存器值,监测Err信号无异常,如下程序中红色部分是必须添加的延时,不加就会出现各种奇怪的时序错误,比如丢失写Slave读取寄存器地址的周期,或者丢失master读数的一个周期...请问这个时延是怎么确定的?应该如何合理的判断状态?

    u32 test_i2c_read(u32 ui32Base, u8 ui8SlaveAddr, u8 u8RegAddr)
    {
        u32 u32Data = 0;

        //
        // Specify slave address
        //
        I2CMasterSlaveAddrSet(ui32Base, ui8SlaveAddr, false);
        //
        // Place the character to be sent in the data register
        //
        I2CMasterDataPut(ui32Base, u8RegAddr);

        while(I2CMasterBusBusy(ui32Base))
        {
        }

        //配置I2C模式,没有STOP,IDLE->TRANS
        HWREG(ui32Base + 4) = 0x03;

        while(I2CMasterBusy(ui32Base))
        {
        }

        SysDelayMs(500);

        I2CMasterSlaveAddrSet(ui32Base, ui8SlaveAddr, true);

        //配置I2C模式,REPEAT START读数第一的Byte,TRANS->RECV
        HWREG(ui32Base + 4) = 0x0B;

        while(I2CMasterBusy(ui32Base))
        {
        }

        SysDelayMs(500);

        u32Data = I2CMasterDataGet(ui32Base);

        u32Data <<= 8;

        //配置I2C模式,没有START,直接读取第二个Byte,然后STOP,RECV->IDLE
        HWREG(ui32Base + 4) = 0x05;

        while(I2CMasterBusy(ui32Base))
        {
        }

        SysDelayMs(500);

        u32Data |= I2CMasterDataGet(ui32Base);

        g_u32Err |= I2CMasterErr(ui32Base);

        return u32Data;
    }

  • hi:您好!我也遇到同样的问题; 如果在read时候,使用检测I2CMasterBusy();看到还未读完就执行了I2CMasterBusy()后的事件 ;如果使用I2CMasterBusBusy(); 就会看到read完毕,才执行了I2CMasterBusBusy()后的函数; 

    I2C_read();

    while(I2CMasterBusy());//while(I2CMasterBusBusy());

    //delay_1ms();

    printf(“\nissue\n”);

    以上!!!!  求高手来指点下,感激不尽!