You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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üş

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:26:45