☰
从万用表到示波器:I2C调试的完整排查链路与ACK位深度解析
2026/11/6 4:45:58 网站建设 项目流程

搞嵌入式的,恐怕没人敢说自己从没被 I2C 卡过。屏、触摸、EEPROM、温湿度传感器、电源管理芯片,十块板子里八块都有 I2C。可不少朋友排查问题的方式,还是一支万用表走天下:量量有没有电压,测测通不通,什么都正常,就是通信不成功。其实 I2C 信号测量是有明确套路的,万用表解决静态问题,示波器解决动态问题和时序问题,最后再落在 ACK 位这个“到底有没有人回应我”的关键信息上。这篇就把这条完整链路拆开,从工具选择一直聊到 NACK 排查,给你一套能直接对着操作的流程。

1. I2C 调试前的必修课:先把协议和工具底牌搞清楚

1.1 I2C 到底在传输什么信号(SCL、SDA、时序、ACK)

I2C 是两线制串行总线,SCL 是时钟线,SDA 是数据线。所有器件都通过开漏输出方式接入,这意味着任何一个节点都只能主动把线拉到 GND,而不能主动驱动到高电平,高电平完全靠外部上拉电阻维持。因此总线的电平是“拉低”与“释放”的组合,这个物理特性决定了你在示波器上看到的波形,总是从高往下掉,而不是像 SPI 那样被强驱动的高电平和低电平。

通信过程可以拆成几个关键事件。起始条件(Start)是 SCL 为高时 SDA 发生高到低跳变;停止条件(Stop)是 SCL 为高时 SDA 发生低到高跳变。中间传输的每个字节都是高位在前,先传 8 个数据位,再传第 9 个时钟脉冲作为应答位。如果从机在第 9 个时钟内把 SDA 拉低,表示 ACK;如果 SDA 保持高,就是 NACK。写操作时,地址字节由 7 位从机地址加一个写位(0)组成;读操作时,地址字节由 7 位地址加一个读位(1)组成。所以你在示波器上看到的第一帧“地址字节 + ACK/NACK”,就能直接看出从机是否识别你。

我为什么要把这些协议细节重新说一遍?因为很多人在量 I2C 时根本不知道看什么。光看到 SDA 有高低变化是不够的,你要学会在时间轴上把每个 SCL 高电平区间对应的 SDA 电平读出来,然后再看第 9 个时钟的 SDA 状态。这是后面所有排查的基础,也是理解“万用表能干什么、不能干什么”的前提。

1.2 三种测量工具的分工:万用表、逻辑分析仪、示波器怎么选

我见过很多新手一上来就抓示波器,结果无从下手。工具选择应该按“信号特点”来决定。万用表擅长测静态参数,能告诉你电源对不对、上拉电阻是否在位、总线有没有被拉死,但看不到时序,也看不到 ACK。逻辑分析仪是目前性价比最高的协议分析工具,几十块钱的也能解码 I2C,直接把地址、数据、ACK 列出来,缺点是不擅长反映模拟特性,比如边沿缓不缓、幅度够不够。示波器则是最终的“裁决者”,它既能看到数字逻辑,也能看到模拟波形,但操作门槛比前两者高。

我的建议是:手里没有逻辑分析仪时,直接用示波器也能解决 90% 的 I2C 问题。如果你做的是产品研发,建议示波器加逻辑分析仪搭配使用。日常快速验证功能用逻辑分析仪,定位疑难杂症拿示波器查电气特性。这篇文章接下来会以“先万用表、再示波器、最后 ACK”为线索展开,正好对应从静态到动态、从电气到协议的全过程。这么一套走下来,你以后遇到 I2C 问题就不会再乱猜了。

2. 万用表在 I2C 排障里的正确打开方式:不是量通断那么简单

2.1 万用表能测的项目和具体操作方法

先说最常用的几个测量项目,每个都有对应的操作细节。

供电电压:将万用表调到直流电压档,红表笔接板子上的 VCC 测试点,黑表笔接 GND。如果 I2C 上拉电阻是接在 3.3V 或 5V 上,一定要确认这一路电源正常。很多时候从机没响应,根源就是上拉电源被分压或断开。我遇到过不少板子,逻辑分析仪抓不到波形,最后发现是 LDO 输出虚焊,VCC 只有 1.2V,整个总线电平都不满足器件要求。

上拉电阻阻值:断电,用电阻档测量 SCL 和 SDA 各自的上拉电阻。一般取值在 2.2kΩ 到 10kΩ 之间,具体和总线电容、通信速率相关。如果量出来是几十千欧甚至兆欧,说明上拉缺失或虚焊。这一点在低功耗板子里特别常见,有些设计把上拉电阻放在传感器模组内部,外部不可见,但照样要确认阻值合适。

