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

STM32F3寄存器级开发I2C切换从机地址返回NACK传输失败问题排查

问题原因定位及解决方案

核心故障原因

  • I2C_CR2寄存器未清残留值导致从机地址错误
    你的I2C_WriteByte函数中对CR2寄存器全部使用|=(或运算)赋值,第一次调用写入加速度计地址0x19<<1后,CR2的SADD(从机地址)位已经被写入对应值,第二次调用写入磁力计地址0x1E<<1时,两个地址做或运算得到错误的混合地址,从机识别不到正确地址自然返回NACK,这是最可能的故障原因。
  • 传输逻辑时序错误
    写完两个字节后未等待I2C_ISR_TC(传输完成)标志置1就直接触发STOP条件,可能截断当前传输;且清除STOPCF标志的操作未等待STOP条件硬件完成就执行,会导致I2C状态机异常,影响下一次传输。
  • 外设配置不严谨
    配置TIMINGR寄存器时使用|=运算,若寄存器存在非0复位值或上一次配置残留位,会导致I2C时序参数错误;STM32F3的I2C要求配置核心参数时必须先关闭PE外设使能位,否则配置不生效。
  • 磁力计硬件地址不匹配
    LSM303AGR的磁力计地址由SA0引脚电平决定,若硬件上SA0接高电平,磁力计的7位地址为0x1F而非0x1E,会导致地址帧NACK。
  • 总线状态未复位
    前一次传输产生的错误标志(如NACK、OVR等)未清除,会导致后续传输直接触发异常停止。

修正代码示例

修正后的I2C_WriteByte函数

void I2C_WriteByte(uint8_t sAddress,uint8_t* sData) {
    // 先清除CR2的传输相关残留位
    I2C1->CR2 &= ~(I2C_CR2_SADD_Msk | I2C_CR2_NBYTES_Msk | I2C_CR2_RD_WRN);
    // 写入新的地址和传输字节数
    I2C1->CR2 |= (0x02 << I2C_CR2_NBYTES_Pos) | sAddress;
    // 清空所有错误标志
    I2C1->ICR = 0xFFFFFFFF;
    // 发起起始
    I2C1->CR2 |= I2C_CR2_START;
    
    // 发送第一个字节
    while(!(I2C1->ISR & I2C_ISR_TXIS)) {
        // 加NACK错误判断,避免卡死
        if(I2C1->ISR & I2C_ISR_NACKF) {
            I2C1->ICR |= I2C_ICR_NACKCF;
            I2C1->CR2 |= I2C_CR2_STOP;
            return;
        }
    }
    I2C1->TXDR = sData[0];
    
    // 发送第二个字节
    while(!(I2C1->ISR & I2C_ISR_TXIS)) {
        if(I2C1->ISR & I2C_ISR_NACKF) {
            I2C1->ICR |= I2C_ICR_NACKCF;
            I2C1->CR2 |= I2C_CR2_STOP;
            return;
        }
    }
    I2C1->TXDR = sData[1];
    
    // 等待传输完成
    while(!(I2C1->ISR & I2C_ISR_TC));
    // 触发STOP
    I2C1->CR2 |= I2C_CR2_STOP;
    // 等待STOP完成再清标志
    while(I2C1->CR2 & I2C_CR2_STOP);
    I2C1->ICR |= I2C_ICR_STOPCF;
}

I2C初始化部分修正建议

// 配置TIMINGR前先关闭I2C,且直接赋值不要用|=
I2C1->CR1 &= ~I2C_CR1_PE;
I2C1->TIMINGR = 0x2010091A; // 直接赋值,避免残留位
I2C1->CR1 |= I2C_CR1_PE|I2C_CR1_RXDMAEN;

内容的提问来源于stack exchange,提问作者user13909066

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 09:45:06