現象描述
異常斷開產品的電源,會出現產品無法讀取eeprom資料,並且iic返回繁忙警告。
原因
iic再讀取eeprom時,出現電源抖動的情況。而該電源能維持晶片不進入關機狀態,但是會影響iic通訊問題。
解決辦法
在出現iic忙碌時,將iic復位即可。
void i2c_reset(void)
{
/* 復位I2C */
/*Reset I2C*/
hi2c2.Instance->CR1 |= I2C_CR1_SWRST;
hi2c2.Instance->CR1 &= ~I2C_CR1_SWRST;
/* 配置成普通IO */
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOB_CLK_ENABLE(); // 根據名字,這是使能B埠
GPIO_Initure.Pin=GPIO_PIN_10 | GPIO_PIN_11; // 0口
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; // 推輓輸出
GPIO_Initure.Pull=GPIO_PULLUP; // 上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; // 高速
HAL_GPIO_Init(GPIOB, &GPIO_Initure); // 呼叫初始化函式
/* 開漏輸出,關閉I2C輸入通道,並嘗試將匯流排拉高 */
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10 | GPIO_PIN_11, GPIO_PIN_SET);
/* SCL PB10 拉高 */
for (uint8_t i = 0; i < 10; i++) {
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_10) == GPIO_PIN_SET)
{
break;
}
/* 該延時迴圈的週期和時長,請根據你的實際主機對I2C通訊出錯的處理來修改 */
vTaskDelay(10);
}
/* 歸還匯流排控制權 */
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* 重新初始化I2C */
MX_I2C2_Init();
}