现象描述
异常断开产品的电源,会出现产品无法读取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();
}
标签:HAL,PIN,Initure,STM32,IIC,InitStruct,GPIO,I2C,Eeprom From: https://www.cnblogs.com/wfagly/p/18218933