STM32H743ZIT6调用HAL_I2C_IsDeviceReady()陷入无限循环求助
STM32H743ZIT6与LMP92066 I2C通信:HAL_I2C_IsDeviceReady()无限循环问题排查
针对你遇到的HAL_I2C_IsDeviceReady()陷入无限循环(tmp1和tmp2始终为RESET)的问题,结合更换I2C外设、提前开时钟无效的情况,从硬件到软件给出以下排查方向:
一、硬件连接优先级排查
I2C通信故障80%以上源于硬件问题,先确认以下几点:
- 上拉电阻缺失/异常:I2C总线必须在SDA、SCL引脚分别接入4.7k~10k的上拉电阻到传感器供电电压(LMP92066为3.3V)。无拉电阻会导致总线电平无法被正确拉高,无法产生ACK或STOP信号,进而让标志位无法触发。
- 引脚对应错误:核对STM32H743的引脚定义,确保SDA/SCL引脚与所选I2C外设匹配(比如I2C1默认SDA=PB7、SCL=PB6,具体以 datasheet 为准),避免引脚接错到其他功能引脚。
- 传感器供电与接地:检查LMP92066的VDD引脚是否有稳定3.3V供电,GND是否与STM32共地,虚焊、断线会直接导致设备无响应。
- 地址引脚配置:LMP92066的I2C地址由ADDR引脚决定,默认接地时7位地址为
0x48,若ADDR接VCC则为0x49,确认实际硬件配置的地址是否与代码中使用的一致。
二、I2C外设配置检查
- 时钟参数配置:
- 确认CubeMX中I2C的时钟模式,LMP92066仅支持最高100kHz的标准模式,不要误设为400kHz快速模式。
- 检查STM32的时钟树,I2C外设的时钟源(APB1/APB2)频率需满足标准模式下≥2MHz,否则会导致通信时序异常。
- HAL初始化状态:调用
HAL_I2C_IsDeviceReady()前,务必确认HAL_I2C_Init(&hi2cx)的返回值为HAL_OK,避免外设未正确初始化就执行探测操作。 - 超时参数设置:不要给
HAL_I2C_IsDeviceReady()的超时参数传HAL_MAX_DELAY,先设置一个合理值(如100ms),观察是否会返回HAL_ERROR(超时),而非无限阻塞。
三、代码层面调试与验证
1. 手动测试I2C通信链路
绕过HAL_I2C_IsDeviceReady(),手动发送起始信号+设备地址,直接检查标志位,确认总线是否能正常交互:
#define LMP92066_ADDR 0x90 // 7位地址0x48左移一位(HAL库要求传入8位带读写位的地址) // 发送起始信号+写地址 HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&hi2c1, LMP92066_ADDR, NULL, 0, 100); if(status == HAL_OK){ // 设备响应正常 }else if(status == HAL_ERROR){ // 检查标志位 if(__HAL_I2C_GET_FLAG(&hi2c1, I2C_FLAG_AF)){ // 应答失败:地址错误或设备无响应 __HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_AF); }else if(__HAL_I2C_GET_FLAG(&hi2c1, I2C_FLAG_TIMEOUT)){ // 总线超时:硬件连接异常 } }
2. 标志位读取逻辑验证
- 确认
__HAL_I2C_GET_FLAG()宏的正确性:STM32H7的I2C_STOPF标志位于SR1寄存器,I2C_AF标志位于SR2寄存器,检查CubeMX生成的stm32h7xx_hal_i2c.h中宏定义是否与寄存器匹配,避免因宏定义错误导致无法读取正确标志。 - 在循环中加入短延时:在原代码的循环内添加
HAL_Delay(1),避免CPU过度占用,给总线足够时间生成STOP或AF标志。
四、其他排查点
- 总线干扰:若电路中有其他高速设备,检查是否存在电磁干扰,可尝试将I2C总线远离电源、高频信号线。
- 传感器复位:若LMP92066有复位引脚,尝试拉低复位后再拉高,确保设备处于正常工作状态。
内容的提问来源于stack exchange,提问作者Kaan Kurtça
相关产品推荐
相关产品推荐