总线静态电平:上电后不通信,用电压档量 SCL、SDA 对地电压。正常时两根线都应该是接近 VCC 的电平,因为开漏器件全都处于释放状态,由上位电阻拉高。如果某根线电压只有零点几伏,说明有器件把它拉死了,或是板上有短路。如果测得的是电源电压的一半左右,更要小心,可能是总线被外部电路分压。

二极管压降:用二极管档,红表笔接 GND,黑表笔接 SCL 或 SDA,测量引脚对 GND 的正向压降。常见值是 0.4V 到 0.7V。如果完全测不到,说明芯片引脚和总线走线之间可能断线。这个检查在排除“焊盘虚焊导致从机根本没接到总线上”时非常有用。

短路排查:用蜂鸣档量 SCL 与 SDA 之间,正常应该不通。注意有些芯片内部会有保护二极管造成蜂鸣短响,最好在断电状态下确认一次。如果持续导通,就要查 PCB 上是不是有锡连或走线过孔短路。

这里有个万用表的坑,一定要提醒:很多总线引脚内部有 ESD 保护二极管到电源和地,所以蜂鸣档量 SCL 对 GND 时可能会瞬间响一下,这不是真短路。要区分“电容充放电导致的响声”和“持续导通”。如果蜂鸣档持续响,才说明有异常。另外,测上拉电阻时最好断开芯片供电,否则芯片引脚内部路径会影响读数,测出来的阻值会明显偏小。

2.2 万用表的边界:为什么静态电压正常,通信还是失败

这是很多人栽跟头的地方。万用表测出来 SCL、SDA 都是 3.3V,上拉电阻也正常,但设备就是通信失败。原因很简单:万用表的采样速率很低,只能显示电压的平均值或有效值,对几十 kHz 到几百 kHz 的跳变波形只会给出一个“平均电平”一般的模糊读数。你根本看不到 SCL 脉冲是否畸变,看不到 SDA 在第 9 个时钟是不是被从机成功拉低,也看不到起始条件和停止条件是否完整。

我举个例子:如果 SDA 在每个字节后都应该被从机拉低产生 ACK,但实际从机没应答,SDA 一直保持高电平。用万用表量,依然是接近 VCC 的电压,和正常情况毫无区别。可工作就是不正常。这种情况只有动用示波器,把时序展开看,才能发现真正的问题。

所以我常说,万用表只能告诉你“有没有电、有没有断”,不能告诉你“信号走没走对”。当静态测量全部正常而通信仍然失败时,请立刻转移战场,上示波器。这里没有捷径,也别指望拿万用表的频率档去量总线频率,那种测量对边沿畸变和协议错误几乎无能为力。

3. 示波器抓 I2C 波形:接线、设置与协议解码全流程

3.1 测量前的准备:探头补偿、接线位置、带宽要求

示波器测量 I2C,第一件事不是开机就接,而是确认探头状态。I2C 是低速总线,但它的边沿可能很陡,如果探头没做补偿,测出来的上升沿会明显失真,甚至影响对 ACK 的判断。具体操作是:把探头接到示波器自带的 1kHz 方波校准输出,观察方波顶角。如果看到尖角或圆角,就用小螺丝刀调整探头上的微调电容,把波形修成平直。这个步骤看似基础,但很多波形测量不准的问题都出在它身上。

接线时,我建议把示波器通道 1 接 SCL,通道 2 接 SDA,探头地线要尽量短,最好直接在板子的 GND 测试点上,不要用超长飞线夹远端地,否则会串入噪声。测量点尽量选在靠近目标芯片的引脚或串联电阻处,避免测长走线末端的反射区域。测试夹要夹牢,I2C 信号幅度一般不高(常见 3.3V 或 1.8V),如果探头夹子松了,波形会乱跳,让你误判成信号质量问题。

带宽方面,I2C 标准模式 100kbps、快速模式 400kbps 都是低速,100MHz 模拟带宽的示波器足够。如果目标是快速模式加 1MHz 或更高,建议选择 200MHz 以上的示波器。因为开漏信号的上沿由电阻和总线电容决定,通常有几十 ns 量级,100MHz 带宽可以很好还原。如果你只有 20MHz 的老示波器,也能抓出协议帧,但上升沿测量值会偏慢,且可能在频率较高时显示成圆弧顶波形,这一点心里有数就行。

3.2 示波器触发与时基设置:保证能稳定抓到一帧完整数据

