You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32作为I2C从机与Jetson AGX通信故障排查求助

STM32 I2C从机与Jetson AGX通信故障排查

需求

将STM32 MCU作为I2C从机连接到Jetson AGX,实现Jetson通过i2cdetect、i2cset、i2cget命令扫描总线并完成寄存器读写操作。

硬件连接

采用STM32 NUCLEO-G071RB开发板作为I2C从机,接线如下:

  • STM32 GND ↔ Jetson AGX 40针引脚9
  • STM32 SCL(PB8) ↔ Jetson AGX 40针引脚5
  • STM32 SDA(PB9) ↔ Jetson AGX 40针引脚3

软件配置

Jetson端

运行JetPack 4.6.0(Ubuntu 18.04),使用系统默认I2C驱动。

STM32端(STMCube IDE)

  • I2C1配置:PB8设为SCL、PB9设为SDA,均启用内部上拉,通信速度100 KHz
  • 从机地址设为0x20(7位地址)
  • 初始化代码:
static void MX_I2C1_Init(void)
{
  /* USER CODE BEGIN I2C1_Init 0 */
  /* USER CODE END I2C1_Init 0 */

  /* USER CODE BEGIN I2C1_Init 1 */
  /* USER CODE END I2C1_Init 1 */
  hi2c1.Instance = I2C1;
  hi2c1.Init.Timing = 0x00303D5B;
  hi2c1.Init.OwnAddress1 = 40;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Analogue filter
  */
  if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Digital filter
  */
  if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C1_Init 2 */
  /* USER CODE END I2C1_Init 2 */
}
  • main循环逻辑(轮询模式):
switch (hi2c1.State)
{
case HAL_I2C_STATE_READY:
  /*!< Peripheral Initialized and ready for use  */
  status = HAL_I2C_Slave_Receive(&hi2c1, buf, 2, 1000);
  if (status == HAL_OK)
      status = HAL_I2C_Slave_Transmit(&hi2c1, buf, 2, 1000);
  break;
};

问题现象

  • 初始因电平不匹配(非3.3V),STM32所有I2C操作均应答失败
  • 调整为3.3V电平后,STM32报告I2C状态为READY,但HAL_I2C_Slave_Receive中等待ADDR标志置位的I2C_WaitOnFlagUntilTimeout函数超时失败
  • Jetson端执行sudo i2cdetect -y -r 8扫描总线,无任何设备响应

排查思路

1. 地址配置错误(核心疑点)

代码中hi2c1.Init.OwnAddress1 = 40是十进制值,对应十六进制0x28,但需求中从机地址是0x20(十进制32)。Jetson扫描的是0x20,而STM32监听的是0x28,必然无法匹配。需修改为:

hi2c1.Init.OwnAddress1 = 32; // 对应7位地址0x20

2. 硬件层面验证

  • 信号检测:用示波器抓取SCL/SDA引脚波形,确认Jetson发送的起始信号、地址帧是否正常到达STM32
  • 上拉电阻:STM32内部上拉可能不足,若接线距离较长或负载较大,需在SCL/SDA与3.3V之间添加10K~47K的外部上拉电阻
  • 共地检查:确保STM32与Jetson的GND连接牢固,共地是I2C通信的必要条件

3. STM32 I2C配置优化

  • 中断模式替代轮询:轮询模式在while循环中可能存在响应延迟,改用中断回调模式更可靠:
    static uint8_t rx_done = 1;
    uint8_t buf[2];
    HAL_StatusTypeDef status;
    
    int main(void)
    {
      HAL_Init();
      SystemClock_Config();
      MX_GPIO_Init();
      MX_I2C1_Init();
    
      while (1)
      {
        if (hi2c1.State == HAL_I2C_STATE_READY && rx_done)
        {
          rx_done = 0;
          status = HAL_I2C_Slave_Receive_IT(&hi2c1, buf, 2);
        }
      }
    }
    
    void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
    {
      if (hi2c->Instance == I2C1)
      {
        // 接收完成后立即准备发送
        HAL_I2C_Slave_Transmit_IT(&hi2c1, buf, 2);
      }
    }
    
    void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
    {
      if (hi2c->Instance == I2C1)
      {
        // 发送完成,允许下一次接收
        rx_done = 1;
      }
    }
    
  • 引脚复用确认:检查PB8/PB9是否被其他外设占用,确保CubeIDE中已正确配置为I2C功能
  • 时钟拉伸:确认NoStretchMode设为I2C_NOSTRETCH_DISABLE(代码中已正确设置),时钟拉伸是从机同步主机的关键

4. Jetson端配置验证

  • 总线号确认:执行i2cdetect -l列出所有I2C总线,确认总线8对应40针的I2C接口
  • 速率匹配:将Jetson的I2C总线速率强制设为100KHz,与STM32匹配:
    echo 100000 | sudo tee /sys/class/i2c-adapter/i2c-8/device/i2c-8/rate
    
  • 扫描模式调整:改用普通扫描模式(去掉-r参数):
    sudo i2cdetect -y 8
    

5. 调试手段

  • STM32寄存器调试:用调试器查看I2C的SR1、SR2寄存器,确认ADDR标志是否被置位,或是否存在AF(应答失败)、BUSY(总线忙)等错误标志
  • Jetson日志排查:执行dmesg | grep i2c查看系统日志,确认是否有I2C通信的错误提示

内容的提问来源于stack exchange,提问作者Moti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 10:52:26