2. 逻辑分析仪实战:用 Saleae Logic 抓 I2C/SPI/UART 时序
逻辑分析仪这东西,说白了就是嵌入式工程师的「示波器」——但它不关心电压多高,只关心电平是 0 还是 1。我最早用逻辑分析仪是在一个电机驱动项目里,I2C 总线老是丢数据,示波器看波形累得半死,换了 Saleae 之后,十分钟就定位到是时钟毛刺问题。嗯,从那以后,我的工具包里就再也没缺过它。
2.1 为什么是 Saleae Logic?
市面上逻辑分析仪很多,但 Saleae 系列(特别是 Logic 8 / Logic Pro 16)在嵌入式调试圈子里几乎是标配。原因很简单:
- 软件体验好:跨平台,界面清爽,协议解析插件丰富
- 采样深度够用:24MHz 采样率,对于 I2C(400kHz)、SPI(几十 MHz)、UART(115200bps)绰绰有余
- 触发灵活:支持边沿、电平、协议帧触发,抓异常波形很方便
2.2 连接与基础设置
连接其实很简单。Saleae 的探头是杜邦线,直接夹到目标板子的信号线上就行。但有几个坑,我踩过不止一次:
- 共地必须接:逻辑分析仪的 GND 不接,波形全是乱的。我见过有人折腾半小时,最后发现地线没夹紧。
- 信号线别太长:超过 20cm 的杜邦线在 SPI 高速模式下会引入振铃,波形看起来像有毛刺,其实是反射。
- 通道顺序记清楚:我习惯把 SCL 接 CH0,SDA 接 CH1,这样解析时不用来回对线。
| 总线类型 | 信号线 | 推荐通道 | 采样率建议 |
|---|---|---|---|
| I2C | SCL, SDA | CH0=SCL, CH1=SDA | 4MHz |
| SPI | SCLK, MOSI, MISO, CS | CH0-3 按顺序 | 16-24MHz |
| UART | TX, RX | CH0=TX, CH1=RX | 2MHz(115200bps) |
2.3 I2C 时序抓取与异常分析
I2C 的时序其实很规矩:起始条件、从机地址、读写位、应答、数据、停止条件。但实际项目中,异常往往出在「不规矩」的地方。
2.3.1 正常波形长什么样?
抓一个正常的 I2C 写操作,你会看到:
- SCL 空闲时高电平
- SDA 在 SCL 低电平时变化,高电平时采样
- 起始条件:SCL 高电平时 SDA 从高拉低
- 停止条件:SCL 高电平时 SDA 从低拉高
2.3.2 我遇到过的 I2C 异常波形
案例 1:时钟拉伸导致超时
有一次调试温湿度传感器,读数据时偶尔卡死。用 Saleae 抓波形发现,从机在 ACK 之后把 SCL 拉低了 2ms——这是时钟拉伸。但主控的 I2C 超时设的是 1ms,直接报错了。
案例 2:总线竞争
两个主设备同时发数据,SDA 上出现「中间电平」——既不是 0 也不是 1。逻辑分析仪上看到的是毛刺。解决办法:加总线仲裁或改用多主模式。
2.4 SPI 时序抓取与异常分析
SPI 比 I2C 快,但信号完整性要求更高。我见过太多人 SPI 调不通,最后发现是相位极性配错了。
2.4.1 SPI 的四种模式
| 模式 | CPOL | CPHA | 数据采样边沿 |
|---|---|---|---|
| 模式 0 | 0 | 0 | 上升沿采样 |
| 模式 1 | 0 | 1 | 下降沿采样 |
| 模式 2 | 1 | 0 | 上升沿采样 |
| 模式 3 | 1 | 1 | 下降沿采样 |
抓波形时,先看 SCLK 空闲电平(CPOL),再看数据在哪个边沿变化(CPHA)。我习惯用 Saleae 的 SPI 解析器自动识别,但也会手动对一下第一个字节——确保解析器没选错模式。
2.4.2 常见 SPI 异常
- CS 毛刺:片选信号在传输过程中抖动,导致从机复位。解决办法:CS 加 10kΩ 上拉,软件里加去抖延时。
- MISO 无数据:从机没拉低 CS 或没使能输出。用逻辑分析仪看 CS 拉低后 MISO 是否从高阻变推挽。
- 数据错位:主从机的 MSB/LSB 顺序不一致。抓一个已知数据(如 0x55 或 0xAA)对比一下。
2.5 UART 时序抓取与异常分析
UART 看起来简单——就 TX 和 RX 两根线。但波特率不对、极性反了、停止位少了,都会导致乱码。
2.5.1 用逻辑分析仪测波特率
抓一个 UART 波形,测量最短脉冲的宽度(就是 1 个 bit 的时间),然后算波特率:
波特率 = 1 / 最短脉冲宽度
例如:最短脉冲宽度 = 8.68μs
波特率 = 1 / 0.00000868 ≈ 115200 bps
我习惯在 Saleae 里直接加 UART 解析器,设好波特率,看解析出来的数据对不对。如果全是乱码,先检查波特率偏差——±2% 以内通常没问题,超过 5% 必乱。
2.5.2 我踩过的 UART 坑
坑 1:电平反了
有一次用 3.3V 的 STM32 和 5V 的 GPS 模块通信,RX 波形看起来正常,但数据全是 0xFF。后来发现 GPS 模块是 RS-232 电平(负逻辑),需要加电平转换芯片。
坑 2:波特率漂移
某个项目用内部 RC 振荡器做 UART,低温下波特率偏了 8%,通信时好时坏。用逻辑分析仪抓波形,发现每个字节的停止位宽度明显不对。解决办法:换外部晶振或做波特率自适应。
2.6 异常波形实战案例
下面这个案例来自我去年做的一个智能家居项目。主控通过 I2C 读取光照传感器,偶尔读到 0x00。用 Saleae 抓了 10 分钟波形,发现规律:
- 正常读操作:起始 → 地址+写 → ACK → 寄存器地址 → ACK → 重复起始 → 地址+读 → ACK → 数据 → NACK → 停止
- 异常读操作:起始 → 地址+写 → ACK → 寄存器地址 → 没有重复起始 → 直接发地址+读 → 从机不响应 → 超时
问题出在主控的 I2C 驱动库——在某种中断抢占场景下,重复起始条件没发出来。修复后,再也没出现过 0x00。
2.7 本章知识结构
下面这张图总结了逻辑分析仪调试三种总线的核心流程和常见异常点:
2.8 小结
逻辑分析仪是嵌入式调试的「眼睛」。用好它,你就能看到总线上到底在发生什么——而不是靠猜。我个人建议,每个嵌入式工程师都应该花半天时间,拿 Saleae 把自己手头项目的 I2C、SPI、UART 波形都抓一遍,看看「正常」长什么样。这样以后出问题时,你一眼就能看出哪里不对劲。