STM32 IIC读取Eeprom失败问题

现象描述

异常断开产品的电源,会出现产品无法读取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();
}

 

posted @ 2024-05-28 21:17  wfagly  阅读(388)  评论(0)    收藏  举报