ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

I2C通信故障排查全攻略:从万用表到逻辑分析仪的完整链路

I2C通信故障排查全攻略:从万用表到逻辑分析仪的完整链路 1. 为什么I2C排查值得单独写一篇I2C这玩意儿说简单是真简单两根线一挂上拉电阻一焊代码里调个库函数就能读写。但说难也是真难多少人卡在“设备没反应”这四个字上一卡就是一整天。我见过太多人一上来就怀疑芯片坏了、代码写错了结果折腾半天发现是上拉电阻没焊或者地址左移了一位。I2C排查的核心难点在于它是一条共享总线任何一个环节出问题表现都是一样的——没反应。主机发不出去、从机不应答、电平被拉死、时序不满足最终你看到的都是同一个现象。这就导致排查必须系统化不能靠猜。这篇内容我打算把I2C从“怀疑有问题”到“定位到具体原因”的完整排查链路讲清楚。涉及的工具从最便宜的万用表到示波器、逻辑分析仪覆盖的环节从硬件电平到协议时序再到ACK应答。适合刚接触I2C的嵌入式新手也适合调了几年但排查思路还比较零散的老手。读完你至少能做到拿到一块不通信的板子知道先测什么、再测什么、每一步的预期结果是什么、不符合预期时往哪个方向查。2. 排查前的准备工作与基础认知2.1 I2C总线的物理层本质I2C的物理层就两根线SCL和SDA。这两根线都是开漏输出结构什么意思呢就是每个挂载在总线上的设备只能把线拉低不能主动拉高。线要变高靠的是上拉电阻把电平拽上去。这个结构决定了几个关键特性。第一总线上任何设备拉低整条线就是低电平所以I2C天然支持多主多从。第二上拉电阻的值直接影响信号上升沿的陡峭程度阻值太大上升沿变缓高速通信时数据还没到高电平就被采样了直接出错。第三如果某个设备把线一直拉低不放整条总线就死了这就是所谓的“总线锁死”。理解这三点后面的排查才有方向。很多问题归根结底就是这三个特性的某个环节出了偏差。2.2 常见I2C速率与上拉电阻的对应关系上拉电阻不是随便选的它和通信速率、总线电容直接相关。总线电容包括PCB走线电容、器件引脚电容、连接线电容一般估算在100pF到400pF之间。上升时间公式是tr ≈ 0.847 × R × C标准模式100kHz时上升时间要求小于1000ns快速模式400kHz时要求小于300ns快速模式1MHz时要求小于120ns。按这个算100kHz下如果总线电容200pF上拉电阻最大约5.9kΩ400kHz下同样电容最大约1.77kΩ。所以常见的4.7kΩ适合100kHz2.2kΩ到1kΩ适合400kHz。很多人从标准模式切到快速模式后通信不稳定第一件事就该检查上拉电阻是不是太大了。通信模式速率典型上拉电阻上升时间要求标准模式100kHz4.7kΩ1000ns快速模式400kHz2.2kΩ300ns快速模式1MHz1kΩ120ns高速模式3.4MHz特殊驱动不适用2.3 排查工具的选择逻辑万用表、示波器、逻辑分析仪这三个工具在I2C排查中扮演不同角色不是替代关系。万用表看的是静态电平适合确认上拉电阻有没有焊、线有没有断、电平范围对不对。它看不到动态波形但胜在便宜、随手就有。示波器看的是模拟波形质量能测上升沿时间、电平幅度、有没有毛刺、时钟频率对不对。排查信号完整性问题必须用示波器。逻辑分析仪看的是协议解码能把SCL和SDA上的电平变化翻译成地址、数据、ACK/NACK。排查协议层问题效率最高。我的建议是先用万用表做静态检查排除低级错误再用示波器看波形质量最后用逻辑分析仪解协议。这个顺序从便宜到贵、从简单到复杂能避免一上来就上高端工具却查了个寂寞。3. 万用表静态排查先排除最蠢的问题3.1 上拉电阻与供电电压测量拿到一块不通信的板子第一步永远是断电测电阻、上电测电压。断电状态下用万用表电阻档测SCL和SDA对VCC的阻值。如果读数是无穷大说明上拉电阻没焊或者虚焊。如果读数是0说明有短路。正常应该读到上拉电阻的标称值比如4.7kΩ。同时测SCL对GND、SDA对GND的阻值排除线间短路。上电状态下用直流电压档测SCL和SDA的静态电平。总线空闲时两根线都应该是高电平接近VCC。如果测到0V或者中间某个奇怪的值说明有设备在拉低总线或者上拉电阻没起作用。这里有个细节有些设备在未初始化时会拉住总线所以最好在主机还没开始通信的时候测。如果主机已经在跑I2C了空闲时刻可能很短万用表采样跟不上读数会跳。注意万用表测电压时输入阻抗一般是10MΩ对I2C总线影响很小但如果你用的是老式指针万用表比如MF50输入阻抗低接上去可能直接把总线拉低测出来全是错的。用数字万用表。3.2 用万用表判断总线是否被拉死总线锁死是I2C最常见的故障之一。现象是SCL或SDA一直停在低电平主机发什么从机都没反应。判断方法很简单上电后不运行任何I2C通信代码用万用表测SCL和SDA电压。如果某根线是0V而VCC正常、上拉电阻正常那就是有设备在拉低。进一步定位逐个断开从机设备每断开一个测一次。断开哪个之后线恢复高电平问题就出在那个设备上。如果所有从机都断了还是低那可能是主机引脚配置错了比如GPIO模式设成了推挽输出低。还有一种情况是某个从机在上电过程中进入了异常状态把SDA拉低不放。这时候可以尝试给从机单独断电重启或者在SCL上手动发几个时钟脉冲有些设备在收到时钟后会释放SDA。3.3 万用表排查的局限性与常见误判万用表只能看静态值这是它最大的局限。我遇到过好几次万用表测SCL和SDA都是正常的高电平上拉电阻也正常但通信就是不通。后来用示波器一看上升沿慢得像蜗牛爬400kHz下根本来不及到高电平就被采样了。另一个常见误判是测到了“中间电平”。比如VCC是3.3V但SCL测出来是1.8V。这可能是两个设备一个在拉低一个在拉高形成了分压。这种情况在推挽输出误接到I2C总线时特别常见。I2C要求开漏如果某个设备的引脚配置成了推挽输出高就会和另一个拉低的设备打架测出来就是中间值。所以万用表排查的结论只能是“静态没问题”不能得出“I2C没问题”的结论。动态问题必须上示波器。4. 示波器动态波形分析看信号质量4.1 示波器探头连接与触发设置用示波器测I2C至少需要两个通道一个接SCL一个接SDA。探头要用10倍衰减档减少对总线的负载。接地夹要就近接GND引线越短越好否则测出来的波形全是振铃。触发设置是关键。I2C通信是突发的不是持续信号所以要用边沿触发。触发源选SCL触发方式选下降沿触发电平设在VCC的一半左右。这样每次SCL下降沿都会触发一次捕获你就能看到完整的通信过程。如果信号很稀疏可以用单次触发模式然后让主机发一次读写示波器就能抓到那一帧。如果信号密集用正常触发模式调整触发电平到合适位置。时基设置要看通信速率。100kHz时一个时钟周期10微秒建议时基设成10微秒到20微秒每格一屏能看几个字节。400kHz时时基设成2微秒到5微秒每格。4.2 上升沿时间与电平幅度测量抓到波形后第一眼看上升沿。把示波器光标打开测SCL从10%VCC到90%VCC的时间。100kHz下应该小于1000ns400kHz下小于300ns。如果超了通信速率就得降或者换小阻值上拉电阻。第二眼看电平幅度。高电平应该接近VCC低电平应该接近0V。如果高电平只有2.0V而VCC是3.3V说明上拉电阻太大或者总线电容太大上升沿还没到顶就被拉下来了。如果低电平有0.5V而不是0V说明有设备拉低能力不足可能是引脚驱动能力不够或者线阻太大。第三眼看有没有过冲和振铃。如果上升沿顶部有尖峰说明阻抗不匹配可能是走线太长或者探头接地不好。轻微的过冲一般不影响通信但如果过冲超过VCC太多可能触发从机的保护电路。4.3 时钟频率与占空比验证示波器还能测实际时钟频率。把时基调到能看一个完整时钟周期用光标测相邻两个下降沿之间的时间取倒数就是频率。如果主机配置的是400kHz但实测只有350kHz可能是时钟源精度不够或者分频系数算错了。占空比也要看。I2C规范要求高电平和低电平时间都至少1.3微秒标准模式或0.6微秒快速模式。如果低电平特别短可能是主机驱动能力太强或者上拉太弱导致高电平时间被压缩。我遇到过一种情况主机配置的时钟是400kHz但示波器测出来高电平只有0.3微秒低电平有2.2微秒。原因是上拉电阻太大SCL被拉低后释放上升沿太慢还没到高电平主机就又开始拉低了。这种波形逻辑分析仪可能还能解码但实际从机已经采样错误了。4.4 用示波器判断ACK位的实际电平ACK位是I2C通信的关键。主机发完8位数据后释放SDA从机如果收到就把SDA拉低这就是ACK。示波器上看到的是第9个时钟周期SDA在SCL高电平期间是低电平。用示波器看ACK有个技巧把SDA通道的触发电平设在VCC的30%左右触发方式选下降沿触发源选SCL。这样每次SDA下降沿都会触发你就能快速定位到ACK位。如果第9个时钟SDA没有下降沿说明从机没应答。但示波器看ACK有个坑如果从机拉低SDA的时间很短或者上升沿很慢示波器可能显示一个斜坡而不是明确的低电平。这时候要结合逻辑分析仪确认。5. 逻辑分析仪协议解码定位到具体字节5.1 逻辑分析仪与示波器的分工示波器看的是“信号长什么样”逻辑分析仪看的是“信号说了什么”。逻辑分析仪只关心高还是低不关心具体电压值所以它能直接解码出地址、数据、ACK/NACK。用逻辑分析仪排查I2C效率比示波器高一个数量级。你不需要手动数时钟、对数据软件直接告诉你起始条件、地址0x50、写操作、ACK、寄存器地址0x00、ACK、数据0xAB、ACK、停止条件。哪一步不对一目了然。但逻辑分析仪看不到信号质量问题。如果上升沿太慢导致逻辑分析仪都采错了那说明信号已经差到一定程度了得回去用示波器查硬件。5.2 解码设置与常见解码错误逻辑分析仪的I2C解码设置一般包括SCL通道、SDA通道、地址位数7位或8位、字节序MSB或LSB。地址位数设错是最常见的解码错误。很多逻辑分析仪默认7位地址但有些设备手册给的是8位地址包含读写位直接填进去就会解出错误的地址。比如一个设备手册写“设备地址0xA0”这是8位写法实际7位地址是0x50。逻辑分析仪如果设成7位你输入0xA0它就会去找0xA0这个7位地址当然找不到。正确做法是把0xA0右移一位得到0x50填进逻辑分析仪的地址过滤里。另一个常见问题是采样率不够。逻辑分析仪采样率至少要是通信速率的10倍以上。400kHz的I2C采样率至少4MHz建议8MHz以上。采样率不够会漏掉窄脉冲解码结果时对时错。5.3 从解码结果定位问题环节逻辑分析仪解出一帧数据后按这个顺序看第一有没有起始条件。如果没有说明主机根本没发起通信问题在主机端。第二地址字节对不对。如果地址错了说明主机代码里的设备地址写错了或者地址移位方向搞反了。第三地址后面有没有ACK。如果地址正确但没有ACK说明从机没响应。可能原因从机没供电、从机地址不匹配、从机坏了、总线上有另一个设备占用了同一地址。第四寄存器地址有没有ACK。如果地址有ACK但寄存器地址没ACK说明从机接收到了自己的地址但不认识这个寄存器地址。查手册确认寄存器地址范围。第五数据字节有没有ACK。如果前面都有ACK但数据没ACK说明从机在接收数据时出了问题可能是从机缓冲区满了或者内部状态不对。第六有没有停止条件。如果没有停止条件说明主机在通信中途卡死了可能是等待ACK超时。5.4 用逻辑分析仪抓取偶发故障偶发故障是最难查的。通信大部分时候正常偶尔出错。逻辑分析仪可以用流模式或者长时间捕获来抓。设置触发条件为“地址不匹配”或者“NACK”让逻辑分析仪一直跑等到出错时自动停止。然后看出错前后的波形对比正常帧和异常帧的区别。我遇到过一种偶发故障每通信几百次就出错一次。逻辑分析仪抓到后发现出错的那一帧SCL上多了一个窄脉冲导致从机多移了一位。后来查出来是旁边一个PWM信号串扰到了SCL走线上。这种问题示波器都不一定抓得到逻辑分析仪的长时间捕获帮了大忙。6. ACK/NACK深度解析与排查6.1 ACK的电气本质与采样时刻ACK不是一个独立的信号它是第9个时钟周期SDA的状态。主机发完8位数据后在第9个时钟周期释放SDA输出高阻从机如果正确接收就把SDA拉低。主机在第9个时钟的高电平期间采样SDA读到低就是ACK读到高就是NACK。这里的关键是采样时刻。I2C规范要求数据在SCL低电平期间变化在SCL高电平期间保持稳定。所以ACK的采样点是在第9个时钟的高电平中间。如果从机拉低SDA的时间太晚或者主机采样太早都会误判。用示波器看ACK时要把时基放大到能看清第9个时钟的高电平期间SDA的状态。如果SDA在这个窗口内是低就是ACK如果是高就是NACK。6.2 主机收不到ACK的六大原因从机没供电或者供电电压不对。这是最蠢但最常见的原因。用万用表测从机VCC引脚确认在手册规定范围内。从机地址不匹配。7位地址和8位地址搞混或者地址引脚接错。查手册确认地址用逻辑分析仪看主机发的地址和从机期望的是否一致。从机复位状态不对。有些从机需要先发特定命令才能进入I2C通信模式或者需要等待上电复位完成。查手册确认上电时序。总线电容太大导致上升沿太慢。从机还没看到高电平主机已经开始采样了。用示波器测上升沿时间必要时减小上拉电阻。总线上有另一个设备拉低了SDA。某个设备故障把SDA拉死所有通信都失败。逐个断开从机排查。从机坏了。如果以上都排除了换一个同型号从机试试。6.3 从机收不到主机数据的排查有时候主机发了数据逻辑分析仪也解出来了但从机就是没反应。这种情况要从从机侧查。先确认从机的I2C引脚配置对不对。有些MCU的I2C引脚需要配置成开漏模式如果配成了推挽从机可能无法正确拉低SDA。再确认从机的中断和DMA有没有正确配置。如果从机用中断接收但中断优先级太低被其他中断抢占可能错过数据。还要确认从机的时钟延展功能。有些从机处理慢会拉低SCL来暂停主机。如果主机不支持时钟延展就会出错。用示波器看SCL有没有被从机拉低的时段。6.4 手动ACK与时钟延展的配合有些场景下需要手动控制ACK比如用GPIO模拟I2C。这时候ACK的时序就完全靠软件控制容易出问题。手动ACK的关键是在第8个时钟下降沿之后、第9个时钟上升沿之前把SDA切换为输入模式释放总线然后等第9个时钟上升沿读SDA电平再在第9个时钟下降沿之后把SDA切回输出模式。如果切换太早SDA还没被从机拉低你就读了读到高误判为NACK。如果切换太晚从机拉低SDA的时候你的GPIO还在输出高两边打架可能损坏引脚。时钟延展是另一个坑。从机拉低SCL表示“我还没准备好”主机必须等SCL释放后才能继续。如果主机用硬件I2C一般自动处理时钟延展。如果用软件模拟必须检测SCL是否被从机拉低等待释放。7. 典型故障场景与排查速查表7.1 上电后完全无通信现象主机发什么逻辑分析仪都抓不到起始条件或者抓到了但没有任何ACK。排查顺序万用表测SCL和SDA静态电平确认都是高。如果某根线是低逐个断开从机找拉低源。如果都是高用示波器看主机发通信时SCL有没有动。SCL不动说明主机代码没跑起来或者I2C外设没使能。SCL动了但SDA不动说明主机在等ACK超时。7.2 通信时好时坏现象有时候能读到数据有时候读不到。排查顺序示波器测上升沿时间确认在规范范围内。逻辑分析仪长时间捕获抓出错帧对比正常帧。检查电源纹波用示波器AC耦合测VCC纹波太大可能导致从机复位。检查总线走线有没有和高速信号平行走串扰可能导致偶发错误。7.3 能读不能写现象读操作正常写操作从机不响应。排查顺序确认写操作的地址和读操作地址是否一致读写位不同。确认从机的写保护引脚有没有被拉高。查手册确认写操作是否需要先解锁或者发特定命令。逻辑分析仪看写操作的寄存器地址和数据有没有被ACK。7.4 多设备总线冲突现象单个设备测试正常挂上多个设备后通信失败。排查顺序确认所有设备的地址不冲突。用逻辑分析仪看主机发的地址确认每次通信的目标地址正确。检查总线上拉电阻是否只焊了一组多组上拉并联会导致阻值过小。检查总线电容是否超标设备越多电容越大上升沿越慢。故障现象优先排查工具关键检查点常见原因完全无通信万用表SCL/SDA静态电平上拉缺失、总线拉死无ACK逻辑分析仪地址字节和ACK位地址错误、从机未供电时好时坏示波器上升沿时间、电源纹波上拉过大、串扰能读不能写逻辑分析仪写操作地址和数据写保护、地址混淆多设备冲突逻辑分析仪每次通信的目标地址地址冲突、上拉过小8. 几个容易踩的坑和实操心得第一个坑用万用表测I2C时忘了切档。电阻档测电压或者电压档测电阻读数完全没意义。养成习惯测之前看一眼档位。第二个坑示波器探头的地线夹太长。地线夹的引线电感会和探头电容形成谐振测出来的波形全是振铃。尽量用短的接地弹簧或者把地线夹就近夹在被测点旁边的GND上。第三个坑逻辑分析仪的采样率设太低。400kHz的I2C用1MHz采样率解码结果基本不可信。采样率至少是通信速率的10倍建议20倍以上。第四个坑忽略从机的上电时间。有些从机上电后需要几十毫秒才能响应I2C主机上电就发通信从机还没准备好当然没ACK。在主机初始化后加个延时或者循环重试直到收到ACK。第五个坑地址左移右移搞混。7位地址0x50写成8位是0xA0左移一位加读写位。有些库函数要7位地址有些要8位地址搞混了就是找不到设备。我的习惯是统一用7位地址在发送时再拼读写位。第六个坑总线上拉电阻焊了两组。一块板子上主机侧焊了4.7kΩ从机模块上又自带了4.7kΩ并联后变成2.35kΩ。100kHz下可能还能用400kHz下上升沿太快反而可能引起过冲。挂多个模块时要注意上拉电阻的总阻值。第七个坑用GPIO模拟I2C时忘了设开漏。推挽输出高电平时如果从机拉低SDA两个引脚直接对电源短路电流可能烧毁引脚。模拟I2C的SDA和SCL必须配置成开漏模式或者至少在输出高时切换成输入模式。第八个坑逻辑分析仪解码设置里的地址过滤。有些逻辑分析仪可以设置只解码特定地址的帧如果设错了过滤条件会以为总线上没有通信。排查时先把过滤关掉看所有帧。9. 从排查流程反推设计建议排查多了就会发现很多I2C问题在硬件设计阶段就能避免。上拉电阻的位置尽量靠近主机不要放在从机模块上。这样主机侧的上升沿最陡从机侧的信号质量也不会太差。SCL和SDA走线尽量短不要跨分割地平面。如果必须跨在跨接处加缝合电容。总线上的设备数量不要太多一般不超过8个。设备越多电容越大上升沿越慢。如果必须挂很多设备考虑用I2C多路复用器分叉。预留测试点。SCL和SDA上各留一个测试焊盘方便示波器和逻辑分析仪探头连接。没有测试点的时候用探头勾住引脚很容易短路。电源设计要留余量。I2C从机的电源纹波太大会导致内部逻辑误动作表现就是偶发通信失败。LDO的输出电容不要省该加就加。软件上I2C初始化后先做一次扫描确认所有预期设备都能应答。扫描不到的设备直接报错不要等到读写数据时才失败。读写操作加超时和重试单次失败不要紧重试三次还失败再报错。我个人在实际操作中的体会是I2C排查最忌讳的就是“我觉得”。我觉得上拉没问题、我觉得地址没错、我觉得从机是好的。每一个“我觉得”都要用工具验证。万用表验证静态、示波器验证波形、逻辑分析仪验证协议三个工具各司其职按顺序走一遍90%的问题都能定位到具体环节。剩下10%的偶发问题靠长时间捕获和对比分析也能揪出来。
返回列表