STM32 HAL庫 I2C 工作出錯 返回I2C_BUSY


使用stm32cubemx生成硬件I2C的代碼
不過自動生成的代碼,調用HAL_I2C_XXX的API工作不正常,返回錯誤代碼為I2C_BUSY
使用STM32的I2C接口使用時需要注意很多細節,不過HAL庫中官方已經為用戶根據這些細節做了處理,可以直接使用。不過這個I2C代碼並不穩定,有些板子可以用,另一些則出錯.

出錯現象為調用HAL_I2C的API時,返回I2C_BUSY

查看寄存器 BUSY位被置位

在此基礎上,替換過上拉電阻亦沒有作用
在網上搜到一個回答解決了這個問題

附下原文鏈接
https://electronics.stackexchange.com/questions/272427/stm32-busy-flag-is-set-after-i2c-initialization?answertab=votes#tab-top

解決方案 將自動生成的代碼中,HAL_RCC_I2C1_CLK_ENABLE()放到GPIO初始化之前就不會出現這個問題,I2C工作正常

具體依據沒有找到,不過在HAL的說明文檔中有要求這樣的初始化順序,同時其他的模塊如SPI或UART,也都是先初始化模塊(SPI,UART),再初始化GPIO

void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(i2cHandle->Instance==I2C1)
  {
  /* USER CODE BEGIN I2C1_MspInit 0 */
	__HAL_RCC_I2C1_CLK_ENABLE(); //添加時鍾使能命令
  /* USER CODE END I2C1_MspInit 0 */
  
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**I2C1 GPIO Configuration    
    PB6     ------> I2C1_SCL
    PB7     ------> I2C1_SDA 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* I2C1 clock enable */
    __HAL_RCC_I2C1_CLK_ENABLE();

    /* I2C1 interrupt Init */
    HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
  /* USER CODE BEGIN I2C1_MspInit 1 */

  /* USER CODE END I2C1_MspInit 1 */
  }
}

其他解決方式

即初始化時,重新置位下I2C,再重新初始化,雖然說這種方法也可行,只是總感覺不太合適。再沒有找到合理的解決方式之前也用這個方式試過。
重置方式有兩種

一、I2C寄存器復位


換成代碼可以是這樣,
hi2c1.Instance->CR1 |= 0x8000;
hi2c1.Instance->CR1 &= ~0x8000;

不過這個操作之后I2C必須要重新初始化,可用於除錯的處理吧

I2C1的復位操作也可以通過操作另外一個標志位達到復位的效果

二、APB寄存器復位


置位I2C1RST來達到復位I2C的效果
HAL中有現成的庫函數定義
__HAL_RCC_I2C1_FORCE_RESET()
__HAL_RCC_I2C1_RELEASE_RESET()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM