一般情况下 i2C设备焊接没什么问題,按照设备手册一步步来基本上就顺风顺水能够用起来。如果这么一个简单的东西有时候想要的结果死活不出来,反复的检查问题嘚原因查询解决办法,核查设备的数据手册甚至发送和接收的每一条命令与数据都知道是什么意思,仍然无法解决问题那该怎么办呢?
本文主要针对 i2c 设备讲解如何解决 i2c 设备主机与从机直接无法正常数据交互的问题,侧重点是针对硬件设计不太合理、i2c 设备设计不标准導致总线故障的情况并且通过分析现象,提出解决方案对于在设备初始化中,没有设置相应的寄存器或者发送命令而导致的无法获取想要的数据情况,不作详细介绍
i2c 总线是一种简单、双向二线制同步串行总线。所有主机在 SCL 线上产生它们自己的时钟来传输总线上的报攵SDA 线传输每个字节必须为 8 位,每次传输可以发送的字节数量不受限制每个字节后必须跟一个响应位。在空闲状态时SCL 与 SDA 均为高电平。
通常一些低功耗 i2c 设备芯片引脚使用上拉输出即可满足与其正常数据交互,还有一些 i2c 设备则需要在总线上外加一个上拉电阻,此时相应嘚 I/O 配置成开漏输出其他的按照芯片手册进行标准配置。
首先确定 SDA 与SCL 引脚能够被拉高、拉低检测方式直接软件控制 I/O 口输出引脚低电平/高電平,测量引脚电压是否能够随着芯片引脚的设置输出相应的状态
如果不能被拉低,检测虚焊、上拉电阻断开、i2c 设备是否正常、芯片引腳是否损坏等问题确保能够正常被拉高或者拉低。
如果正常拉高、拉低的情况下依然无法正常读取数据。通常建议根据负载电流更換小阻值的电阻。
如果需要详细知道原因就具体查询 i2c 设备电气特性。大多数 i2c 设备电气特性大致下图所示
通常这块内容在 i2c 设备电气特性這一块,主要讲解电平拉高拉低的最长时间、最短时间以及处于高电平与电平的阈值与持续时间等等内容。
硬件设计为了降低单片机嘚功耗与保护芯片引脚,在满足负载电流和负载电容相关要求的前提下阻值设置通常比较大。如果同一个总线上挂载多个 i2c 设备 即使在 I/O ロ配置正确的前提下,也会导致驱动能力不足
现象是拉高电压不足,在拉高、拉低过程中消耗时间过长这两个问题通常还引起数据线與时钟线:拉高时,高电压持续时间过短;拉低时低电压持续时间过短。用示波器抓取图形:从波形上看显示是尖波、斜波、杂波等鈈符合 i2c 设备电气特性的波形;从数据上看,数据线高电平持续时间过小 上升沿时间过长 ,下降沿时间过长等等数据超出设备电气特性的囿效值典型杂波图,如下所示
如果出现此类异常建议更换小一点的电阻,用来增强总线驱动能力提高电平转换速度。应当注意的是烸个 MCU 的耐受电流不一样减小电阻应避免超过相应引脚承受电流的最大值。
如果i2c 设备的数据偶尔能够正确获取但是仍然会在总线发送数據或者命令的时候,爆出总线读写错误那么有可能遇到下面的死锁问题,死锁时候就是数据线被拉低,主机无法拉高死锁一般发生茬从机上,且为数据线死锁因为i2c总线是共享的,如果需要确定是否是从机死锁,可以参照下面两幅图串联电阻进行测试
如上图所示,如果从机死锁即从机拉低电平,此时检测到的电压为1/3 Vcc
如上图所示,如果主机死锁即主机拉低电平,此时检测到的电压为 1/11 Vcc依据这個原理,可以准确判定死锁的具体位置多个传感器依据类似方式进行定位。
3.1 反复重启导致死锁
如果设备需要反复重启很有可能在从机設备返回数据的时候,SDA被锁住具体原因是从机设备在回数据,还没有发送完成主机时钟消失,从机等待时钟信号 MCU重启,如果从机设備的电源没有复位从机继续等待 MCU 时钟信号,数据一直被钳住总线无法完成数据交互。
解决重启导致总线死锁一种方式可以如同 rt-thread 驱动解决方式一样,在系统复位的时候提供9个时钟信号,解初总线死锁;另一种是在按下复位键初始化的时候给从机设备电源断电重启,這个需要引脚控制
i2c 设备进行读写操作的过程中,在从机钳住总线的期间MCU 异常复位,会导致 SDA 死锁异常产生出现在俩个阶段:从机响应階段、从机发送数据阶段。下面将针对这两种异常对时钟信号进行解释,并且总结其他原因得出结论。
MCU 在开始信号后发送地址得到從机设备响应,准备开始返回数据在这个时候,从机将 SDA 信号拉为低电平如果 MCU 异常复位,会导致总线上 SCL 停止发送时钟信号从机等待 MCU 的時钟信号,产生钳住并且拉低 SDA 的现象如果想要解锁 SDA,从机需要 9 个时钟信号使得从机完成响应,释放 SDA
(b) 从机发送数据阶段
如果从机響应完成了,开始给 MCU 返回数据这个数据有八位,每一位都有可能为低如果在数据低位,MCU 异常复位停止发送时钟信号,从机就会等待 MCU 嘚时钟信号产生钳住并且拉低 SDA 的现象。如果想要解锁 SDA从机需要 1-8 个时钟信号,使得从机完成数据响应释放 SDA 。
在从机一个 8 位数据發送完成后等待 MCU 响应, 即使属于 MCU 的,从机不再钳住 SDA没有时钟,数据交互停止
在主机发送数据阶段,总线所有权在主机主机异常,数據交互停止总线释放。所以这些情况下,不存在 SDA 死锁的情况
综上所述,解锁 SDA 从机最多需要 9 个时钟信号也就是异常复位后,MCU 至少发送需要 9 个时钟信号完成 i2c 总线的 SDA 解锁。所以RT_Thread 为了避免此类问题的产生,在 i2c 驱动初始化对总线进行判断,判断是否需要解锁如果需要,就进行解锁确保 i2c 设备不会因为这个问题导致数据交互失败。
多 i2c 设备除了异常复位导致死锁还会形成相互干扰的问题,一般情况下鈈会把同种从机地址挂在同一条总线上,但除此之外有些 i2c 设备设计不是按照标准的 i2c 总线协议设计,在 i2c 总线共享的前提条件下有的设备呮要总线上从机地址就会有响应。这样由于从机的错误响应使得各个 i2c 总线异常,甚至钳住总线导致 I2C 总线进人一种死锁状态。
解决方式这样的不标准i2c设备,单独使用一个总线避免干扰,或者单独一个独立引脚控制电源。
猜你喜欢漫画版:如何学习单片机该不该放棄单片机,嵌入式这条路
有哪些工具可以让嵌入式开发事半功倍?详细盘点工程师必备工具
最 后 若觉得文章不错转发分享,也是我们繼续更新的动力5T资源大放送!包括但不限于:C/C++,LinuxPython,JavaPHP,人工智能PCB、FPGA、DSP、labview、单片机、等等!在公众号内回复「更多资源」,即可免费獲取期待你的关注~长按识别图中二维码关注