新闻详情

新闻详情

首页 / 资讯中心 / 详情

I2C通信排查实战:万用表、示波器与i2cdetect分层定位指南

发布时间:2026/9/28 19:49:33来源:尧图网络
I2C通信排查实战:万用表、示波器与i2cdetect分层定位指南
1. 从一根不亮的 OLED 说起I2C 排查到底难在哪I2C 总线只有两根线SDA 和 SCL看起来比 SPI、UART 都简单但真正在项目里调起来它反而是最容易让人抓狂的一种。我见过太多人板子焊好、代码烧进去屏幕就是不亮然后开始怀疑人生是地址错了是上拉电阻没焊是时序不对还是从机根本没响应更麻烦的是I2C 是双向开漏总线主机发完一个字节之后要释放 SDA 去读从机的 ACK这个释放再采样的动作用普通万用表几乎看不出来用示波器又容易因为触发设置不对而抓不到关键帧。所以这篇东西我想把 I2C 从怀疑它坏了到确认它到底哪一步坏了的完整排查链路讲清楚。核心工具就三样万用表、示波器、以及 Linux 下的i2cdetect这类软件工具。目标读者是嵌入式软件工程师、硬件调试人员、以及刚接触 I2C 协议、手里拿着逻辑分析仪却不知道怎么下手的同学。不管你是调 SSD1306 OLED、GT911 触摸屏、BH1750 光照传感器还是读写 EEPROM这套流程都能套用。我先把结论摆在这I2C 排查的本质是分层定位。电气层电压、上拉、短路用万用表协议层起始、地址、ACK、数据用示波器或逻辑分析仪软件层地址扫描、驱动加载用 i2cdetect 和内核日志。三层从下往上排哪一层出问题就在哪一层解决不要一上来就改代码。下面我按这个思路一层一层拆。2. 先搞懂 I2C 的电气本质再谈测量2.1 为什么 I2C 必须用开漏加外部上拉很多人测 I2C 时第一个困惑是为什么空闲时 SDA 和 SCL 都是高电平这跟 I2C 的电气结构直接相关。I2C 的每个引脚都是开漏Open-Drain输出器件只能把线拉低不能主动拉高。线要变高靠的是外部上拉电阻把线拽回 VCC。这就好比一根绳子所有人都只能往下拽没人能往上推那要让它回到上面就得在顶端挂一根弹簧——这个弹簧就是上拉电阻。这个结构带来两个直接后果。第一总线上任何一个器件把线拉低整条线就是低这就是 I2C 支持多主多从、还能做时钟同步和仲裁的物理基础。第二上拉电阻的阻值直接决定上升沿的陡峭程度。阻值太大上升沿变缓高速通信时波形还没爬到高电平阈值就被下一个时钟拉低了通信直接失败阻值太小灌电流过大器件可能扛不住。常见取值是 4.7kΩ快速模式400kHz下有时用 2.2kΩ 甚至 1.5kΩ具体要看总线电容。提示如果你测到 SDA 或 SCL 空闲时不是稳定的高电平而是中间某个电压比如 1.8V 而不是 3.3V八成是上拉电阻没焊、焊错阻值或者总线上有器件把线半拉着。这种情况万用表一测就露馅。2.2 万用表能测什么不能测什么万用表在 I2C 排查里的定位很明确它测静态不测动态。具体来说它能干这几件事测 SDA、SCL 对地的直流电压判断空闲电平是否正常应该是接近 VCC测上拉电阻的实际阻值确认有没有虚焊、错件测 SDA 和 SCL 之间、以及各自对 VCC/GND 之间有没有短路断电测通断确认走线有没有断。但它测不了 ACK。原因很简单ACK 是主机发完 8 个数据位后从机在第 9 个时钟周期把 SDA 拉低的一个短暂动作持续时间可能只有几个微秒甚至更短。万用表的采样率根本跟不上你看到的永远是平均值或者跳动。所以凡是涉及从机到底有没有应答的问题万用表直接出局必须上示波器或逻辑分析仪。我自己的习惯是拿到一块新板子先不上电用万用表蜂鸣档把 SDA、SCL 对 VCC、对 GND 都量一遍确认没有短路再量上拉电阻阻值然后上电量空闲电压。这三步做完电气层的低级问题基本就排除了能省掉后面一大堆瞎折腾。2.3 上电前的静态检查清单我把上电前的检查整理成一张表照着做就行检查项工具正常表现异常含义SDA/SCL 对 GND 通断万用表蜂鸣档不通或高阻短路查焊接SDA/SCL 对 VCC 通断万用表蜂鸣档不通短路查焊接上拉电阻阻值万用表电阻档标称值附近虚焊/错件空闲电平万用表电压档接近 VCC上拉缺失或器件拉死器件供电万用表电压档标称电压供电异常这张表看着简单但我踩过的坑里至少三成的问题在第一步就能发现。有一次一块板子 SCL 死活不动最后发现是上拉电阻焊成了 0Ω等于把 SCL 直接短到 VCC从机根本拉不动。万用表一量就出来了可惜当时我直接上示波器折腾了半小时。3. 示波器抓 I2C触发设置才是成败关键3.1 为什么很多人抓不到完整的 I2C 帧用示波器测 I2C最常见的失败不是探头接错而是触发没设对。I2C 是突发通信主机想发就发如果你用自动触发或者边沿触发随便设一个屏幕上要么是一堆乱七八糟的毛刺要么波形一直在跑根本稳不住。正确的做法是用协议触发或者脉宽/欠幅触发去锁定起始条件。起始条件Start的定义是SCL 保持高电平时SDA 从高变低。这是 I2C 一帧数据的开头也是最好的触发点。如果你的示波器支持 I2C 协议解码现在很多中端示波器都带比如鼎阳、普源的部分型号直接开协议触发设成Start或者Address触发一抓一个准。如果示波器不支持协议触发就用 SDA 的下降沿触发同时把 SCL 也接上靠双通道看时序关系。注意测 I2C 一定要用两个通道CH1 接 SCLCH2 接 SDA别只接一根。只接 SDA 你根本分不清哪段是数据、哪段是 ACK因为 ACK 也是 SDA 上的电平变化没有 SCL 做参照就是天书。3.2 探头接法和地线处理探头接法这块很多人忽略一个细节地线要短。示波器探头那根鳄鱼夹地线如果拉得很长会形成一个天线环路测高速信号时引入大量振铃和噪声本来干净的 I2C 波形看起来像被狗啃过。正确做法是用探头自带的弹簧地针直接怼在器件 GND 引脚附近地线环路越小越好。另外探头要设在10X 档不要用 1X。1X 档输入电容大会加重总线负载本来上升沿就缓再被探头电容一拖波形更难看。10X 档输入电容小对总线影响小代价是信号幅度衰减 10 倍示波器里记得把探头倍率设成 10X 补偿回来。3.3 从波形上读出起始、地址、ACK抓到波形之后怎么读我按一帧典型写操作的顺序说起始条件SCL 高SDA 下降沿。这是帧头。7 位地址 读写位紧接着起始条件主机在 SCL 的每个时钟周期送一位共 8 位。前 7 位是从机地址第 8 位是 R/W 位0 写1 读。ACK/NACK第 9 个时钟周期主机释放 SDA从机如果在线且地址匹配就把 SDA 拉低这就是 ACK。如果从机没反应SDA 保持高就是 NACK。数据字节 ACK之后每 8 位数据后面跟一个 ACK直到停止条件。判断 ACK 的关键就是看第 9 个 SCL 高电平期间SDA 是不是被拉低了。如果 SDA 在这段时间一直是高说明从机没应答。这一步用示波器看非常直观但前提是你得把时基调对让一个字节的宽度占屏幕合适比例。一般 100kHz 的 I2C一个时钟周期 10μs一个字节加 ACK 是 9 个周期 90μs时基设成 20μs/div 左右比较舒服。3.4 用双通道测量判断谁在拉低有时候你会看到 SDA 一直是低分不清是主机在发数据还是从机把线拉死了。这时候双通道配合就有用了看 SCL 有没有在动。如果 SCL 完全不动、SDA 恒低很可能是某个从机把 SDA 拉死了比如器件上电异常、地址冲突、或者器件损坏。如果 SCL 在动、SDA 跟着 SCL 有规律变化那就是正常通信只是你可能没触发对。还有一种情况SDA 和 SCL 都被拉低总线彻底死锁。这通常发生在主机复位时从机还在传输中途从机占着 SDA 不放。解决办法是主机发 9 个时钟脉冲把从机状态机走完让它释放总线。这个技巧在调 GT911 这类触摸芯片时特别有用它们偶尔会卡在传输中途。4. 软件层排查i2cdetect 和内核日志怎么用4.1 i2cdetect 扫不到设备先别急着骂驱动在 Linux 平台上i2cdetect是排查 I2C 的第一把刀。用法很简单i2cdetect -l # 列出所有 I2C 总线 i2cdetect -y 1 # 扫描 1 号总线上的所有地址正常的话你会看到一张表从机地址位置显示对应的十六进制地址。如果全是--说明总线上一个设备都没应答。这时候很多人第一反应是驱动没加载其实更可能是电气问题或者地址问题。排查顺序应该是确认总线号对不对i2cdetect -l看名字确认设备供电正常万用表量确认上拉电阻在万用表量确认设备地址查数据手册注意 7 位地址和 8 位地址的区别最后才怀疑驱动。提示i2cdetect默认只扫 0x03 到 0x77 这段地址。有些设备的地址在这个范围之外或者被内核驱动占用了显示成UU这时候要加参数或者先卸载驱动再扫。4.2 地址的 7 位与 8 位之争这是 I2C 新手最容易栽的坑。数据手册上写的地址有的是 7 位有的是 8 位把读写位也算进去了。比如一个器件手册写地址 0x50这是 7 位地址如果写 0xA0那其实是 8 位写法右移一位才是 7 位地址 0x50。i2cdetect显示的是 7 位地址所以如果你拿 8 位地址去对永远对不上。我一般这么记7 位地址左移一位最低位补 0 是写补 1 是读。比如 SSD1306 的 7 位地址是 0x3C写操作就是 0x78读操作就是 0x79。示波器上抓到的地址字节如果是 0x78那对应的 7 位地址就是 0x3C。这个换算在对照波形和代码时特别重要。4.3 内核日志里的 I2C 线索Linux 下dmesg是排查 I2C 的另一个宝库。设备树里配了 I2C 设备但驱动没起来dmesg里通常会有线索dmesg | grep -i i2c dmesg | grep -i 0x3c常见的报错有i2c i2c-1: sendbytes: NAK bailout从机没应答、timeout waiting for bus ready总线被占死、probe failed驱动探测失败。看到 NAK就往电气和地址方向查看到 timeout就往总线死锁方向查。这些日志比盲目改代码有用得多。5. 完整排查流程从现象到根因5.1 一张流程图式的排查顺序我把整个排查过程整理成一条线遇到问题按这个顺序走基本不会绕远路现象确认设备完全不工作还是偶尔工作完全不动优先查电气偶尔出错优先查时序和干扰。静态检查万用表量短路、上拉、供电、空闲电平。软件扫描i2cdetect 扫地址确认从机是否应答。波形抓取示波器抓起始、地址、ACK确认协议层是否正常。根因定位根据前面三步的结果锁定是电气、协议还是软件问题。这个顺序的核心逻辑是从便宜到贵、从简单到复杂。万用表两分钟能做的事不要一上来就架示波器i2cdetect 一条命令能确认的事不要先去改驱动。5.2 典型故障对照表现象可能原因排查工具解决方向i2cdetect 全--供电/上拉/地址错万用表 i2cdetect查电气和地址有地址但读写失败时序/速率不匹配示波器降速或查时序波形上升沿很缓上拉阻值过大示波器减小上拉SDA 恒低从机拉死/短路万用表 示波器查器件/发时钟脉冲ACK 缺失地址错/从机异常示波器核对地址和器件偶发 NAK干扰/总线电容大示波器缩短走线/减小上拉5.3 几个我踩过的真实坑第一个坑上拉电阻接到了错误的电源域。有一次板子上 I2C 器件是 1.8V 供电但上拉电阻接到了 3.3V结果空闲电平是 3.3V超过了从机 IO 的耐压从机直接不响应。万用表一量空闲电平 3.3V而器件供电是 1.8V问题立刻暴露。所以量空闲电平时一定要跟器件供电电压对比不能只看是不是高。第二个坑总线电容过大导致上升沿太缓。一块板子上挂了 6 个 I2C 器件走线又长用 4.7kΩ 上拉时400kHz 下波形上升沿爬不到阈值通信时好时坏。后来把上拉改成 2.2kΩ问题解决。这个用示波器看上升时间一目了然万用表完全看不出来。第三个坑地址冲突。两个器件地址一样i2cdetect 能扫到地址但读写数据总是错乱。这种情况示波器上能看到 ACK 是有的但数据内容不对。解决办法是查每个器件的数据手册确认地址引脚配置必要时改硬件地址。6. 进阶逻辑分析仪和协议解码的配合6.1 逻辑分析仪和示波器怎么分工示波器看的是模拟波形能看出上升沿、过冲、噪声这些电气细节逻辑分析仪看的是数字电平能直接解码出地址、数据、ACK适合看协议层。两者不是替代关系而是互补。我的习惯是电气问题用示波器协议问题用逻辑分析仪。如果只有示波器那就开协议解码功能现在很多示波器都带。逻辑分析仪接 I2C 时采样率要足够高。100kHz 的 I2C采样率至少 1MHz 以上才能准确还原一般设 4MHz 或 10MHz 比较稳。采样深度要够否则一帧还没抓完就满了。触发条件设成 SDA 下降沿起始条件或者直接设地址触发。6.2 协议解码结果怎么读逻辑分析仪解码出来的结果通常长这样Start Address: 0x3C (Write) ACK Data: 0x00 ACK Data: 0xAE ACK Stop读这个结果重点看三处地址对不对、ACK 有没有、数据是不是你期望的。如果地址后面跟的是 NACK说明从机没应答如果 ACK 都有但数据不对说明时序或者寄存器配置有问题。这个解码结果比示波器上数格子直观太多强烈建议有条件就上一个。6.3 自由数据模式下的观察技巧有些 I2C 器件支持自由数据模式或者连续读主机发一次地址后连续读多个字节。这种模式下示波器上会看到一长串时钟中间没有停止条件。观察这种波形时重点看每个字节后的 ACK 是否连续以及最后一个字节主机是否回 NACK表示读够了要停止。如果中间某个 ACK 丢了说明从机在那一拍出了问题可能是内部缓冲满了或者时序跟不上。7. 一些容易被忽略的细节7.1 时钟拉伸Clock StretchingI2C 允许从机把 SCL 拉低来拖住主机这叫时钟拉伸。从机处理不过来时就会这么干。示波器上表现为 SCL 高电平时间被拉长。如果你的主机不支持时钟拉伸或者超时设置太短就会误判为通信失败。排查时如果看到 SCL 高电平异常长先别怀疑主机看看是不是从机在拉伸时钟。7.2 上电顺序和复位有些 I2C 器件对上下电顺序敏感主机先上电、从机后上电可能导致从机在初始化时把总线拉死。解决办法是确保从机先上电稳定或者主机在初始化前先发几个时钟脉冲清总线。这个细节在数据手册里经常一笔带过但实际调试中很要命。7.3 长走线和干扰I2C 走线长了容易受干扰尤其是和开关电源、电机驱动这些噪声源靠近时。示波器上会看到波形上有毛刺严重时毛刺被误判成时钟边沿导致多读或少读数据。解决办法是缩短走线、远离噪声源、必要时加屏蔽或者用 I2C 缓冲器/多路复用器。测纹波和噪声时示波器探头要用弹簧地针别用长地线否则测到的噪声里有一半是探头自己引入的。8. 我个人在实际操作中的体会调 I2C 这么多年我最大的体会是别急着改代码先看波形。代码逻辑再对电气层不对照样不通反过来电气层对了代码问题反而好定位。万用表、示波器、i2cdetect 这三样工具对应电气、协议、软件三层按顺序用绝大多数问题都能在半小时内定位。还有一点记录每次测量的结果。我习惯在调试笔记里记下每次量的电压、抓的波形、i2cdetect 的输出这样问题复现或者换人接手时不用从头再来。I2C 这种总线问题往往藏在细节里今天量到的 1.8V 空闲电平可能就是明天定位问题的关键线索。最后分享一个小技巧如果手头没有逻辑分析仪又需要快速确认 ACK可以用示波器的单次触发触发条件设成 SDA 下降沿时基设成 50μs/div抓一帧完整的写操作然后放大看第 9 个时钟。这个土办法我用了很多年虽然不如协议解码直观但足够判断从机有没有应答。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

