STM32F407VG与ZSC31050 I2C通信忽略ACK位的库修改咨询
解决STM32 I2C忽略ZSC31050首次通信无ACK的问题
我之前调试I2C外设时也碰到过类似这种“特殊”器件不发ACK的情况,针对你这个ZSC31050首次编程无应答的问题,修改HAL库的I2C驱动逻辑来跳过ACK检测是可行的,下面是具体操作步骤:
1. 定位HAL库中I2C发送的核心代码
打开stm32f4xx_hal_i2c.c文件,找到阻塞模式下的主发送函数HAL_I2C_Master_Transmit,或者更底层的I2C_MasterRequestWrite函数——这个函数负责处理地址发送和ACK检测的核心逻辑。
2. 修改ACK检测逻辑
在I2C_MasterRequestWrite函数里,你会看到一段等待地址应答并检测NACK(AF标志)的代码,原来的逻辑是收到NACK就直接返回错误,我们需要修改这段逻辑来忽略NACK:
原代码片段:
/* Wait until ADDR flag is set */ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == RESET) { if ((HAL_GetTick() - tickstart) > I2C_TIMEOUT_ADDR) { hi2c->State = HAL_I2C_STATE_ERROR; hi2c->ErrorCode = HAL_I2C_ERROR_TIMEOUT; return HAL_ERROR; } } /* Clear ADDR flag */ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); /* Check if NACK is received */ if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) != RESET) { __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); hi2c->State = HAL_I2C_STATE_ERROR; hi2c->ErrorCode = HAL_I2C_ERROR_AF; return HAL_ERROR; }
修改后的代码:
/* Wait until ADDR flag is set OR NACK (AF) is received */ while ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == RESET) && (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == RESET)) { if ((HAL_GetTick() - tickstart) > I2C_TIMEOUT_ADDR) { hi2c->State = HAL_I2C_STATE_ERROR; hi2c->ErrorCode = HAL_I2C_ERROR_TIMEOUT; return HAL_ERROR; } } /* Clear ADDR or AF flag based on which was triggered */ if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) != RESET) { __HAL_I2C_CLEAR_ADDRFLAG(hi2c); } else if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) != RESET) { __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); } // 注释掉原来的NACK错误返回逻辑,继续执行后续数据发送 // if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) != RESET) // { // __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); // hi2c->State = HAL_I2C_STATE_ERROR; // hi2c->ErrorCode = HAL_I2C_ERROR_AF; // return HAL_ERROR; // }
3. 更安全的替代方案:自定义发送函数
直接修改HAL库文件有个隐患——后续用STM32CubeMX重新生成代码时,你的修改会被覆盖。所以更稳妥的方式是复制HAL_I2C_Master_Transmit的完整代码,创建一个自定义函数(比如HAL_I2C_Master_Transmit_IgnoreACK),把上面的修改逻辑放到这个自定义函数里,只在和ZSC31050首次通信时调用它,正常通信时还是用标准的HAL函数。
4. 验证修改效果
修改完成后,建议用逻辑分析仪或者示波器抓取I2C总线信号,确认STM32在发送从机地址后,即使没有收到ACK,也能继续发送后续的配置数据。
内容的提问来源于stack exchange,提问作者Orkut Göküş
相关产品推荐
相关产品推荐

