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.

[参考译文] TM4C123GH6PM:I2C 通信在初始上电时不工作、但在调试后工作。

Guru**** 2604225 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/749245/tm4c123gh6pm-i2c-communication-not-working-on-intial-power-up-but-works-once-debugged

器件型号:TM4C123GH6PM

您好!

I2C 在初始上电时不会读取寄存器、但如果我进行了一次调试、它会在接下来的所有运行中按预期工作。  

我使用的是 CCSv8.1、Windows 10、EK - TM4C123GXL

I2C0通道用于 I2C 通信。

I2C0 SCL - PB2

I2C0 SDA - PB3

我在此附上了我的代码片段:

/*检查 I2C SDA 是否未保持低电平如果是,则切换 I2C SCL 直到它被释放
*按下"Reset"按钮时可安全进行 i2c 通信*/

GPIOPinTypeGPIOInput (GPIO_PORTB_BASE、GPIO_PIN_3);
GPIOPinTypeGPIOOutput (GPIO_PORTB_BASE、GPIO_PIN_2);
while (GPIOPinRead (GPIO_PORTB_BASE、GPIO_PIN_3)!= GPIO_PIN_3)
{
GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_2、0);
GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_2、GPIO_PIN_2);
} 

初始化 I2C:

/* I2C0 Init */
/*启用外设*/
SysCtlPeripheralEnable (SYSCTL_Periph_I2C0);

//为 I2C0SCL 的 PB2配置 GPIO 引脚多路复用器

GPIOPinConfigure (GPIO_PB2_I2C0SCL);
GPIOPinTypeI2CSCL (GPIO_PORTB_BASE、GPIO_PIN_2);

//为 I2C0SDA 的 PB3配置 GPIO 引脚多路复用器

GPIOPinConfigure (GPIO_PB3_I2C0SDA);
GPIOPinTypeI2C (GPIO_PORTB_BASE、GPIO_PIN_3); 

我将 TI-RTOS 2.16.00.08用于配置如下的项目、作为任务从 IMU 传感器获取数据:

void get_IMU()
{
I2C_Handle i2c;
I2C_Params i2cParams;
uint8_t 电源;
PWR = 0x00;

//创建 I2C 以供使用
I2C_Params_init (&i2cParams);
i2cParams.bitrate = I2C_400kHz;
I2C = I2C_open (IMU_sensor、&i2cParams);
if (i2c == NULL)
{
System_abort ("初始化 I2C\n 时出错");
}
其他
{
system_printf ("I2C 已初始化!\n");
}

//初始化 MPU6050
writeRegister (i2c、0x6B、0x80、true);
读寄存器(i2c、0x6B、&pwr、1、true);
操作
{
读寄存器(i2c、0x6B、&pwr、1、true);
}
while (pwr & 0x40!= 0x40);

//使用具有 X 轴陀螺仪基准的 PLL
writeRegister (i2c、0x6B、0x01、true);
//启用 I2C 主机模式
writeRegister (i2c、0x6A、0x20、true);
//设置采样率分频器
writeRegister (i2c、0x19、0x13、true);
writeRegister (i2c、0x67、0x11、true);

while (1)
{
Semaphore_pend (IMUSem、BIOS_wait_forever);
readRegister (i2c、0x3B、(uint8_t *)&signal.imu.mpu6050、14、true);
}

//取消初始化 I2C
I2C_Close (i2c);
System_printf ("I2C 已关闭!\n"\});
system_flush();
}

此致、

Yashwanth Kumar Gandeti。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您发布的内容对我来说是正确的。 我建议您使用逻辑分析仪来查看未连接 Code Composer 的 SCL 和 SDA。 (使用重置按钮。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Bob Crosby:

    我已使用逻辑分析仪进行验证。 这是相同的屏幕截图。  读数为00。

    在调试一次之后、通过保持断点在  

    writeRegister (i2c、0x6B、0x80、true);//在 get_IMU ()任务中
    

    并运行代码、即使在复位后也能获得正确的传感器数据。 以下是调试一次并按建议按下按钮后的屏幕截图。

     

    很抱歉、我也没有通过使用逻辑分析仪发现任何变化。

    此致、

    Yashwanth Kumar Gandeti。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您需要的是处于故障模式时开始的逻辑分析仪轨迹。 将0x80写入寄存器0x6B、然后读取该寄存器、直到 SLEEP 位置位(0x40)、然后写入0x01。 写入0x01清零 SLEEP 位、MPU6050开始工作。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Bob Crosby:

    希望现在已附上正确的图像,因为 您可以看到0x6B 被写入0x01 (有效载荷中的第6条记录)。

      

    之后 、来自 0x3B 的14个寄存器的输出为00。 这是相同的屏幕截图。

    请在这方面帮助我。

    此致、

    Yashwanth Kumar Gandeti。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我看到问题了。 您写入0x80、然后读取一个0x00两次。 它应该继续读取、直到您读取0x40。 写入0x01太快了。 MPU6050没有完成复位序列。 根本原因是您的 DO{}while;中的运算符优先。 尝试以下操作:

    操作
    {
    读寄存器(i2c、0x6B、&pwr、1、true);
    }
    while ((pwr & 0x40)!= 0x40);
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Bob Crosby、
    感谢您的支持。 您的解决方案解决了我的问题。