由I2C高电平不到VCC,再思考时序要求

文章描述了一个I2C设备在写入数据后读回全0的问题,通过波形分析发现SDA高电平未达VCC,调整上拉电阻无效。进一步排查时序发现设备上电时序不满足规范,解决方法是按照正确的时序控制OE引脚,从而恢复正常通信。这强调了时序在硬件设计中的重要性以及排查问题时的系统性方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1.I2C 写入后马上读出来

2.测量I2C 波形,判断是否异常

3.解析I2C判断写操作输出是否正常

4.排查异常原因

时序思考


最近一个项目遇到一个问题,I2C device 写进去读出来的数据全是0,device 并没有报I2C busy,

测量波形发现,SDA 高电平没有达到VCC,再排查时序发现Device上电时序不满足SPECI要求。

简单做个记录,也方便遇到同类问题的童鞋们参考!

1.I2C 写入后马上读出来

方便判断读写是否成功

如下是打印出的log

write!,0xFF,0x01
 read!,0xFF,0x01
 write!,0x00,0x02
 read!,0x00,0x82
 write!,0xFF,0x00
 read!,0xFF,0x00
 write!,0x09,0x37
 read!,0x09,0x00
 write!,0x0A,0x7B
 read!,0x0A,0x00
 write!,0x0D,0x80
 read!,0x0D,0x00
 write!,0x0C,0x6D
 read!,0x0C,0x00
 write!,0x10,0x00
 read!,0x10,0x00
 write!,0x16,0xF1
 read!,0x16,0x00
 write!,0xFF,0x01
 read!,0xFF,0x00
 write!,0x00,0x02
 read!,0x00,0x00
 write!,0x04,0x80
 read!,0x04,0x00
 write!,0x05,0x00
 read!,0x05,0x00
 write!,0x08,0x00
 read!,0x08,0x00
 write!,0x0D,0x02
 read!,0x0D,0x00
 write!,0x0E,0x03
 read!,0x0E,0x00
 write!,0x01,0x01
 read!,0x01,0x00
 write!,0x02,0x3F
 read!,0x02,0x00
 write!,0x0B,0x33
 read!,0x0B,0x00
 write!,0xA1,0x02
 read!,0xA1,0x00
 write!,0xA4,0x02
 read!,0xA4,0x00
 write!,0x10,0xF0
 read!,0x10,0x00
 write!,0x11,0x30
 read!,0x11,0x00
 write!,0x14,0x00
 read!,0x14,0x00
 write!,0x12,0x03
 read!,0x12,0x00
 write!,0x13,0xFF
 read!,0x13,0x00
 write!,0x13,0x00
 read!,0x13,0x00
 write!,0x30,0xE0
 read!,0x30,0x00
 write!,0x32,0x00
 read!,0x32,0x00
 write!,0x31,0x00
 read!,0x31,0x00
 write!,0x4D,0x08
 read!,0x4D,0x00
 write!,0x4C,0x01
 read!,0x4C,0x00
 write!,0x34,0x01
 read!,0x34,0x00
 write!,0x32,0xF0
 read!,0x32,0x00
 write!,0x32,0x00
 read!,0x32,0x00
 write!,0x33,0xF0
 read!,0x33,0x00
 write!,0xFF,0x00
 read!,0xFF,0x00
 write!,0x0A,0x3B
 read!,0x0A,0x00
 write!,0xFF,0x01
 read!,0xFF,0x00
 ok!

写入后读出来是全0,因此有I2C有一端是工作异常的,但此时Device端并没有报busy,测量波形确实ack bit确实是0;

2.测量I2C 波形,判断是否异常

如下是I2C 波形

ch1 SDA

ch2 SCL 

可以看到VCC正常是3.3V,而SDA只有2.7V,当然从IC VIH=0.7VCC,因此2.7V也是高电平

此处还尝试加大上拉电阻,原来是2.2K,修改为1K,SDA只提高到2.78V,但依然没有解决问题

bit 9 为ack

3.解析I2C判断写操作输出是否正常

如下是其中一个数据的解析 ,可以看到写入过程是正确的

0xBC 设备,写地址 0xA4 写入值0x02

 写入过程正确,因此可能的原因有两个:

1.        Device端有异常,写不进去

2.        Device端读不出来

继续用JTAG debug模式排查,发现在刚上电时SDA也是正常,只有跑程序后SDA才被拉低

 因此可能是device端异常

4.排查异常原因

排查电源正常

排查时序时发现时序不满足要求

 时序要求如下

尝试在如上基础上拉低OE再拉高,再去完成初始化工作

 再次读取初始化信息,发现写入和读出相同了,这说明器件工作正常