SD-WAN弱网测试指南:六大指标与双链路模拟实战 2026/9/28 20:36:03

SD-WAN弱网测试指南:六大指标与双链路模拟实战

1. 弱网测试到底在测什么:先搞懂这六个指标做SD-WAN弱网测试,不是拉两条网线、丢几个包、看个延迟就完事了。我见过太多人上来就问“用什么工具测”,结果链路参数都没设计明白,测出来的数据自己都不信,更别说拿给客户看…

阅读更多 →
UWE5621DS WiFi驱动移植实战:SDIO中断与固件加载排坑指南 2026/9/28 20:36:03

UWE5621DS WiFi驱动移植实战:SDIO中断与固件加载排坑指南

干了这些年嵌入式Linux平台移植,我对“WiFi驱动而起不来”这件事深有体会:最让人头秃的往往不是驱动代码本身,而是内核、SDIO总线和固件三者之间的配合。最近在一个ARM平台项目里移植UWE5621DS WiFi驱动,前前后后折腾了两个多星期…

阅读更多 →
AI工程化落地:代码评审、智能体底座与去AI味实践 2026/9/28 20:36:03

AI工程化落地:代码评审、智能体底座与去AI味实践

2026年第38周的GitHub周刊,我拖到今天才整理完。这期不打算罗列一堆涨星仓库,只挑了几件我觉得值得长期跟的事:阿里把代码评审工具开源了,有人做了个ADHD友好输出方向的写作辅助项目,智能体运行底座ECC进入可以自己动手…

