ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

I2C总线调试全流程:万用表、示波器与ACK位排查实战

I2C总线调试全流程:万用表、示波器与ACK位排查实战 I2C 总线只有两根线SDA 和 SCL看起来简单得不能再简单但真正在板子上调起来很多人会卡在同一个地方知道要测却不知道从哪一步下手。万用表量了半天电压都正常代码跑起来就是没响应示波器接上去波形也抓到了可到底是哪一帧出了问题、ACK 有没有回来还是说不清楚。这篇内容就是把这套排查流程从头到尾串一遍——从最基础的万用表静态检查到示波器抓波形看时序再到 ACK 位到底怎么判断、NACK 出现后往哪个方向查。不管你是刚接触 I2C 的嵌入式新手还是调过不少板子但每次遇到 I2C 问题还是靠猜的老手这套流程都能直接拿去用。我自己的习惯是I2C 调不通先别急着改代码也别急着换从机芯片。按“静态电气检查 → 动态波形抓取 → 协议层 ACK 判定 → 根因定位”这个顺序走绝大多数问题在十分钟内就能锁定方向。下面按这个顺序展开每一步都讲清楚为什么这么做、具体怎么操作、以及我踩过的那些坑。1. 先搞清楚 I2C 到底在测什么1.1 两根线的电气本质开漏与上拉I2C 的 SDA 和 SCL 都是开漏open-drain结构这意味着器件只能把线拉低不能主动拉高。线要变高靠的是上拉电阻把电平拉上去。这个特性决定了 I2C 的很多现象如果上拉电阻没接、阻值太大、或者总线被某个器件一直拉低你看到的波形就会是“塌”的或者干脆一直是低电平。所以测 I2C 的第一步不是看波形好不好看而是确认这两根线在空闲状态下是不是都被拉到了高电平。空闲时 SDA 和 SCL 都应该是高电平通常是 3.3V 或 1.8V取决于你的系统电平。如果空闲时有一根线是低的那说明有器件在持续拉低总线这时候你抓什么波形都没意义得先把这个问题解决掉。1.2 一次完整传输包含哪些可测点一次典型的 I2C 写操作从主机发出 START 开始到 STOP 结束中间包含这些关键节点START 条件SCL 为高时SDA 从高变低。从机地址 读写位7 位地址加 1 位方向位共 8 位。ACK/NACK 位第 9 个时钟周期从机拉低 SDA 表示 ACK保持高表示 NACK。数据字节每个字节后面同样跟一个 ACK/NACK。STOP 条件SCL 为高时SDA 从低变高。每一个节点都是可以单独测量的。排查的时候你要做的就是判断“信号走到了哪一步、在哪一步断掉了”。这个思路比笼统地说“I2C 不通”要有效得多。1.3 万用表、示波器、逻辑分析仪各自能回答什么问题这三种工具不是互相替代的关系而是各管一段工具能回答的问题局限性万用表空闲电平对不对、上拉有没有、有没有短路/断路看不到动态波形测不了时序示波器波形完整性、上升沿、时钟频率、毛刺、ACK 位电平单次触发抓特定帧需要技巧逻辑分析仪协议解码、地址、数据、ACK/NACK 的协议层判定只看逻辑电平不看模拟特性实际排查中我一般是万用表先做静态检查确认电气基础没问题再上示波器看波形质量最后如果需要看协议内容用逻辑分析仪解码。三者配合效率最高。2. 万用表阶段别小看静态检查2.1 空闲电平测量红黑表笔怎么放把万用表打到直流电压档黑表笔接系统地GND红表笔分别点 SDA 和 SCL 测试点。正常情况SDA 空闲电压 ≈ 上拉电源电压3.3V 系统就是 3.3V 左右SCL 空闲电压 ≈ 上拉电源电压如果测出来是 0V说明这根线被拉低了。常见原因某个从机芯片没供电但 I/O 口通过内部保护二极管把线拉低、上拉电阻虚焊、PCB 走线短路到地。如果测出来是 1.5V 这种“中间值”那更麻烦——说明有多个器件在互相拉扯或者上拉电阻和某个下拉路径形成了分压。这种情况必须查清楚不能凑合。注意测量时确保系统处于空闲状态也就是主机没有在发起传输。如果主机一直在轮询你测到的可能是动态变化的电压万用表读数会跳。2.2 上拉电阻的确认阻值和位置上拉电阻的典型值是 4.7kΩ但这不是死规定。阻值的选择取决于总线电容和通信速率总线电容小、速率低100kHz可以用 10kΩ 甚至更大。总线电容大、速率高400kHz 或 1MHz需要减小阻值比如 2.2kΩ 或 1kΩ。用万用表电阻档断电情况下测 SDA 对 VCC 的电阻应该等于上拉电阻的阻值。如果测出来是无穷大说明上拉没接或者断了。如果测出来远小于预期可能有多个上拉并联或者有短路。我遇到过一个很隐蔽的情况上拉电阻焊在了从机板上但主机板和从机板之间的连接线断了导致主机侧看不到上拉。这种时候在主机侧量 SDA 对 VCC 就是无穷大但问题不在电阻本身而在连接。2.3 短路与断路的快速判断断电用万用表蜂鸣档SDA 对 GND不应该导通。如果导通查短路。SCL 对 GND同上。SDA 对 SCL不应该导通。如果导通两根线短在一起了通信必然失败。SDA/SCL 对 VCC不应该导通除了通过上拉电阻的正常路径。这些检查看起来基础但我见过太多人跳过这一步直接去抓波形结果查了半天发现是 SDA 和 SCL 在 PCB 上短路了。2.4 一个容易被忽略的点地从哪里量万用表的黑表笔接的“地”必须是主机和从机共用的那个参考地。如果主机和从机之间地线没接好或者地线上有较大压差你测出来的电平就是错的。特别是在多板系统中板间连接器的地针如果接触不良I2C 会时好时坏非常难查。我的做法是在主机侧和从机侧分别量 SDA 对各自 GND 的电压如果两个值差很多先查地线连接。3. 示波器阶段波形里藏着真相3.1 探头怎么接、触发怎么设示波器测 I2C至少需要两个通道一个接 SDA一个接 SCL。探头用 10:1 无源探头即可带宽 100MHz 以上足够看 I2CI2C 最高也就几 MHz。触发设置是关键。推荐用 SCL 或 SDA 的下降沿触发触发电平设在 VCC/2 左右。如果你想抓 START 条件可以用 SDA 下降沿触发同时确保 SCL 为高——但大多数示波器不支持这种组合触发所以更实用的做法是用 SCL 下降沿触发然后往前看找到 START。如果示波器有协议触发或解码功能很多中端示波器都有 I2C 解码选件直接开启 I2C 解码设置好地址和数据类型让示波器帮你触发特定帧。这比手动找波形效率高得多。提示探头的地线要尽量短最好用探头自带的弹簧地针不要用长长的鳄鱼夹地线。地线太长会引入振铃让你误以为信号有毛刺。3.2 上升沿太慢说明什么I2C 的上升沿是由上拉电阻和总线电容决定的 RC 充电过程。上升时间大约是 0.3 × R × C 到 0.7 × R × C 之间取决于你定义的阈值。如果上升沿明显变缓可能的原因上拉电阻太大总线电容太大挂的设备太多、走线太长某个器件的 I/O 口漏电流偏大上升沿太慢会导致在高速通信时时钟高电平期间数据还没稳定从机采样出错。标准模式下 I2C 的上升时间要求不超过 1000ns快速模式不超过 300ns。用示波器的光标功能量一下上升时间如果超标就得减小上拉电阻或减少总线负载。3.3 时钟频率和占空比的实测示波器上量 SCL 的周期算出实际频率。比如周期是 10μs那就是 100kHz。然后量高电平时间和低电平时间看占空比是否接近 50%。有些主机的 I2C 控制器占空比偏离较大高电平特别短这可能导致从机来不及响应。我遇到过一颗从机芯片手册要求 SCL 高电平至少 1.3μs但主机配置出来的高电平只有 0.8μs结果就是偶尔能通、偶尔不通。把主机时钟频率降下来之后问题消失。这种问题用万用表永远查不出来只有示波器能看到。3.4 毛刺和振铃什么时候需要在意I2C 的 SDA 在 ACK 位和数据的切换点会有电平变化如果看到明显的振铃或毛刺先判断它是否跨越了逻辑阈值。如果毛刺幅度很小没有越过 VIL/VIH 门限通常不影响通信。但如果毛刺导致误触发那就需要处理缩短走线增加串联端接电阻通常 22Ω 到 100Ω检查是否有其他高速信号串扰不要一看到毛刺就慌先判断它是否影响逻辑电平。4. ACK 位I2C 排查的核心判据4.1 ACK 在波形上长什么样ACK 是第 9 个时钟周期。主机发完 8 位数据后释放 SDA让它被上拉为高从机如果正确接收会在第 9 个 SCL 高电平期间把 SDA 拉低。所以在示波器上ACK 位的波形特征是SCL 第 9 个高电平期间SDA 是低的。如果你看到第 9 个时钟高电平期间 SDA 保持高那就是 NACK。NACK 意味着从机没有响应可能的原因包括地址不对、从机没供电、从机忙、从机损坏。用示波器看 ACK 的时候建议把时基展开让一个字节的时间占据屏幕大部分。这样你能清楚地看到 8 个数据位加 1 个 ACK 位。4.2 地址阶段的 NACK 和数据阶段的 NACK 含义不同这是很多人混淆的地方地址阶段 NACK主机发出地址后没有从机应答。说明总线上没有器件认识这个地址。查地址配置、从机供电、从机复位状态。数据阶段 NACK地址被应答了但后续数据字节被 NACK。说明从机认识地址但拒绝接收数据。常见于从机缓冲区满、寄存器地址非法、写保护生效。区分这两种 NACK能帮你快速缩小排查范围。如果地址阶段就 NACK你根本不用看数据如果地址 ACK 了但数据 NACK问题在从机内部状态或协议层。4.3 用示波器单次触发抓 ACK 的技巧抓 ACK 最实用的方法是示波器设为单次触发Single。触发源设为 SDA 下降沿触发电平设在 VCC/2。时基设为能显示 2 到 3 个字节的时间窗口。让主机发起一次传输。触发后在波形上找到第 9 个时钟看 SDA 电平。如果示波器有 I2C 解码功能直接看解码结果里的 ACK/NACK 标记更快。但要注意解码器有时会把毛刺误判所以关键帧还是要人工核对波形。4.4 时钟拉伸从机拉低 SCL 时你在看什么有些从机在还没准备好数据时会主动拉低 SCL这叫时钟拉伸clock stretching。在示波器上表现为 SCL 的高电平时间被异常拉长。如果你看到 SCL 的高电平比正常周期长很多而且 SDA 在此期间保持稳定那很可能就是从机在做时钟拉伸。时钟拉伸本身不是错误但如果主机不支持时钟拉伸有些硬件 I2C 控制器不支持就会导致通信失败。查一下主机的 I2C 控制器手册确认是否支持时钟拉伸。如果不支持要么换从机要么用软件 I2C。5. 从波形到根因典型故障的排查链路5.1 完全无波形先查使能和供电如果示波器上什么都抓不到SDA 和 SCL 都是直线先查主机 I2C 外设是否使能寄存器配置、时钟门控主机引脚是否配置为 I2C 功能有些芯片需要配置引脚复用从机是否供电上拉电源是否正常我遇到过 STM32 上 I2C 引脚没配置为复用开漏模式结果引脚是推挽输出波形完全不对。这种问题查手册的 GPIO 复用表就能解决。5.2 有 START 无 ACK地址和供电排查能看到 START 条件但地址阶段就 NACK。排查顺序确认从机地址是否正确7 位地址左移一位后的值确认从机供电电压是否在手册范围内确认从机复位引脚是否被正确释放确认从机是否处于低功耗模式有些芯片休眠时不应答 I2C地址问题是最常见的。很多人把 7 位地址和 8 位地址搞混。比如某芯片手册写地址是 0x50这是 7 位地址实际发送时要左移一位变成 0xA0写或 0xA1读。5.3 ACK 正常但数据错时序和寄存器排查地址 ACK 了数据也 ACK 了但读回来的值不对。这时候查寄存器地址是否正确读写方向位是否正确数据字节序大端/小端从机是否需要特定的初始化序列我调过一颗传感器地址和数据都 ACK但读出来的值一直是 0。后来发现是上电后需要等待一段时间才能读手册里写的是 10ms我代码里只等了 1ms。加长等待时间后正常。5.4 偶发失败电源纹波和地弹如果 I2C 大部分时候正常偶尔失败重点查电源和地用示波器看 VCC 上的纹波特别是在 I2C 传输瞬间看 GND 上是否有地弹ground bounce检查是否有其他大电流器件在同一电源轨上电源纹波导致 I2C 偶发失败是很常见的。特别是当从机和电机、继电器等大电流负载共用电源时传输瞬间的电压跌落可能导致从机复位或采样错误。解决办法是给 I2C 从机单独加去耦电容或者用独立的 LDO 供电。6. 工具选型与实战经验杂谈6.1 万用表选型够用就好测 I2C 静态电平普通数字万用表完全够用。不需要高精度不需要真有效值。关键是表笔要细能点到细间距的测试点。我用的是带细尖表笔的便携表点 0.5mm 间距的引脚没问题。如果要测上拉电阻阻值万用表的电阻档精度也不需要太高5% 误差完全可接受。上拉电阻本身通常就是 5% 或 1% 精度的。6.2 示波器带宽和通道数是关键测 I2C示波器的最低要求是带宽100MHz 以上I2C 信号本身频率不高但要看上升沿和毛刺带宽要够通道数至少 2 通道SDA SCL存储深度越大越好方便抓长帧触发功能最好有协议触发或至少边沿触发如果预算有限国产入门级示波器如 Rigol、Siglent 的入门型号完全能胜任 I2C 调试。不需要追求高端品牌。关键是会用而不是设备多贵。6.3 逻辑分析仪协议解码的利器逻辑分析仪在 I2C 调试中的价值在于协议解码。它能把波形直接翻译成地址、数据、ACK/NACK省去人工数时钟的时间。入门级的 8 通道逻辑分析仪配合开源软件就能很好地解码 I2C。但逻辑分析仪只看逻辑电平不看模拟特性。所以它不能替代示波器。我的流程是示波器确认波形质量逻辑分析仪确认协议内容。两者配合效率最高。6.4 几个让我印象深刻的踩坑经历坑一上拉电阻焊错位置。有一次从机模块自带 10kΩ 上拉主机板上也焊了 4.7kΩ 上拉两个并联后等效约 3.2kΩ。低速时没问题高速时上升沿反而变得太陡导致过冲和振铃。后来去掉主机侧上拉只用从机侧的问题解决。上拉电阻不是越多越好并联后阻值变小可能引入新的信号完整性问题。坑二地址搞错一位。一颗 EEPROM 的 7 位地址是 0x50我在代码里写的是 0xA0。看起来 0xA0 是 0x50 左移一位应该对啊。但实际上我用的驱动库要求传入 7 位地址库内部会自己左移。结果就是左移了两次地址变成了 0x40当然 NACK。这种问题查手册的 API 说明就能避免。坑三时钟拉伸导致偶发失败。一颗传感器在转换期间会拉低 SCL 做时钟拉伸但主机的硬件 I2C 控制器不支持时钟拉伸导致偶尔读不到数据。换成软件 I2C 后正常。这个坑的教训是选主机 I2C 控制器时一定要确认它支持从机的所有特性包括时钟拉伸。坑四地线没接好。两块板子之间用排线连接I2C 时好时坏。查了半天发现排线里的地线针接触不良。重新压接后正常。I2C 对地线质量很敏感因为 SDA 和 SCL 的电平都是相对于地的。6.5 一套可复用的排查清单把上面的流程整理成一张清单下次遇到 I2C 问题可以直接照着走万用表量 SDA、SCL 空闲电平确认都是高。万用表量上拉电阻确认阻值合理。万用表查 SDA/SCL 对地、对 VCC、相互之间是否短路。示波器接 SDA、SCL设下降沿触发抓一次传输。看 START 条件是否正常。看地址阶段第 9 个时钟 SDA 是否被拉低ACK。如果地址 NACK查地址、供电、复位。如果地址 ACK 但数据 NACK查寄存器地址、从机状态。如果数据都 ACK 但值不对查时序、字节序、初始化。如果偶发失败查电源纹波、地弹、时钟拉伸。这套清单覆盖了我遇到过的绝大多数 I2C 问题。剩下的那些疑难杂症通常需要结合具体芯片手册和 PCB 布局来查但大方向不会跑出这个框架。调 I2C 这件事工具是辅助思路才是核心。知道每一步在测什么、为什么测、测出来异常意味着什么比拥有多贵的示波器都重要。我见过用入门示波器十分钟定位问题的老手也见过用高端设备查了一下午还没找到方向的新手。差别就在于是不是有一套清晰的排查链路。上面这套流程你可以在下次遇到 I2C 问题时直接套用也可以根据自己的习惯调整顺序。关键是别跳步别猜让每一级工具回答它该回答的问题。
返回列表