3、单字节读写波形解码:从波形到数据的实战演练

好,咱们今天来点真格的。

前面两章讲了SPI的理论和协议框架,说实话,那些东西看文档都能学会。但真正让你拿着逻辑分析仪去抓波形、手动解析数据,很多人就懵了。我当年刚入行时也是这样,看波形像看天书,明明知道协议规则,就是对应不上。

这一章,咱们就拿一个最简单的例子——单字节读写操作,手把手带你走一遍。我会用0x55写操作和0xAA读操作来演示,这两个数据很有特点,解析起来特别直观。

3.1 准备工作:搭建测试环境

在动手之前,先把家伙事儿备齐。我个人习惯用24MHz采样率的逻辑分析仪,对于SPI来说绰绰有余。你手头如果有8通道的,那就更好了。

硬件连接:

  • 逻辑分析仪通道0 → CS(片选)
  • 逻辑分析仪通道1 → SCLK(时钟)
  • 逻辑分析仪通道2 → MOSI(主出从入)
  • 逻辑分析仪通道3 → MISO(主入从出)
  • GND共地(这个千万别忘,我吃过亏)
⚠️ 重要提醒: 逻辑分析仪的GND必须和被测设备的GND连在一起!我曾经有一次忘了接GND,抓出来的波形全是毛刺,折腾了半小时才发现是共地问题。

3.2 捕获写操作波形:0x55的奥秘

我们先看写操作。主机要向从机发送一个字节0x55。为什么选0x55?因为它的二进制是01010101,每个bit都交替变化,在波形上特别容易辨认。

触发设置我建议这样配:

  • 触发条件:CS下降沿(片选拉低表示传输开始)
  • 采样深度:够抓2-3个字节就行,别贪多
  • 采样率:至少4倍于SCLK频率,我一般设8倍

抓到的波形大概长这样(我描述一下,你对照自己的波形看):

CS:   ━━━━━━━┓         ┏━━━━━━━━━━━
              ┃         ┃
SCLK: ━━━━━━┓┃┓┃┓┃┓┃┓┃┓┃┓┃┓┃┓┃┓┃━━━━
             ┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃
MOSI: ━━━━━━┛┛┓┓┛┛┓┓┛┛┓┓┛┛┓┓━━━━━━━
              ┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃┃
MISO: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

嗯,这里要注意:MISO在写操作期间是高阻态或者保持原值,因为从机还没返回数据。

3.3 手动解析MOSI数据:0x55的二进制之美

现在我们来手动解析。把波形放大,找到第一个SCLK上升沿(或者下降沿,取决于CPOL/CPHA配置,我们这里假设是模式0,即上升沿采样)。

解析步骤:

  1. 找到CS拉低的时刻,这是传输开始的标志
  2. 从第一个SCLK有效沿开始,依次读取MOSI电平
  3. 高位在前(MSB first),所以第一个bit是bit7
  4. 记录8个bit,组成一个字节

咱们来实际读一下:

SCLK边沿序号 1 2 3 4 5 6 7 8
MOSI电平 0 1 0 1 0 1 0 1
对应bit位 bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

把电平值按顺序写下来:0 1 0 1 0 1 0 1,转换成十六进制就是0x55。你看,是不是很直观?

💡 小技巧: 0x55和0xAA是调试SPI时的黄金数据。0x55是01010101,0xAA是10101010,两者互为取反。用这两个数据可以快速验证bit顺序是否正确、时钟极性是否配置对。

3.4 解析MISO数据:0xAA的读取

接下来看读操作。假设主机发送一个读命令后,从机返回0xAA。这时候MISO线上就有数据了。

抓到的波形中,MISO的变化和SCLK是同步的。同样是在SCLK的上升沿采样MISO的电平:

SCLK边沿序号 1 2 3 4 5 6 7 8
MISO电平 1 0 1 0 1 0 1 0
对应bit位 bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

1 0 1 0 1 0 1 0,十六进制就是0xAA。完美!

你想想看,如果这时候你读出来的是0x55,那说明什么?要么是bit顺序搞反了(LSB first),要么是时钟沿采错了。我在项目中就遇到过这种情况,当时排查了半天,最后发现是从机手册里写的是下降沿采样,而我默认用了上升沿。

3.5 验证CS与SCLK的时序关系

这是很多新手容易忽略的地方。CS和SCLK之间是有严格时序要求的,不是随便拉低CS就能开始传时钟。

关键时序参数:

  • t_lead(CS建立时间): CS拉低后,到第一个SCLK有效沿之前,必须保持至少一个最小时间。我见过有些从机要求至少50ns。
  • t_lag(CS保持时间): 最后一个SCLK有效沿之后,到CS拉高之前,也需要保持一段时间。
  • t_idle(CS空闲时间): 两次传输之间,CS必须保持高电平至少一段时间。

用逻辑分析仪怎么验证?很简单:

  1. 把波形放大,找到CS下降沿的位置
  2. 找到第一个SCLK上升沿的位置
  3. 测量两者之间的时间差,这就是t_lead
  4. 同样方法测量最后一个SCLK沿到CS上升沿的时间,就是t_lag
🔧 实战经验: 我建议你在逻辑分析仪软件里直接添加测量光标。比如Saleae Logic软件,按M键添加测量点,然后拖动到波形上,软件会自动显示时间差。这样比你肉眼估算准得多。

如果测出来t_lead只有10ns,而从机手册要求至少50ns,那就会出现偶发性的通信失败。我曾经在一个项目中,SPI偶尔读写错误,查了三天,最后发现就是CS建立时间不够。把CS拉低的时机提前了几个时钟周期,问题就解决了。

3.6 常见问题与避坑指南

最后,我总结几个实际调试中容易踩的坑:

  • 采样率不够: 如果逻辑分析仪采样率只有SCLK的2倍,可能采不到正确的电平。我建议至少4倍,8倍更保险。
  • 触发位置不对: 有时候CS下降沿触发抓不到数据,可能是因为CS上有毛刺。可以试试用SCLK的第一个上升沿作为触发条件。
  • 忘记考虑CPOL/CPHA: 模式0和模式3的采样沿不同,解析时一定要先确认从机的工作模式。
  • MISO和MOSI搞反: 这个错误很低级,但我真见过有人把通道接反了,然后对着波形分析半天分析不出来。

好了,这一章的内容就到这儿。你拿着逻辑分析仪,按照我说的步骤去抓一次波形,手动解析一遍,保证你对SPI的理解会上一个台阶。下一章咱们讲多字节传输和连续读写,那个更有意思。

📌 本章要点回顾:
  • 0x55的二进制是01010101,0xAA是10101010,两者是调试SPI的黄金数据
  • 手动解析时,按SCLK有效沿逐个读取bit,高位在前
  • CS与SCLK之间有t_lead、t_lag、t_idle三个关键时序参数
  • 用逻辑分析仪的测量光标功能精确测量时序

公众号:蓝海资料掘金营,微信deep3321