接下来是设置步骤,按顺序操作,基本一次就能抓到:

  1. 先按 Auto 让示波器看到两条通道的波形,确认两个探头都接到了正确的信号上。
  2. 把触发模式从 Auto 切到 Normal 或 Single,触发源选通道 2(SDA),触发方式选下降沿。原因很简单:I2C 的起始条件是 SDA 在 SCL 高电平期间发生下降沿,用它当触发可以保证每次抓到的都是一帧通信的开始。如果用 SCL 触发,很容易抓到传输中间,反而不利于判断起始和应答。
  3. 触发电平设置在信号幅度的中间附近,比如 3.3V 系统设 1.5~1.7V。如果信号有噪声干扰,可以稍调高一点阈值,避免误触发。
  4. 时基设置要看通信速率。以 100kbps 为例,一个位周期是 10μs,一个字节含 ACK 约 9×10μs = 90μs,如果只想看地址帧和 ACK,设 50μs/div 到 100μs/div 比较合适;想看连续几个字节的读写序列,设 200μs/div 到 500μs/div。400kbps 则相应快 4 倍,设 20μs/div 左右。
  5. 水平位置可以放在左边,让触发点靠左,从而看到触发后的完整数据。如果使用 Single 单次触发,就能把一次完整传输抓下来,停止在屏幕上慢慢分析。

如果示波器自动设置后看到波形在屏幕上乱跳,多半是触发源选错,或触发电平过高过低。还可以利用示波器的时间测量功能,直接测 SCL 的周期和频率,确认实际速率是否和预期一致。很多疑难问题,比如从机在 400k 下不稳定,但 100k 正常,可以通过对比不同速率下的波形找出原因。我在实际调试中会先跑一个循环通信的例程,让示波器不停触发,再逐步缩小触发条件,这样比一次一次按 Single 要舒服得多。

3.3 开启协议解码:直接从波形里读出地址和 ACK(常用按键/菜单)

现在的示波器,哪怕是入门级的国产型号,很多都带 I2C 协议解码功能。进入“解码”或“总线”菜单,选择 I2C,然后指定 SCL 为通道 1,SDA 为通道 2。关键参数是设置阈值电压,一般设为 VCC 的一半左右,示波器会据此把模拟电压转换成 0/1 逻辑电平。接着设置 I2C 速率或者让示波器自动识别。开启解码后,屏幕上方会直接显示类似“地址:0x3C 写,ACK”这样的信息。这个功能能帮你快速确认地址字节是否被正确响应,省去手动数时钟的麻烦。

如果没有解码功能,也有笨办法:把波形展开,先找起始条件,然后从第一个 SCL 上升沿开始,每 8 个时钟读一次 SDA 高低,再在下一个时钟的高电平区间看 SDA 是低还是高。用一张总线和 SDA 的关系草图画一下,很快就能数出“写地址 0x?? + 是否 ACK”。这个方法其实很适合学习,能让你真正理解协议时序,而不是被解码功能“黑盒化”。

解码结果只是辅助,最终判断还是要落到波形本身。比如解码显示 ACK,但 SDA 的低电平深度不够,只有零点几伏的正向残留,其实是上拉电阻和从机驱动能力不匹配造成的“弱 ACK”,这时只靠解码是看不出来的。这是我反复强调示波器比逻辑分析仪多一层价值的地方。解码功能能告诉你协议层的答案,但电气层的真相还得看模拟波形。

4. ACK 位深度排查:从波形看从机到底有没有“听见”

4.1 ACK 在波形上长什么样:从第九个时钟看 SDA 状态

ACK 是 I2C 通信里最容易被忽略又最关键的一个位置。主设备发出一个字节后,在第 9 个时钟脉冲会释放 SDA,然后从设备如果正常收到并准备继续,就会把 SDA 拉低;如果从设备不想响应,就会让 SDA 保持高电平,这就是 NACK。

在示波器上看,关键在于“第 9 个时钟的高电平期间”SDA 电平。正常 ACK 的波形是:在第 8 个时钟下降沿之后,SDA 被释放,然后迅速被上拉拉高;到第 9 个时钟上升沿附近,SDA 被从机拉低,并且在整个第 9 个时钟高电平期间保持低;第 9 个时钟下降沿后,SDA 再被释放。如果你看到第 9 个时钟高电平时 SDA 一直是高,那就是 NACK。有些示波器带光标测量,可以把光标放在第 9 个时钟的中间,直接读取 SDA 电压值,低于 VIL(输入低门限)就是 ACK,高于 VIH 就是 NACK。

