本帖最后由 Ernest2000 于 2019-7-13 10:36 编辑
一般情况下, i2c 设备焊接没什么问题,按照设备手册一步步来,基本上就顺风顺水能够用起来。如果这么一个简单的东西,有时候想要的结果死活不出来,反复的检查问题的原因,查询解决办法,核查设备的数据手册,甚至发送和接收的每一条命令与数据都知道是什么意思,仍然无法解决问题,那该怎么办呢? 本文主要针对 i2c 设备,讲解如何解决 i2c 设备主机与从机直接无法正常数据交互的问题,侧重点是针对硬件设计不太合理、i2c 设备设计不标准导致总线故障的情况,并且通过分析现象,提出解决方案。对于在设备初始化中,没有设置相应的寄存器或者发送命令,而导致的无法获取想要的数据情况,不作详细介绍。
1 i2c 基本用法i2c总线是一种简单、双向二线制同步串行总线。所有主机在SCL线上产生它们自己的时钟来传输I2C总线上的报文,SDA 线传输每个字节必须为 8 位,每次传输可以发送的字节数量不受限制,每个字节后必须跟一个响应位。在空闲状态时,SCL 与 SDA 均为高电平。 通常一些低功耗 i2c 设备,芯片引脚使用上拉输出即可满足与其正常数据交互,但是还有一些 i2c 设备,则需要在总线上外加一个上拉电阻,此时相应的 I/O 配置成开漏输出,其他的按照芯片手册进行标准配置。
2 硬件问题汇总2.1 无法正常拉高拉低引脚首先确定 SDA 与SCL 引脚能够被拉高拉低,检测方式直接软件控制 I/O 口输出引脚低电平/高电平,测量引脚电压是否能够随着芯片引脚的设置输出相应的状态。 如果不能被拉低,检测虚焊、上拉电阻断开、i2c设备是否正常、芯片引脚是否损坏等问题,确保能够正常被拉高或者拉低。
2.2 电气特性无法满足如果正常拉高拉低的情况下,依然无法正常读取数据。如果不考虑具体情况,就直接换电阻,逐渐换小阻值的电阻。如果需要详细知道原因,就具体查询 i2c 设备电气特性。 大多数 i2c 设备电气特性,大致下图所示 file://E:/document/i2c_solve_method/figures/clip_image001.png?lastModify=1561689369 通常这块内容在 i2c 设备电气特性这一块,主要讲解电平拉高拉低的最长时间、最短时间,以及处于高电平与电平的持续时间。 一般硬件设计,为了降低单片机的功耗与保护芯片引脚在单片机,上拉电阻一般建议常用阻值为4.7k。如果同一个总线上挂载多个 i2c 设备, 即使在 I/O 口配置正确的前提下,也会导致驱动能力不足,导致图2所示的问题 file://E:/document/i2c_solve_method/figures/clip_image003.png?lastModify=1561689369 图中两个问题通常还引起数据线与时钟线:拉高时,高电压持续时间过短;拉低时,低电压持续时间过短。用示波器抓取图形,从波形上看,显示是尖波、斜波、杂波等不符合 i2c 设备电气特性的波形;从数据上看,数据线高电平持续时间过小 ,上升沿时间过长 ,下降沿时间过长等等数据超出设备电气特性的有效值。 如果出现此类异常,建议更换小一点的电阻,但不应小于1kΩ(避免芯片引脚烧坏),用来增强总线驱动能力,提高电平转换速度。
3 SDA 死锁如果i2c 设备的数据偶尔能够正确获取,但是仍然会在总线发送数据或者命令的时候,爆出总线读写错误,那么有可能遇到下面的死锁问题,死锁时候,就是数据线被拉低,主机无法拉高。死锁一般发生在从机上,且为数据线死锁。因为i2c总线是共享的,如果需要确定,是否是从机死锁,可以参照下面两幅图,串联电阻进行测试 file://E:/document/i2c_solve_method/figures/clip_image005.png?lastModify=1561689369 如上图所示,如果从机死锁,那么就是从机拉低电平,此时检测到的电压为 Vcc*(5/(10+5))。 file://E:/document/i2c_solve_method/figures/clip_image007.png?lastModify=1561689369 如上图所示,如果主机死锁,那么就是主机拉低电平,此时检测到的电压为 Vcc*(1/(10+1))。依据这个原理,可以准确判定死锁的具体位置,多个传感器依据类似方式进行定位。
3.1 反复重启导致死锁如果设备需要反复重启,很有可能在从机设备返回数据的时候,SDA被锁住。具体原因是从机设备在回数据,还没有发送完成,主机时钟消失,从机等待时钟信号, MCU重启,如果从机设备的电源没有复位,从机继续等待 MCU 时钟信号,数据一直被钳住,总线无法完成数据交互。 解决重启导致总线死锁,一种方式可以如同 rt-thread 驱动解决方式一样,在系统复位的时候,提供9个时钟信号,解初总线死锁;另一种是在按下复位键初始化的时候,给从机设备电源断电重启,这个需要引脚控制。
3.2 多个i2c设备导致死锁在一个i2c总线上挂载多个从机设备,可能有写传感器没有按照标准i2c协议进行设计,在数据总线上,有其从机地址就开始响应,导致SDA被锁。 解决方式,这样的不标准i2c设备,单独使用一个总线,避免干扰,或者单独一个独立引脚,控制电源。
来源于微信公众--- RTThread物联网操作系统
欢迎总结其他的 i2c 坑,作为相关问题的指南
|