STM32 HAL 库 I2C_WaitOnFlagUntilTimeout BUSY 解决办法

今日使用STM32F103读写MLX90640 热成像相机, 采用硬件IIC时老是返回繁忙 或者错误, 运气好的话只有第一次成功访问,但后续将无法读取数据
经测试研究发现,系为 IO直接对接,未做信号上拉导致,检测到SDA持续为低 STM32单片机误以为是有设备占用总线,便一直处于忙状态。

解决方式

  1. 外接上拉电阻

  2. STM32IIC引脚 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;改为推挽输出 也就是单片机的内置上拉给启用 便能解决

使用的CubeMX生成的工程 这里便不再粘贴更多源码

2022年10月18日
问题依旧出现,便可能是IIC初始化后总线上SCL 或SDA 有低电平信号 导致总线仲裁失败,因此设备处于繁忙状态;
官方的详细解释 见https://wenku.baidu.com/view/8c4d675cff00bed5b9f31dd9.html
官方给的方案简单来说就是 使用I2C_CR1->SWRST 进行I2C复位。解除I2C_SR2->BUSY问题。
STM32 HAL 库 I2C_WaitOnFlagUntilTimeout BUSY 解决办法_第1张图片

注意

本人在实际测试过程中,由于使用的HAL库,使用CubeMX生成的,因此并不想改动太多,在原有结构上我将复位操作加入初始化 经测试设备不再busy


void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
 if(i2cHandle->Instance==I2C2)
  {
  /* USER CODE BEGIN I2C2_MspInit 0 */

  /* USER CODE END I2C2_MspInit 0 */

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**I2C2 GPIO Configuration
    PB10     ------> I2C2_SCL
    PB11     ------> I2C2_SDA
    */
    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* I2C2 clock enable */
    __HAL_RCC_I2C2_CLK_ENABLE();
  /* USER CODE BEGIN I2C2_MspInit 1 */
  /*Reset I2C****************在设备初始化之前便添加此操作************************/
  i2cHandle->Instance->CR1 |= I2C_CR1_SWRST;
  i2cHandle->Instance->CR1 &= ~I2C_CR1_SWRST;
  /* USER CODE END I2C2_MspInit 1 */
  }
}

后续使用过程中 如果发现busy 则调用反初始化 再初始化即可
HAL_I2C_DeInit(&hi2c2);
MX_I2C2_Init();

你可能感兴趣的:(单片机,stm32,单片机,arm)