IIC死锁现象和解决办法
背景知识
1.IIC总线空闲状态
IIC总线中,当SCL和SDA都为高电平时,总线处于空闲状态
2.IIC总线起始信号
IIC总线中,当处于空闲状态时,SCL为高,SDA由高到低的变化为起始信号
3.IIC总线停止信号
IIC总线中,当传输完数据后,SCL为高,SDA由低变高为停止信号,停止信号都由主机发出
4.SCL为低时可以传输数据,传送完后SCL会被拉高,在SCL上升沿开始传输数据。SCL为高时要保持SDA数据稳定
5.发送完数据,读完数据,发送完STOP信号,都要延时一会,等设备反应
IIC死锁现象
正常情况下,IIC总线能保证总线正常读写操作,但是,IIC设备异常复位(看门狗动作,板上电源异常到时芯片动作,手动按钮复位等等)都有可能导致IIC总线死锁产生。
在IIC主设备进行读写操作过程中,主设备开始信号控制八个时钟脉冲,然后拉低SCL信号为低电平,在这个时候,从设备输出应答信号,将SDA信号拉为低电平;如果这个时候主设备异常复位,SCL就会释放为高电平。此时,如果从设备没有复位,就会继续IIC的应答,将SDA一直拉为低电平,知道SCL变为低电平,才会结束应答信号。而对于IIC主设备来说,复位后检测SCL信号和SDA信号,则会认为IIC总线被占用,会一直等待SCL和SDA信号变为高电平。这样,IIC主设备等待从设备释放SDA信号,而同时IIC从设备又在等待主设备SCL拉低以释放应答信号,两者相互等待,IIC总线进入一种死锁状态。同样,当IIC进行读操作,IIC从设备应答输出数据,如果这个时刻IIC主设备异常复位,而此时IIC从设备输出数据正好为0,也会到时IIC总线进入死锁状态。
死锁现象:SCL为高,SDA一直为低
从:正常时序下,SDA信号是在SCL为低的状态下改变,即从应答SDA为低电平时,此时SCL应为低电平(即从设备是先拉低SDA信号,等待主设备SCL由高变低,取走ACK信号,从设备再释放SDA为高),但如果此时时序被打乱,例如单片机IIC通讯时突然复位,SCL突然变高,则从设备SDA一直为低,等待SCL变低。
主:SDA被从拉低,故主认为IIC总线占用,一直等待SDA变高
这样主从进入一个相互等待的死锁过程
死锁的解决办法
最好用模拟IIC实现,则不会死锁
1.尽量使用带复位输入的IIC从器件
2.将所有的IIC设备的电源连在一起,通过MOS管连接到主电源,而MOS管的导通关断由IIC主设备实现
3.在IIC从设备设计看门狗功能
4.在IIC主设备中增加IIC总线恢复程序,每次IIC主设备复位后,如果检测到SDA数据一直被拉低,则控制IIC的SCL时钟线产生9个时钟脉冲(针对8位数据情况),这样从设备就可以完成被挂起的读操作,从死锁状态中恢复过来,因为大部分主设备的I2C模块由内置的硬件电路来实 现,软件并不能够直接控制SCL信号模拟产生需要时钟脉冲。
5.在I2C总线上增加一个额外的总线恢复设备。这个设备监视I2C总线。当设备检测到SDA信号被拉低超过指定时间时,就在SCL总线上产生9个时钟脉冲,使I2C从设备完成读操作,从死锁状态上恢复出来。总线恢复设备需要有具有编程功能,一般可以用单片机或CPLD实现这一功能。
6.在I2C上串人一个具有死锁恢复的I2C缓冲器,如Linear公司的LTC4307如图2所示:LTC4307是一个双向的I2C总线缓冲器,并且具有I2C总线死锁恢复的功能。 LTC4307总线输人侧连接主设备,总线输出侧连接所有从设备。当LTC4307检测到输出侧SDA或SCL信号被拉低30ms时,就自动断开I2C总线输人侧与输出 侧 的连接.并且在输出侧SCL信号上产生16个时钟脉冲来释放总线。当总线成功恢复后,LTC4307会再次连接输人输出侧,使总线能够正常工作。
更多推荐

所有评论(0)