You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

STM32 I2C中断模式下重复起始发送0x00地址问题求助

STM32 I2C重复起始条件下读地址发送异常问题

我基于STM32开发I2C中断处理程序,写入数据到总线的流程完全正常,但触发**重复起始(repeated start)**条件时出现异常:总线能检测到重复起始信号,但无论如何调整代码,STM32始终发送带读位的0x00地址,而非预期的0x71地址。

状态机定义

eIdle = 0,
eSendingStart = 1,
eSendingAddr = 2,
eSendingValues = 3,
eSendingRepeatedStart = 4,
eSendingAddrForRead = 5,
eReceivingValues = 6

UART输出位定义

MSB 3位4321LSB
StateRXNESBADDRBTFTXE

事件序列(含中断触发与状态机流转)

  1. 设置起始位,状态机切换至eSendingStart
  2. 中断触发,I2C_SR1_SB标志置位,将设备地址写入DR寄存器,状态切换至eSendingAddr
  3. 中断再次触发,但无任何中断标志位,直接忽略;
  4. 中断触发,I2C_SR1_ADDR标志置位(表示从设备应答),状态切换至eSendingValues,此时I2C_SR1_TXE也处于置位状态;
  5. 中断触发,处于eSendingValues状态且I2C_SR1_TXE置位,发送第一个寄存器字节0x00;
  6. 中断触发,处于eSendingValues状态且I2C_SR1_TXE置位,确认所有寄存器字节发送完毕,触发重复起始条件。设置I2C_CR1_STARTI2C_SR1_TXE仍保持置位,需关闭I2C_CR2_ITBUFEN避免中断泛滥,状态切换至eSendingRepeatedStart
  7. 0x00传输结束、重复起始发出前,I2C_SR1_BTF标志置位,读取DR寄存器清除该标志;
  8. 随后I2C_SR1_SB标志置位,将带读位的设备地址(0x71)写入DR寄存器,状态切换至eSendingAddrForRead,等待I2C_SR1_ADDR标志置位(表示从设备应答);
  9. 立即再次触发中断,但无任何中断标志位;
  10. 示波器确认STM32发送了0x00地址而非预期的0x71,后续读数据的RXNE相关代码从未执行——因为eSendingAddrForRead状态下从未检测到ADDR标志。0x00地址被从设备NAK后触发错误中断,此时我设置停止位,UART输出0xEE。

已尝试的调试手段

  • 调整中断处理程序中SR1与SR2寄存器的读取顺序;
  • 尝试先发送停止位再触发起始位(放弃重复起始逻辑);
  • 在不同代码位置写入读地址;
  • 排查中断使能/禁用的时机逻辑。

我曾为其他MCU编写过I2C驱动,从未遇到此类问题,但STM32的I2C接口设计逻辑晦涩,官方手册缺乏有效细节指导,HAL库代码也未覆盖重复起始的完整处理场景,特此求助。

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

火山引擎 最新活动