阅读更多 →
GSD 命令表面清理实战:如何彻底消除「Unknown command」陈日斜杠路由残留 2026/9/28 20:35:57

GSD 命令表面清理实战:如何彻底消除「Unknown command」陈日斜杠路由残留

【免费下载链接】gsd-core Git. Ship. Done - Core 项目地址: https://gitcode.com/gh_mirrors/ge/gsd-core 点击查看 免费下载 本文以 gsd-core 仓库中的 changeset 归档记录(scrub-stale-command-routes.md,PR #3029)为骨架&am…

阅读更多 →
OpenCart 4 邮件设置完全指南:Mail 引擎与 SMTP 协议配置、通知告警与投递性优化 2026/9/28 20:35:57

OpenCart 4 邮件设置完全指南:Mail 引擎与 SMTP 协议配置、通知告警与投递性优化

电商后端 【免费下载链接】opencart A free shopping cart system. OpenCart is an open source PHP-based online e-commerce solution. 项目地址: https://gitcode.com/gh_mirrors/op/opencart 点击查看 免费下载 本文以 OpenCart 4 后台 System → Settings → …

阅读更多 →
windows(剪切板测试程序)(原生api) 2026/9/28 20:35:57

windows(剪切板测试程序)(原生api)

剪贴板测试程序 // clipboard_test.cpp // 编译(MSVC): // cl /EHsc /utf-8 clipboard_test.cpp user32.lib // 编译(MinGW): // g -stdc17 -municode clipboard_test.cpp -o clipboard_test.exe -lus…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