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()
标签:
STM32
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了