4. 硬件排查第二步:总线时序分析与示波器抓波
上一节我们把电源和时钟搞定了,板子能跑起来了。但存储器读写还是出错,怎么办?
这时候,就该请出我们的老朋友——示波器了。我个人习惯把时序分析叫做“用眼睛看信号在跑”。你写再好的代码,如果时序对不上,存储器就是不理你。
4.1 时序分析到底在看什么?
说白了,就是看控制信号和数据信号之间的“时间配合”。单片机跟存储器通信,就像两个人跳舞。你出左脚,我得知道什么时候出右脚。踩不到点上,就乱套了。
我遇到过最典型的一个案例:一块板子,读数据偶尔出错,十次里错一两次。代码翻来覆去查了三遍,没问题。最后拿示波器一抓,发现片选信号(CS)的建立时间差了那么几十纳秒。嗯,就是这几十纳秒,折腾了我一整天。
时序分析主要关注三个维度:
- 建立时间(tsu):数据在时钟有效沿之前必须稳定的最短时间。
- 保持时间(th):数据在时钟有效沿之后必须稳定的最短时间。
- 访问时间(tacc):从地址有效到数据输出有效的时间。
核心原则:单片机输出的时序参数,必须满足存储器数据手册中要求的最小/最大值。不满足,就是硬件问题。
4.2 示波器抓波前的准备工作
别急着上探头。先做三件事:
- 看数据手册:把存储器的时序图打印出来,标出关键参数。
- 选对探头:普通信号用10×探头,高频信号用有源探头。
- 设置触发:我一般用CS或WE信号的下降沿触发,这样能稳定抓到读写周期。
小技巧:抓多路信号时,把探头的地线夹子尽量缩短。地线太长会引入噪声,波形看起来毛刺很多,影响判断。
4.3 实战:抓取一次完整的读操作时序
以最常见的并行SRAM为例。我们要抓的信号有:CS(片选)、OE(输出使能)、WE(写使能)、地址线(A0-Ax)、数据线(D0-Dx)。
示波器通道分配(我常用的方案):
| 通道 | 信号 | 颜色 | 说明 |
|---|---|---|---|
| CH1 | CS | 黄色 | 片选,低电平有效 |
| CH2 | OE | 绿色 | 输出使能,低电平有效 |
| CH3 | 地址线(最高位) | 蓝色 | 观察地址变化时刻 |
| CH4 | 数据线(最高位) | 红色 | 观察数据输出时刻 |
抓波步骤:
- 将示波器时基设为 50ns/div 或 100ns/div。
- 触发源选 CH1(CS),触发方式选下降沿。
- 运行一段简单的读存储器代码(比如读固定地址 0x0000)。
- 按下示波器的 SINGLE 按钮,等待一次触发。
抓到的波形应该类似这样:
CS ━━━━━━━━━━━━━━━━━━━━\________________________
OE ━━━━━━━━━━━━━━━━━━━━━━\______________________
Addr ━━━━━━━━━━━━━━\_____________________________
Data ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\_______________
↑ ↑
地址建立 数据输出
注意看:地址信号必须先稳定,然后CS和OE拉低,最后数据线上出现有效数据。如果数据在CS拉低之前就变了,那就是保持时间不够。
避坑指南:我曾经遇到过一种情况——波形看起来完全正常,但数据就是不对。后来发现是数据线的上拉电阻焊错了,导致电平转换速度变慢。示波器上看不出毛刺,但时序裕量已经被吃掉了。所以,不仅要看波形形状,还要用示波器的光标测量具体的延迟时间。
4.4 常见时序故障与波形特征
根据我的经验,90%的时序问题都可以通过波形特征快速定位:
| 故障现象 | 波形特征 | 可能原因 | 解决方向 |
|---|---|---|---|
| 数据不稳定 | 数据线在采样点附近跳变 | 建立时间不足 | 增加等待周期或降低时钟 |
| 数据保持错误 | 数据在时钟沿后快速变化 | 保持时间不足 | 调整数据线延迟或换器件 |
| 无数据输出 | 数据线一直为高阻 | CS或OE未有效拉低 | 检查GPIO配置和电平 |
| 数据全为0或全为1 | 数据线电平固定 | 地址线短路或虚焊 | 用万用表量通断 |
| 偶发错误 | 波形偶尔出现毛刺 | 信号反射或串扰 | 加终端电阻或调整PCB走线 |
4.5 用示波器测量具体时序参数
光看波形形状不够,得量化。示波器的光标测量功能这时候就派上用场了。
以测量建立时间为例:
- 将光标A放在时钟(或CS)的有效沿上。
- 将光标B放在数据最后一次跳变的时刻。
- 读取两个光标之间的时间差 Δt。
- 对比数据手册:Δt 必须 ≥ tsu(min)。
我习惯把测量结果记在小本子上,跟数据手册逐项对比。别嫌麻烦,这一步省了,后面调试更痛苦。
经验值参考:对于常见的 55ns SRAM,如果单片机时钟是 72MHz(周期约 13.9ns),建议至少插入 3-4 个等待周期。这样建立时间能留出 40-55ns 的裕量,比较安全。
4.6 时序分析知识体系
下面这张图总结了时序分析与示波器抓波的核心逻辑,建议收藏:
4.7 一个真实案例复盘
去年帮一个客户调试产品,用的是 STM32F4 外挂一个 16 位并行 Flash。现象很诡异:写数据没问题,读数据偶尔返回 0xFF。
我拿到板子,先看电源纹波——正常。再看时钟——正常。然后上示波器抓读时序。
波形一出来我就发现问题了:CS 拉低之后,OE 过了将近 80ns 才拉低。而 Flash 数据手册上写的最大访问时间是 70ns。也就是说,数据已经准备好了,但 OE 还没来,等 OE 来的时候数据已经失效了。
原因是什么?代码里配置的 FSMC(灵活静态存储控制器)时序参数中,OE 延迟设得太大了。我把 FSMC 的 OE 延迟从 4 个 HCLK 改成 2 个,问题立刻解决。
复盘总结:很多时候不是硬件坏了,是时序配置没算对。示波器就是你的“照妖镜”,一照就知道问题在哪。
4.8 抓波时的常见误区
- 只看一路信号:时序是多个信号的配合,至少抓 3-4 路一起看。
- 忽略探头延迟:不同通道的探头延迟可能不同,测量前先做探头补偿。
- 时基设得太快:100ns/div 左右比较合适,太快了看不到完整周期。
- 不测裕量:满足最小值还不够,要留 20%-30% 的裕量才可靠。