协议规定,SCL时钟和SDA数据线都必须是双向开漏结构的,通过总线上的上拉电阻拉到逻辑高电平,空闲状态SCL和SDA应该被上拉到高电平,这样的结构可以实现线与的操作。 一般情况下I2C的SDA只有在SCL为低电平的时候才能改变,为高电平的时候需要保持。对应到芯片设计上则是上升沿采样,下降沿变化。两个例外情况由主机发出的总线起始条件START(SCL为高时SDA由高变低)和停止条件STOP(SCL为高时SDA由低变高)

MCU做主机SCL一直拉低 是因为SDA被从机锁死,主机拉低SCL想要控制SDA,导致的,加个超时错误,重新IIC失能就可以不复位MCU解决

SDA被拉低: 主机会发送9个clk尝试拉高SDA,如果不能成功,需要硬件复位 SCL被拉低: 主机主动拉低SCL是合理的行为,在IP初始化配置的时候,可以选择时钟展频功能。 如下图在从机访问地址与写入数据之间加入一点延时,就会出现SCL被主机拉低的情况

其它情况的SCL拉低就要考虑代码实现是否合理了: 1、I2C是否被意外关闭了 2、是否在某个位置有while等待,一直无法跳出循环

**线与&**结构,是I2C总线设计上最关键的特征,用了这种结构才能实现:

  • 多主机仲裁同步
  • 慢从机同步快主机

因为这个特性,只要总线上任何一个器件拉低了SDA或者SCL,其他器件都无法拉高它们,看到的都是低电平。如果有器件不释放总线,则整个总线上的通讯都会被暂停,我们成为I2C bus hangs:I2C总线挂死

因为I2C主机一般是可编程的器件,受我们控制,如果主机主动拉低了总线,我们可以通过调试代码了解原因,也可以很方便的通过复位I2C外设或者复位芯片来退出这种状态。而I2C从机往往不带RESET引脚,如果挂死了总线即使整个系统复位都无法解除,仅重新上下电才可以恢复。很多系统上是不可接受的,因此我们需要更加小心的处理I2C从机挂死的情况,下面分析也是针对I2C从机挂死来写的。