jicheng0622

【学习笔记】I2C总线被挂起的原因和解决办法

0
阅读(2925) 评论(6)

    I2C总线是我们常用的IC之间的通信总线之一,虽然速率有一定的限制(标准的I2C速率才100kbps, Fast I2C速率为400kbps),但是有利有弊,存在即有理,其简单的两线接口(只需要时钟和数据两根线),支持多主机冲突检测和多节点挂载(节点数不受限制,只要总线电容别超过400pF)还是颇受很多人的欢迎的,所以目前市场上大多数需要配置的专用IC都留有I2C接口(有些芯片为了高速通信会使用SPI接口)用来跟主机通信,包括我们常用到的EEPROM,数字量Sensor,电源管理芯片,电量计之类的种种IC,多不胜数,而且I2C接口都是开漏的,所以大多数情况下(不排除有些设备是伪开漏)可以避免主从机IC电平匹配的问题。

    不过我们在实际应用中肯定会遇到过有时I2C总线被挂起的情况(即时钟线和数据线都被强制拉到高电平),当然有些人可能用了N年都没有遇到过(尤其是对搞Linux的人,Linux底层驱动已经做的很完善了,底层驱动在遇到这种情况它会自动去解除这种挂起现象,具体方法我下面介绍),所以我们需要分析一下,到底在那种情况下会出现I2C总线挂起的现象呢,然后给出相应的解决办法:

1. 出现I2C总线挂起的原因,这里我只列出最有可能的几点:

(1)芯片不正确的上电或者复位时序;

(2)在通信过程中主机或者从机突然掉电中断了通信过程;

(3)在通信过程中出现较大的噪声干扰造成了错误的时钟或数据信号,这种情况是最常见的;

2. 至于真的出现这种挂起的状态怎么办呢,实际上包括在I2C协议的参考手册上已经给出了一个标准的解决挂起的方法(经测有效),如下图。主机检测到挂起的情况时(已经读取不出正常的数据来了),主机可以这样做,即主机线先将本身的I2C功能关掉,然后将I2C接口复用成GPIO模式,然后将SDA线一直拉高,然后SCK时钟线主机用GPIO翻转的方式提供至少9个Clock时钟来唤醒从机,最后主机再重新初始化自身的I2C模块将I2C接口使能成I2C功能。这样就基本可以让I2C总线恢复到正常状态了,So Easy不是吗,呵呵。

image

    好了,今天在火车上一鼓作气写了3篇出来,脑细胞真心消耗不少,正好车也到站了,刚刚好,哈哈,一会儿下车赶紧吃点好的补充一下,晚上得好好休息了,下次再聊,未完待续~

 

  1. 另外 是不是还需要一个停止位啊

  2. 我注意到在AT24C02存储器芯片上也有类似的说明.

    MEMORY RESET: After an interruption in protocol, power loss or system reset, any 2-
    wire part can be reset by following these steps:
    1. Clock up to 9 cycles.
    2. Look for SDA high in each cycle while SCL is high.
    3. Create a start condition

    上述的MEMORY RESET应该就是指您提到的操作,而不是将所有数据恢复吧?

  3. 赞赞赞,这方法非常不错。

  4. 匿名用户匿名用户
    点赞,再次点赞!
  5. 精神可嘉,值得鼓励!

  6. 真厉害了,在火车上都在写博客。。。