需要注意,ACK 槽出现的位置因通信方向而异。主机写从机时,地址字节后和数据字节后的 ACK 都由从机发出;主机读从机时,地址字节后的 ACK 由从机发出,之后主机接收到数据字节后,由主机发出 ACK 或 NACK 来表示是否还要继续读。所以在波形上看到第 9 个时钟 SDA 状态高或低,要先搞清楚这个字节是谁发的,再判断是谁在应答。这一条很多人会搞反,我就见过有人把主机发出的 NACK 当成从机故障,排查了半天,其实主机是故意终止读操作而已。

4.2 NACK 出现的常见原因和对应排查路线

NACK 可以出现在两个位置,排查方向完全不同。

第一个位置是地址字节后的 NACK。遇到这种情况,优先怀疑“从机地址匹配失败”。检查是否把 7 位地址和 8 位写地址搞混了,比如很多器件手册给的是 7 位地址 0x3C,实际地址字节应该是 0x3C << 1 | 0 = 0x78。还要确认从机地址引脚配置,比如 A0/A1/A2 电平均是否正确。接着检查从机是否正常上电、复位脚是否被拉死,很多传感器在复位期间不会应答。最后用 I2C 扫描程序把所有地址扫一遍,看看设备实际响应在什么地址。这一步可以很快帮你确认“是地址不对,还是器件压根没起来”。

第二个位置是数据字节后的 NACK。这通常意味着从机已经正确响应地址,但不接受你当前发送的数据。常见原因有四类:一是器件忙,比如 EEPROM 在写周期内不会应答;二是寄存器地址不存在或处于只读状态;三是写保护引脚生效,拒绝写入;四是主机发送的数据长度和从机期望的不一致。排查时先读数据手册,确认操作序列和寄存器映射,再抓一次完整波形,看在哪个字节之后出现 NACK,就能定位到具体是哪一环节的问题。

除了从机原因,主机端也有坑。如果主机没有在第 9 个时钟前释放 SDA,或者释放时间太短,从机根本拉不下去,示波器上看起来也是“类似 NACK”的波形。这种假 NACK 要特别注意,排查方法是在 ACK 槽前看 SDA 有没有一段由高到低的过程。如果是从机拉低的,会有明确的下降沿;如果是主机驱动残留,可能只是电平浮动。把这个问题识别出来,往往能省下大量怀疑从机的时间。

4.3 总线冲突和时钟拉伸:容易被误判成 ACK 问题的两个坑

总线冲突是 I2C 排查里最隐蔽的问题之一。理论上同一时刻总线上只能有一个从机响应一个地址,但如果地址配置引脚焊错,或多个器件使用了相同的 7 位地址,就可能出现冲突。用示波器看,你会发现在 ACK 槽附近 SDA 出现异常的“半高”或毛刺。这是因为两个从机一个拉低、一个释放,或者两个都在拉低,导致信号不是标准低电平,而是被下拉互相牵制的奇怪电平。遇到这种波形,就要检查总线上所有设备的地址和使能引脚,必要时拆掉其中一个器件再测。

时钟拉伸则是从机主动控制速度的一种机制。部分从机需要更多时间准备数据,会把 SCL 拉低,主机检测到后进行等待。示波器上表现为 SCL 低电平时间明显拉长,但波形本身没有毛刺。这时候如果你不了解这个特性,可能误以为 SCL 卡死或信号异常。解决办法是查看从机数据手册,确认是否支持时钟拉伸,并调整示波器时基,把整个拉伸过程完整捕获。

要区分这两个坑,我的建议是同时观察 SDA 和 SCL 两条通道的波形。总线冲突通常出现在 SDA 上,有电平异常;时钟拉伸通常出现在 SCL 上,有占空比异常。如果两者都正常,但通信依然失败,再往电气参数和上拉电阻方向查。很多时候,示波器上的异常波形本身就足够告诉你问题方向,不要只盯着协议解码结果。

5. 我踩过的 I2C 测量坑与排查速查表(实战总结)

5.1 几个真实案例(边沿太缓、波形台阶、假ACK)

案例一:某项目用 400kbps 快速模式,现象是偶尔读写失败。上示波器一看,SCL 的上升沿明显呈圆弧状,花了近 300ns 才从低拉到高。原因是上拉电阻用了 10kΩ,而总线上挂了三四个器件,总线电容偏大,上升沿时间常数太大,在 400k 下已经逼近时钟周期的四分之一,导致器件采样错误。换成 4.7kΩ 后,边沿明显变直,故障消失。这个案例说明,静态测上拉电阻只是第一步,动态波形才能看到边沿质量。

