STM32 I2C 死锁笔记

问题
调试中遇到过这样一个问题,主芯片访问外部I2C设备时,市场出现I2C读写time out,而且一旦出现这个问题后,I2C的SCL一直为高,SDA一直为低;I2C访问会一直失败。

分析
1) 对于I2C主设备来说,由于检测到SDA信号为低电平,则会认为I2C总线被占用,I2C主设备等待从设备释放SDA信号,而同时I2C从设备又在等待主设备将SCL信号拉低以释放应答信号,两者相互等待,I2C总线进入死锁状态。
2) 从现象上看很可能由主从设备的时序不匹配导致。
硬件I2C 超时时间可能小于从设备响应所需要的时间。

解决
1.延长超时等待时间:STM32H7 与F4 时钟tick不同,移植程序时考虑延长超时时间。

2.cube生成的例程有BUG:
修复如下

  /* I2C2 clock enable */
      __HAL_RCC_I2C2_CLK_ENABLE(); //提到GPIO初始化前面
      __HAL_RCC_GPIOB_CLK_ENABLE(); 

3.开启I2C事件中断+发送接收DMA
能够应付大部分情况,但是碰到从器件不依不饶,非给你SDA一直拉低,占着总线,还是没办法修复

4.I2C超时复位,根据网上解决死锁问题的博客,问题一般是读取从器件的时候时钟没给完,从器件拉低了SDA,并等待后续SCL时钟;所以采取发送9个时钟查询SDA是否拉高;来恢复SDA,但我遇到的问题时在正确写完从期间后,从器件将SDA拉低;所以采取网上的方式并不能解决问题。

发布了15 篇原创文章 · 获赞 0 · 访问量 283

猜你喜欢

转载自blog.csdn.net/qq_33552551/article/details/104798327