OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5214|回复: 0

手把手带你趟过 i2c 的坑--问题总结与解决方式

[复制链接]

10

主题

59

帖子

0

精华

初级会员

Rank: 2

积分
191
金钱
191
注册时间
2018-7-23
在线时间
23 小时
发表于 2019-6-28 10:37:30 | 显示全部楼层 |阅读模式
本帖最后由 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 设备电气特性,大致下图所示
clip_image001.png
file://E:/document/i2c_solve_method/figures/clip_image001.png?lastModify=1561689369
通常这块内容在 i2c 设备电气特性这一块,主要讲解电平拉高拉低的最长时间、最短时间,以及处于高电平与电平的持续时间。
一般硬件设计,为了降低单片机的功耗与保护芯片引脚在单片机,上拉电阻一般建议常用阻值为4.7k。如果同一个总线上挂载多个 i2c 设备, 即使在 I/O 口配置正确的前提下,也会导致驱动能力不足,导致图2所示的问题
clip_image003.png
file://E:/document/i2c_solve_method/figures/clip_image003.png?lastModify=1561689369
图中两个问题通常还引起数据线与时钟线:拉高时,高电压持续时间过短;拉低时,低电压持续时间过短。用示波器抓取图形,从波形上看,显示是尖波、斜波、杂波等不符合 i2c 设备电气特性的波形;从数据上看,数据线高电平持续时间过小 ,上升沿时间过长 ,下降沿时间过长等等数据超出设备电气特性的有效值。
如果出现此类异常,建议更换小一点的电阻,但不应小于1kΩ(避免芯片引脚烧坏),用来增强总线驱动能力,提高电平转换速度。

3 SDA 死锁
如果i2c 设备的数据偶尔能够正确获取,但是仍然会在总线发送数据或者命令的时候,爆出总线读写错误,那么有可能遇到下面的死锁问题,死锁时候,就是数据线被拉低,主机无法拉高。死锁一般发生在从机上,且为数据线死锁。因为i2c总线是共享的,如果需要确定,是否是从机死锁,可以参照下面两幅图,串联电阻进行测试
clip_image005.png
file://E:/document/i2c_solve_method/figures/clip_image005.png?lastModify=1561689369
如上图所示,如果从机死锁,那么就是从机拉低电平,此时检测到的电压为 Vcc*(5/(10+5))。
clip_image007.png
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 坑,作为相关问题的指南
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 18:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表