STM32 IIC讀取Eeprom失敗問題

wfagly發表於2024-05-28

現象描述

異常斷開產品的電源,會出現產品無法讀取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();
}

相關文章