I2C几乎是嵌入系统中最为通用串行总线,MCU周边的各种器件只要对速度要求不高都可以使用。优点是兼容性好(几乎所有MCU都有I2C主机控制器,没有也可以用IO模拟),管脚占用少,芯片实现简单。I2C协议虽然简单,实际使用过程中小毛病还不少。今天先来看一个平日最为常见的问题:I2C从机挂死。

很多事情不难而且经常碰到,每次自认为懂了但最终让你站出来说清楚的时候却总是不能自圆其说,很难受。所以我决定写博客的时候就想尽量把内容写清楚详细甚至是透彻,希望让每一个阅读博文的同学都能看得明明白白,学会一点小知识。如果还有不清楚的可以留言交流.

I2C规范与特性

描述一下I2C最重要的几个特性,为了后面描述问题和解决方案作一些铺垫。

  1. I2C是由两根线(时钟SCL + 数据SDA)组成的多主多从串行同步通信总线。
  2. 规范要求接入I2C的器件,SCL时钟和SDA数据线都必须是双向开漏结构的,通过总线上的上拉电阻拉到逻辑高电平。这样的结构可以实现线与(&)功能。
  3. 一般情况下I2C的SDA只有在SCL为低电平的时候才能改变,为高电平的时候需要保持。对应到芯片设计上则是上升沿采样,下降沿变化。

  4. 两个例外情况由主机发出的总线起始条件START(SCL为高时SDA由高变低)和停止条件STOP(SCL为高时SDA由低变高)

挂死 = 挂了 + 死机

挂死这个词应该来源于英文hangs : To cause (a computer system) to halt so that input devices, such as the keyboard or the mouse, do not function.

前面提到因为线与&结构,是I2C总线设计上最关键的特征,用了这种结构才能实现

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

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

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

SDA挂死

先来看下哪些情况下I2C从机会需要拉低SDA线。

  1. 主机向从机写数据或地址时,从机如果发出ACK应答,则会第9个CLK的期间拉低SDA
  2. 主机读数据的时候,从机会在bit为0时对应的CLK期间拉低SDA

那什么情况I2C从机又可能钳住SDA线呢?我们先来看一个典型的I2C主机发起对某一器件地址读操作,读到的数据为10011000b,MSB在先也就是0x98。在图中地址字节第9个CLK期间从机拉低SDA表示对地址进行应答,在返回的数据字节的第2,3,6,7,8几个CLK器件从机拉低SDA输出逻辑0电平。

根据上面讲的I2C协议SCL为高的时候,SDA电平应保持,而等到SCL为低后(也就是下降沿后)才能发生改变。如果在上面几个CLK的前半个周期SCL拉高后主机不再拉低呢?从机会有什么动作?YES,从机会持续拉低着SDA,直到见到下一个他应该输出高电平的下降沿。

最常见的情况就是主机在通讯的过程中产生了复位。由于复位动作通常会立刻执行,外设状态机都恢复到默认状态,也就发不出完整的CLK了。那么等到主机复位完成回来后,SCL为高,SDA被从机拉低。主机无法发起START起始条件,不能开始下一次与从机的通讯,这称为SDA挂死。

要想办法恢复,我们先得知道从机什么时候会释放SDA。由于刚刚的SCL下降沿没有给出来,恢复总线要做的第一件事情就是在想办法用GPIO在SCL线上模拟一个下降沿,让从机状态机继续走下去。只发一个下降沿并不一定能将SDA释放,因为我们并不清楚当主机复位异常发生时刻从机到底处于图中哪一个状态,所以需要逐个CLK去探测,直到见到SDA被释放了,我们才终止并且发送STOP条件告诉从机这次坑爹的通讯结束了。

网上通常的传授的方法是模拟9个连续的CLK,但是我更喜欢上面的方法,一是速度快,二是具备可确定性。发送9个CLK我主要担心从机在最后一个CLK时又拉低了SDA,还是需要用到上面的方法来释放。

通过模拟几种情形来实际体会一下(从机对SDA的操作红色表示):

如果在地址字节第9个CLK拉高后主机复位。在模拟的第一个时钟低电平期间就可以看到SDA的释放,随后主机先拉低SDA,再模拟一个STOP结束条件。

在数据字节第2个CLK拉高后主机复位,在第二个模拟的时钟低电平期间才看到SDA释放

在数据字节第6个CLK拉高后主机复位,在第三个模拟的时钟低电平期间才看到SDA释放

通过以上三种情况的分析,想必你已经非常清楚改如何处理了,最后附上一个程序处理流程图:

SCL挂死

I2C从机主动拉低SCL线在规范中是一个合法的行为,称之为Clock Stretching(时钟扩展,我一般叫他时钟同步)。通常是主机请求数据( 收或者发)后从机需要一些时间处理,且没有多余Buffer可以接收接或者提供接下来的数据的时候从机则会拉低SCL一段时间直到有新的数据准备好。

SCL挂死(也就是前面所说一直拉低SCL)这种情况在标准I2C从器件上基本不会出现,因为只要芯片还在正常工作buffer总算有准备好的时候,自然就就释放SCL了。往往是使用用户使用MCU作为I2C从机时,程序设计上的问题导致MCU无法读取&填充buffer而导致,重点分析MCU I2C中断服务程序。

  1. I2C中断服务程序被意外屏蔽
  2. 中断服务程序中陷入了一些标志位查询的while(flag != xxx)死循环
  3. I2C功能系统被意外禁止

