CMSIS-Driver I2C驱动异常:状态持续卡在Busy
问题
使用STM32F407VGT6 + AT24C256 EEPROM学习CMSIS-Driver的I2C驱动,通过CubeMX配置I2C环境后,参考ARM官方示例修改代码(已将EEPROM_I2C_ADDR改为0xA0适配AT24C256),调用EEPROM_Initialize(true)时,程序卡在EEPROM_Read_Pool函数的while (I2Cdrv->GetStatus().busy);循环中(执行完I2Cdrv->MasterTransmit后)。
已完成的排查动作:
- 用HAL库的
MEM_Write/MEM_Read验证EEPROM可正常通信 - 检查
PowerControl/Control/MasterTransmit等函数返回值均为0x00000000(无错误) - 调试发现未进入
I2C_EV_IRQHandler或I2C_ER_IRQHandler中断函数
排查与解决建议
1. 中断配置检查
CubeMX中需确保I2C的事件中断和错误中断已正确开启:
- 进入I2C配置页面,在
NVIC Settings中勾选I2Cx event interrupt和I2Cx error interrupt - 确认中断优先级配置合理,避免被其他高优先级中断抢占导致无法响应
- 检查生成代码中
HAL_NVIC_EnableIRQ(I2Cx_EV_IRQn)和HAL_NVIC_EnableIRQ(I2Cx_ER_IRQn)是否存在且未被注释
2. CMSIS-Driver与CubeMX配置兼容性验证
CMSIS-Driver的I2C驱动依赖正确的底层配置,需确认:
- CubeMX生成的I2C初始化代码中,是否开启了中断模式(而非轮询模式),CMSIS-Driver的
MasterTransmit默认依赖中断完成传输 - 检查
I2C_HandleTypeDef的Init.Mode是否设置为I2C_MODE_I2C,而非其他模式 - 确认
I2C_MspInit函数中,已正确配置GPIO为开漏输出并启用上拉电阻(AT24C256要求I2C总线带上拉)
3. CMSIS-Driver回调函数绑定检查
CMSIS-Driver的I2C状态更新依赖中断回调函数,需确认:
- 初始化代码中是否正确调用
I2Cdrv->Initialize()并传入自定义回调函数(用于处理传输完成、错误等事件) - 回调函数中是否正确更新I2C状态标志,比如传输完成时将
busy位置为false - 对照ARM官方示例,确认回调函数实现逻辑完整,未遗漏状态更新步骤
4. AT24C256地址与时序适配
针对AT24C256的I2C特性调整参数:
- 0xA0是7位地址左移1位(包含读写位)的结果,若CMSIS-Driver要求传入7位地址,需改为0x50(0xA0 >> 1),部分驱动会自动左移地址并添加读写位
- 检查
MasterTransmit的传输数据是否包含AT24C256的2字节存储地址,时序是否符合EEPROM写操作后的ACK等待要求
5. 硬件与调试补充
- 在
I2C_EV_IRQHandler和I2C_ER_IRQHandler中添加调试输出或临时断点,确认中断是否真的未触发(排除调试器断点未命中的情况) - 用示波器或逻辑分析仪抓取SDA/SCL信号,查看
MasterTransmit发送后是否收到ACK,总线是否处于挂起状态
内容的提问来源于stack exchange,提问作者BF_zub
相关产品推荐
相关产品推荐