write!,0xFF,0x01
 read!,0xFF,0x01
 write!,0x00,0x02
 read!,0x00,0x00
 write!,0xFF,0x00
 read!,0xFF,0x00
 write!,0x09,0x37
 read!,0x09,0x37
 write!,0x0A,0x7B
 read!,0x0A,0x7B
 write!,0x0D,0x80
 read!,0x0D,0x80
 write!,0x0C,0x6D
 read!,0x0C,0x6D
 write!,0x10,0x00
 read!,0x10,0x00
 write!,0x16,0xF1
 read!,0x16,0xF1
 write!,0xFF,0x01
 read!,0xFF,0x01
 write!,0x00,0x02
 read!,0x00,0x02
 write!,0x04,0x80
 read!,0x04,0x80
 write!,0x05,0x00
 read!,0x05,0x00
 write!,0x08,0x00
 read!,0x08,0x00
 write!,0x0D,0x02
 read!,0x0D,0x02
 write!,0x0E,0x03
 read!,0x0E,0x01
 write!,0x01,0x01
 read!,0x01,0x01
 write!,0x02,0x3F
 read!,0x02,0x3F
 write!,0x0B,0x33
 read!,0x0B,0x33
 write!,0xA1,0x02
 read!,0xA1,0x02
 write!,0xA4,0x02
 read!,0xA4,0x02
 write!,0x10,0xF0
 read!,0x10,0xF0
 write!,0x11,0x30
 read!,0x11,0x30
 write!,0x14,0x00
 read!,0x14,0x00
 write!,0x12,0x03
 read!,0x12,0x03
 write!,0x13,0xFF
 read!,0x13,0xFF
 write!,0x13,0x00
 read!,0x13,0x00
 write!,0x30,0xE0
 read!,0x30,0xE0
 write!,0x32,0x00
 read!,0x32,0x00
 write!,0x31,0x00
 read!,0x31,0x00
 write!,0x4D,0x08
 read!,0x4D,0x08
 write!,0x4C,0x01
 read!,0x4C,0x01
 write!,0x34,0x01
 read!,0x34,0x01
 write!,0x32,0xF0
 read!,0x32,0xF0
 write!,0x32,0x00
 read!,0x32,0x00
 write!,0x33,0xF0
 read!,0x33,0xF0
 write!,0xFF,0x00
 read!,0xFF,0x00
 write!,0x0A,0x3B
 read!,0x0A,0x3B
 write!,0xFF,0x01
 read!,0xFF,0x01
 ok!

后面的功能也正常了!

时序思考

那么为什么要满足时序,厂商又是怎么定义时序的呢?

回想我们自己设计的电源电路,前一级工作之后才会输出给到后一级工作,因此为了保持可靠工作必须要前一阶工作稳定后后一级才启动。

如不满足,最常见的两种现象是:

1. 漏电,尤其是IO 漏电到VCC,IO先于VCC上电的通常会发生这样的漏电,回想IO内部结构,有两个反向二极管包含IO,IO电流会通过上面一个二极管流到VCC,这种情况一般在VCC上电后就会消除。

2.内部逻辑异常,再如上的电源思路上,如第一级的电源供电是为了初始化第二级的逻辑电路,而上电时先上电逻辑部分的供电可能会导致此异常

这也会导致意想不到的结果。

如上时序就导致了I2C通信异常,从波形上看SDA信号已经异常,因此IC内部状态已经是异常的,最终导致不能正常读写寄存器。当然如了解IC内部的电路还可以继续从电路的角度分析,如下这篇链接有部分是从CMOS电路角度分析的,可做参考!



https://www.eefocus.com/article/1419502.html

数字IC设计基本概念之时序路径_startpoint与endpoint_artest1995的博客-CSDN博客

后记废话:

此问题单独拎出来看是个很简单问题,可是这颗Device只是整个设计链路中的其中一个小环节,此Device工作异常会导致整个链路异常,但排查时缺要逐条排查,因此排查到I2C这一级已经会花很大精力,而且这个问题最先是从软件的log角度分析下来的,对于代码不熟悉的硬件工程师来说,真的费了很大精力,更神奇的时device 不正常,但ack还是拉低了,因此一开始都不会怀疑到这里(所以device真的没有做ack的动作吗?)。

教训也很深刻,无论之前强调过多少遍要配置时序,出问题了还是先把本领域部分逐条查一遍,以防止低级错误。也给后面排查用排除法带来很多确定性。从0到1的点越多,问题浮出水面的速度就会越快。查问题如此,做项目也是如此。

### I2C信号低电平偏高的原因 I2C信号低电平偏高可能由多种因素引起,主要包括以下几个方面: #### 1. 上拉电阻选择不当 在I2C总线上,上拉电阻是必不可少的组件。如果上拉电阻值选得太小,则可能导致电流过大,在输出设备试图将线路拉低时,仍然会有较高的电压残留,从而使得低电平升高[^3]。 #### 2. 干扰问题 对于某些特殊应用场景下的I2C通信,例如折叠、滑盖手机中的FPC走线情况,当I2C信号线经过转轴或滑轨区域时,这些地方通常具有较长的布线路径并接近天线位置。由于I2C采用的是开漏(Open Drain)结构,这使得它对电磁干扰特别敏感,尤其是来自射频(RF)信号源的影响可能会使原本应该保持稳定的低电平发生波动甚至抬升[^2]。 #### 3. 器件性能差异 不同制造商生产的I2C兼容芯片可能存在内部设计上的细微差别,特别是在驱动能力方面。有些器件或许不能完全有效地把线路拉到理想的逻辑‘0’状态,尤其是在负载较重或多节点连接的情况下,这种现象会更加明显。 #### 影响分析 - **数据传输错误**:不正常的低电平会影响接收端正确识别起始条件、停止条件以及ACK/NACK确认位,进而引发整个通讯过程失败。 - **增加误码率**:即使偶尔能够完成一次成功的读写操作,长期存在的异常也可能累积成更高的误码概率。 - **降低可靠性**:不稳定的工作环境不利于构建可靠的数据交换通道,尤其是一些工业控制领域中对稳定性的严格要求难以得到保障。 ```python # Python伪代码展示如何检测I2C低电平质量 import smbus def check_i2c_low_level(bus_number, address): bus = smbus.SMBus(bus_number) try: data = bus.read_byte(address) # 尝试读取单字节作为测试 # 如果成功则说明基本功能正常,但仍需进一步验证具体的高低电平特性 print("Basic communication works.") except Exception as e: print(f"Error occurred during read operation: {e}") check_i2c_low_level(1, 0x50) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值