IIC错误原因汇总
前言
最近手里有个项目,是由IIC总线作为通信协议的。IIC的教程和原理网上一大把,但是我在调试时遇到了一个很奇葩的BUG,整整花费了3天时间才得到解决。因此在这里把调试过程记录一下,给大家遇到相似的问题时以提供一个大致思路。
问题排除流程
1、检查硬件连接问题,注意总线是否连接上拉电阻。
2、检查电压,排除由于硬件设计导致读取失败,注意引脚电平一般为3.3V或1.5V。
3、检查IO口配置,在初始化配置IO时一定要注意IO的配置是否正确,是否有复用或重复定义,多检查几遍,尤其是和官方的Datasheet或者例子相对比一下。
4、检查从机设备地址,从机设备地址设置错误导致通信失败,一般读取到的数据为全1。注意函数需要设置的是7bit地址还是8bit地址。
5、频率问题,此类问题一般有2个
一是频率设置错误,可以通过示波器抓取SCL引脚波形判断;
二是2个设备之间的通信频率不匹配,此类问题一般比较难找(如果读取到数据,但是不对,且在连续变动大概率时频率问题),可以在排除以上原因的前提下多设置几次(一般设备都支持100k【标准】,400k【高速】)
6、未知的原因(一般是由于IIC使用了特殊的设置)可以先查看设备手册上是否使用了与标准协议不同的时序,如果没有就查找IIC官方手册是否有可能用到其中的一些特殊设置。实在不行只能联系厂家询问是否有技术支持。
总结
- IIC中出现的错误大概率是时钟/频率之间的问题,可以灵活使用示波器进行检查。
- 要对官方文档抱有怀疑态度,尤其是一些小公司生产的芯片一定要注意。
我出现的问题是IIC读取从机设备寄存器时得到的数据不对,在排除大量问题之后,才发现是频率出现的问题。两个设备都支持400K的通信速率,并且主机设备设置后通过示波器观察是可以到400k的(官方文档也这么写),从机设备官方的例子就是400k(最大1M)但是两个连接在一起就会出现问题。
现象: 通过示波器发现,写入数据正常,但是读取数据时钟波形缺失,数据也会经常变动。
最后将频率改为100k就可以了。
补充
上面的总结是错的,在使用以上的方法之后,发现在做连续多字节读写时还会出现数据错误。使用逻辑分析仪对数据进行抓取,发现从机在ACK之后会将SCL拉起,变为高电平。在查看IIC总线官方文档之后发现,这是使用了IIC的时钟拉伸,为了解决主从机由于速度不匹配造成的数据错误。
现在问题找到,将时钟拉伸相关操作写入代码。在一个ACK之后,如果检测到时钟信号为高电平,就继续等待,直到检测到低电平再开始下一轮数据操作。
在从机的官方手册中,我并没有找到需要进行时钟拉伸的相关提示。但是在开头就介绍了此模块支持最快高达1MHz的速率,而不是一写其他手册中写的固定400K或100K。
IIC时钟拉伸(Clock Stretching)
时钟拉伸时标准的IIC总线协议,当注意到设备支持宽范围的速率时就应该注意到可能使用了时钟拉伸。一般的单片机硬件IIC也是支持此项功能的,可以在寄存器列表中查找关键词Clock Stretching。
仲裁
此现象发生于多主机连接同一总线的情况。原文如下: