天天看点

[问题]Atiny1617 关于IIC总线一直被拉低的原因分析

在之前的工作中遇到一次IIC总线的问题:一个主设备和两个从设备使用的一路硬件IIC的环境下,当分别加载两个从设备驱动的时候,出现了IIC总线中的SDA被一直拉低,SCL有周期性的毛刺

[问题]Atiny1617 关于IIC总线一直被拉低的原因分析

(图中SDA是黄色线,SCL是蓝色线)

细节图:

[问题]Atiny1617 关于IIC总线一直被拉低的原因分析

用逻辑分析仪抓取的:

[问题]Atiny1617 关于IIC总线一直被拉低的原因分析

其中一个从设备是ATmel系列芯片,而问题就是出在Atmel的硬件IIC中。

经分析,在Atmel发送数据时产生了一个冲突,而在冲突的处理函数中,这里直接重新初始化IIC。

[问题]Atiny1617 关于IIC总线一直被拉低的原因分析

查阅了有关datasheet:

[问题]Atiny1617 关于IIC总线一直被拉低的原因分析
[问题]Atiny1617 关于IIC总线一直被拉低的原因分析

意思是:

如果从设备不能发送高电平或NACK,此时冲突标志位会被置起。

于是就不能发送数据了,但是从设备依然能正常工作。

这个冲突标志位是临时的,下一次的start信号会自动清除掉冲突标志位。

该标志用于使用地址解析协议的系统。 但是,检测到的冲突是非地址解析协议情况,表明存在协议冲突,应将其视为总线错误。

因此,原因是这样的,在主机读数据的过程中,从设备控制SDA,主设备控制SCL,此时重新初始化iic,也直接将管脚进行了初始化,直接打乱SCL的时钟和长期占有SDA。

于是,我尝试将冲突处理函数中的重新初始化和return去掉,发现:

[问题]Atiny1617 关于IIC总线一直被拉低的原因分析

IIC当前的问题帧的数据是不对的,但并不影响之后的帧的数据,也不会造成总线持续拉低的问题。

修改方法:

在冲突处理函数中,仅做打印通知,并且主机做好相应的数据过滤。

继续阅读