案例二:某板子 I2C 扫描不到设备,万用表量 SDA 静态电压只有 0.2V。起初以为是芯片坏了,后来仔细查发现是 SDA 线上有个器件一直把总线拉低。用示波器观察,SDA 一直是一条近地直线,SCL 却正常。逐个断开可疑器件,最后定位到一颗电源芯片处于故障锁存状态,强制把 SDA 拉低。这个案例给我的教训是,万用表能发现异常但没有方向,配合示波器才能看到“没波形”也是一种关键波形。

案例三:地址字节后偶尔 NACK,但重新初始化又好了。后来抓波形发现是主机代码在发送地址字节后,没有在 ACK 槽释放 SDA,而是继续驱动低电平,看起来像 ACK,实际是主机把线位住了。改掉 GPIO 模式配置后,NACK 彻底消失。这类问题光看解码结果很难发现,因为解码可能把它当作正常 ACK,只有看波形上 ACK 槽前的电平变化才能判断是不是从机真正拉的。

5.2 排查流程速查表(从无波形到通信正常)

我把平时排查 I2C 的顺序整理成一张表,遇到问题可以按表格走一遍,能省不少时间。

现象首要工具重点检查处理建议
完全没有波形,SCL/SDA 都无变化万用表/示波器供电、复位、上拉电阻、主机是否在跑先确认为主供电和复位,再确认主机程序有 I2C 活动
只有 SCL 有波形,SDA 一直是高示波器/万用表从机是否上电,地址是否正确用地址扫描确认从机地址,确认从机型号
只有 SCL 有波形,SDA 一直低万用表是否某器件把 SDA 拉死,短路断电后测量 SDA 对地阻值,逐个断开器件
SDA 有波形但地址字节后 NACK示波器解码从机地址、器件供电、复位、地址配置检查 7 位/8 位地址,检查地址引脚,用扫描程序
数据字节后 NACK示波器+数据手册寄存器地址、时序、写保护、命令格式对比寄存器手册,测量第 9 个时钟
边沿缓或波形畸形示波器上拉电阻、总线电容、探头接地降低上拉电阻,减小总线负载,缩短走线
速率高时不稳,速率低时正常示波器上拉电阻、布线电容、从机时序按目标速率选择合适上拉,必要时降低速率

这张表不能完全覆盖所有情况,但能把 80% 的 I2C 问题引导到正确的排查方向。实际执行时要注意顺序:先查静态再查动态,先查主机再查从机,先查电源再查信号。顺着这个逻辑走,比随机换电阻、改代码要有条理得多。我自己验证过很多次,按照这个顺序,大多数问题能在半小时内定位。

5.3 实用建议再补一刀:测量顺序和示波器自动测量的坑

最后补充几个我在实操中总结出来的小建议。

第一,测量顺序很重要。拿到一块新板子,我习惯先量电源和上拉,再跑一个最简单的 I2C 扫描程序,如果扫描正常再读写寄存器。这个顺序能快速把问题范围从“电气问题”缩小到“协议问题”。千万不要一上来就上示波器乱抓,否则看到的波形都不知道是谁发出来的。主线一定是“先确认设备在总线上,再确认协议对,最后查信号质量”。

第二,示波器的自动挡不一定可靠。很多示波器在 Auto 模式下会把触发电平、时基改得乱七八糟,尤其是对于 I2C 这种突发性信号。建议一上来就手动设置触发源、触发方式和时基,不要依赖 Auto。如果示波器有“自动设置”,可以先按一下,再手动修正,但最终要以手动画面为准。否则你看到的可能是一屏乱跳的波形,连起始条件都找不准。

第三,测上升时间时要对带宽有数。示波器带宽不达标时,上升沿会被磨圆,测出来的上升时间偏大。例如 100k 信号在 20M 带宽示波器上可能显示 100ns 的上升沿,实际可能只有 50ns。这种误差会影响对上拉电阻是否合适的判断,所以如果要测精确边沿,最好选 100MHz 以上带宽,或者在判断时留出余量。别为了省事用低带宽示波器去硬测边沿,那样只会得到误导数据。

最后分享一个我自己的习惯:每次新板子回来,我会先写一个最简单的 I2C 扫描例程,把总线上的设备地址都扫一遍,如果扫描正常再跑读写,如果扫描不到再去上示波器。这样做不是为了省事,而是用一个稳定的参考结果把问题范围快速缩小。实际用下来,这个顺序比一上来就拿示波器乱戳要高效得多。I2C 调试没有玄学,先把工具用对,再把波形拆开,答案通常就在那几根线上。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询