本文转载

作者:熊小宇
链接:https://www.jianshu.com/p/95f53ca2724e

I2C 挂死原因分析及解决方案相关推荐

  1. USB接口供电不足的原因分析与解决方案

    USB接口供电不足的原因分析与解决方案 USB接口供电不足是什么原因.我们在使用电脑的时候,经常会用到电脑的USB接口,因为有很多USB接口的设备会连接电脑.但是当我们的电脑提示USB接口供电不足,那 ...

  2. AppStore IPv6-only审核被拒原因分析及解决方案-b

    AppStore IPv6-only审核被拒原因分析及解决方案-b 参考文章: (1)AppStore IPv6-only审核被拒原因分析及解决方案-b (2)https://www.cnblogs. ...

  3. linux系统脚本安装失败,ubuntu16.04下vim安装失败的原因分析及解决方案

    先给大家说下问题描述? 重装了ubuntu系统,安装vim出现了以下问题: sudo apt-get install vim 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信 ...

  4. 本机未装Oracle数据库时Navicat for Oracle 报错:Cannot create oci environment 原因分析及解决方案

    本机未装Oracle数据库时Navicat for Oracle 报错:Cannot create oci environment 原因分析及解决方案 参考文章: (1)本机未装Oracle数据库时N ...

  5. Connection reset原因分析和解决方案

    Connection reset原因分析和解决方案 参考文章: (1)Connection reset原因分析和解决方案 (2)https://www.cnblogs.com/exmyth/p/820 ...

  6. 为什么换了硬盘计算机无法启动,完美的解决方案:更换固态硬盘后无法打开计算机的原因分析和解决方案...

    更换SSD固态驱动器后,无法打开计算机的原因分析和解决方案.一些网民首先对自己的计算机反应较慢,然后用SSD固态驱动器代替了硬盘驱动器.他们使用Win8.1系统并正常重启计算机,但是在系统更新之后,打 ...

  7. 美的空气能计算机故障维修,美的空气能热泵热水器故障代码原因分析及解决方案(全)...

    美的空气能热泵热水器故障代码原因分析及解决方案 1.美的空气能热泵热水器E0代码:水流检测故障(进水压力小于0.15MPa) 美的空气能热泵E0代码故障可能原因: 自来水水压不足;水泵扬程不足;水泵没 ...

  8. 我说CMMI 2.0 之:原因分析与解决方案

    原因分析与解决方案(CAR)是对选中的现象识别原因,并采取纠正措施或预防措施. 基本的思想: 组织内的好事和坏事都可以做CAR,并非仅仅是对坏事做CAR.可以在计划阶段做CAR,也可以在事情发生后再做 ...

  9. 斗罗大陆手游服务器维护,斗罗大陆魂师对决怎么进不去 原因分析及解决方案...

    斗罗大陆魂师对决作为动漫原作正版授权的一款真3D斗罗冒险手游,我们将可以体验到一个真实的斗罗大世界,不过一些小伙伴们却遇到了游戏进不去的问题,斗罗大陆魂师对决怎么进不去呢,这里就来分析一下遇到此类问题 ...

最新文章

  1. archlinux安装chrome-webdriver
  2. Katalon Studio之swagger中的API导入
  3. ABAP类的继承、多态、重载
  4. Java的org.apache.commons.lang3.StringUtils
  5. 正态分布图_用EXCEL简易制作正态分布图
  6. Angular之ngx-permissions的角色管理
  7. 计算机课计划,计算机教学计划汇总
  8. linux lnmp1.5.tar.gz,Linux 下lnmp
  9. nginx访问本地目录一直不好使_Nginx跳转本地目录容易犯的错误
  10. Java 并发编程之读写锁 ReentrantReadWriteLock
  11. 基于Python+tkinter+pygame的音乐播放器完整源码
  12. 火狐浏览器手机版_hao123导航app下载-hao123浏览器手机版下载
  13. Matlab Tricks(十八)—— 矩阵间元素距离的计算
  14. 教你如何在微信浏览器下载APP
  15. python table删除一列_在python中从dataframe中删除多个列
  16. 苹果app项目退款教程
  17. “您未被授权查看该页,您不具备使用所提供的凭据查看该目录或页的权限” -- 解决办法
  18. 数学思维导图学习方法
  19. iphone控制中心自定义没有计算机,如何在iPhone上自定义iOS 11控制中心功能
  20. 银河系创投徐芳:专注B2B这片热土,燃起产业新势能 | To B 50+

热门文章

  1. o(1)复杂度之双边滤波算法的原理、流程、实现及效果
  2. const-渣男-直男-暖男的区别
  3. Java - Enum 枚举类型
  4. 小米要进军房地产?雷军花26亿拿下北五环外地块
  5. FineBI-行式填报
  6. 苹果几最好用_苹果树一般用什么肥料最好?既不会让土地硬化,还能保持土壤有机质?...
  7. 【pyqt5学习】——登录界面跳转到主界面,登录界面关闭的情况下从主界面跳转回登录界面
  8. 笔记--Python拼接图片(M * N)
  9. 动态口令(OTP,One-Time Password)原理与实践(TOTP)
  10. 8月13日第五人格服务器维修中,第五人格8月13日更新 沉默宫殿管家上线