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.

求助:I2C问题

Other Parts Discussed in Thread: TM4C129ENCPDT

芯片:TM4C129ENCPDT

I2C初始化(应该没问题):

SysCtlClockFreqSet(SYSCTL_XTAL_24MHZ| SYSCTL_USE_PLL | SYSCTL_CFG_VCO_320,20000000);//系统时钟

SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C9);  //I2C9时钟

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

GPIOPinTypeI2C(GPIO_PORTA_BASE,GPIO_PIN_1);//CAMERA_SDA
GPIOPinTypeI2CSCL(GPIO_PORTA_BASE,GPIO_PIN_0);//CAMERA_SCL

GPIOPinConfigure(0x00000002);//GPIO_PA0_I2C9SCL
GPIOPinConfigure(0x00000402);//GPIO_PA1_I2C9SDA

I2CMasterInitExpClk(I2C9_BASE,sysclock,false);// 100Khz传输

===========================================================================

I2C传输多位代码(有问题):

I2CMasterSlaveAddrSet(I2C9_BASE, slave_addr, false);//设备写入地址=0xD0,7位地址为0x68,这里填了7位地址
I2CMasterDataPut(I2C9_BASE, reg_addr);//寄存器地址
I2CMasterControl(I2C9_BASE, I2C_MASTER_CMD_BURST_SEND_START);
while(I2CMasterBusy(I2C9_BASE));

SysCtlDelay(1500);//问题


I2CMasterDataPut(I2C9_BASE, data);//数据
I2CMasterControl(I2C9_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
while(I2CMasterBusy(I2C9_BASE));

==========================================================================
我的操作是:给I2C设备地址为  0xD0  的0x6B寄存器   写入数据  0x00

                                                     0xD0  的0x19寄存器   写入数据   0x07

得出下图,可以看出在0x68和0x00之间有一小段延迟30us,而0x19和0x07之间是220us

问题1:为什么这里两段延迟不一样(可以先看下一个问题)

===================================================================================

第二张图,是我把上面的I2C传输多位数据代码中的    SysCtlDelay(1500); 去掉后得出来的

这次它把寄存器地址全丢了  没发送(原本的顺序是0xD0 0X6B 0X00,0xD0 0X19 0X70)

问题二:为什么会这样子,这代码根据数据手册P1416的程序框图写的(少写了error检查,感觉没关系)

  • //
    // Wait until the slave is done sending data.
    //
    while(!(I2CSlaveStatus(I2C0_BASE) & I2C_SLAVE_ACT_TREQ))
    {
    }

    利用这条指令来识别是否slave ACK响应,如果代码中延时直接去掉,应该是ACK没有接收完成,你就开发下发数据导致。

  • 这段语句不是工作在从发送/接收模式下使用的吗?_?

    我这个是主发送模式的呀

  • 我用I2CMasterBusBusy或是I2CMasterErr函数去检测,也没用,还是漏了寄存器地址没发过去,如下图,

    发了3个写命令还漏了寄存器地址(后面还有4个写命令),然后就陷入I2CMasterBusBusy或I2CMasterErr的死循环了,代码在最后

    I2CMasterSlaveAddrSet(I2C9_BASE, slave_addr, false);
    I2CMasterDataPut(I2C9_BASE, reg_addr);
    I2CMasterControl(I2C9_BASE, I2C_MASTER_CMD_BURST_SEND_START);
    while(I2CMasterBusy(I2C9_BASE))
    {
    }
    **************************************************下面三句是新加的******************************
    while(I2CMasterBusBusy(I2C9_BASE)){

    }
    while((I2CMasterErr(I2C9_BASE) == I2C_MASTER_ERR_ADDR_ACK)){}       地址没被应答
    while((I2CMasterErr(I2C9_BASE)== I2C_MASTER_ERR_DATA_ACK)){}          数据没被应答

    ***************************************************************************************************

    I2CMasterDataPut(I2C9_BASE, data);
    I2CMasterControl(I2C9_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
    while(I2CMasterBusy(I2C9_BASE))
    {
    }

  • 参照附件中例程

  • 问题算是解决了,跟系统频率和I2C速度有关貌似

    原本是20MHz的系统时钟+100KHz的I2C速率

    单单把I2C速率调为400KHz就可以了

    不过在这两个参数条件下,也最多只能做到一次性做5个I2C写入操作不出错,第6个就出错了

    还不是很清楚为什么系统时钟和I2C速率会导致传输出错

  • 我最近也遇到了题主的问题,我个人认为还是和我们没有正确应答ACK有关系,我需要写17个寄存器,也是无法写入寄存器地址,请TI员工给一个正确相应ACK的语句,上面那位员工给的ACK语句在例程中有体现,但是试验中会死在这条语句中,还请TI员工解释下。。。