一、SPI协议基础:信号定义与时序图

各位同学,咱们直接进入正题。

SPI通信这事儿,说白了就是主从设备之间的聊天协议。你想想看,两个芯片要交换数据,总得有个约定吧?谁来发起,什么时候发,发多少位,怎么确认收到——这些都得定好。SPI就是其中最经典的一种。

我刚开始做数字IC那会儿,总觉得SPI太简单,不就是四根线嘛。直到有一次调试,明明协议是对的,可数据就是不对。查了三天,最后发现是主设备时钟相位设反了。嗯,从那以后我再也不敢小看这四根线了。

核心要点:SPI的全称是 Serial Peripheral Interface,串行外设接口。它是同步的、全双工的、主从结构的总线协议。

咱们先聊聊最基本的信号定义。

1.1 四根信号线,一个都不能少

SPI总共就四条线,不多不少。我给你列个表,一目了然:

信号名称 全称 方向(主设备视角) 一句话描述
SCK Serial Clock 输出 时钟,由主设备产生,决定数据速率
MOSI Master Out Slave In 输出 主设备发送,从设备接收
MISO Master In Slave Out 输入 从设备发送,主设备接收
SS (或 CS) Slave Select / Chip Select 输出 片选信号,低电平有效,选中从设备

你看,就这么简单。但我得提醒你一句:别看线少,时序翻车的概率可不低。我在项目里见过有人把MOSI和MISO搞反,焊完板子才发现,那叫一个尴尬。

避坑指南:我曾经在一个FPGA项目里,SS信号没有做同步处理,导致从设备误触发。记住:SS虽然是控制信号,但在跨时钟域时一定要做同步,否则会出现毛刺误判。

1.2 四种模式,搞不清就容易翻车

SPI有四种工作模式。模式怎么来的?取决于两个参数:时钟极性(CPOL) 和 时钟相位(CPHA)。

  • CPOL:决定SCK空闲时的电平。CPOL=0,空闲低电平;CPOL=1,空闲高电平。
  • CPHA:决定数据采样在哪一个边沿。CPHA=0,在第一个边沿采样(通常是上升沿);CPHA=1,在第二个边沿采样(通常是下降沿)。

组合一下,就是四种模式。我习惯用一张表记住它们:

模式 CPOL CPHA 采样边沿 数据变化边沿
模式 0 0 0 上升沿 下降沿
模式 1 0 1 下降沿 上升沿
模式 2 1 0 下降沿 上升沿
模式 3 1 1 上升沿 下降沿

你注意看规律:CPHA=0时,采样边沿总是CPOL取反后的那个边沿。说白了,模式0和模式3其实是对称的。

小技巧:我个人习惯,如果从设备数据手册没写清楚,先试试模式0(CPOL=0, CPHA=0)。大部分SPI Flash和传感器默认都是模式0。如果不行,再试模式3。大多数场景下,这两个模式能覆盖80%的情况。

1.3 数据传输过程:一拍一拍说清楚

好了,信号知道了,模式也懂了。那实际传输到底怎么走的?我画个流程图给你看。

SPI 四线制数据传输流程 SPI 主从数据传输流程 主设备 (Master) 从设备 (Slave) 步骤1:主设备将 SS/CS 拉低,选中从设备 SS / CS 片选线 步骤2:主设备在 MOSI 上发数据 步骤2:从设备在 MISO 上回数据 步骤3:SCK 提供时钟边沿,双方同步移位数据 步骤4:重复步骤2-3,完成8位(或更多位)传输 循环 8 次

看懂这个图了吗?我再拆开说说:

  1. 主设备先拉低SS,告诉从设备「我要开工了」。这个动作一定要先于SCK时钟,我在项目中曾经因为SS和SCK的时序关系没处理好,导致从设备识别到了第一个位。
  2. 主从同时输出。SPI是全双工的,意思是主发数据的同时,从设备也在发数据。你发一位,我回一位。这个特性很有用,比如读Flash的时候,主设备发命令字节的同时,从设备已经准备好返回状态了。
  3. SCK提供同步时钟。每个时钟边沿,双方各自移出一位、采样一位。具体哪个边沿采样,由CPHA决定。
  4. 重复8次。一个字节传完。如果数据位宽是16位或者32位,那就重复更多次,直到SS拉高为止。

我的经验:SPI的传输单位不一定是8位。很多ADC和DAC用的是12位或16位。设计RTL时,建议把移位计数器做成参数化,别写死了。我就是因为偷懒写死了8位计数器,后来换器件时改得想哭。

1.4 时序参数:搞不清这些,STA会跟你过不去

好,协议流程清楚了。但咱们做时序分析的,不能只停留在逻辑层面。你得知道几个关键的时序参数,这些在静态时序分析(STA)里直接用。

参数 含义 典型值(参考) 违例后果
fSCK SCK时钟频率 10MHz ~ 100MHz 频率过高会导致建立时间违例
tSU 数据建立时间 (Setup Time) 2 ~ 5 ns 数据在时钟沿前稳定不够,采错值
tH 数据保持时间 (Hold Time) 1 ~ 3 ns 数据在时钟沿后变化太快,同样采错
tSCK_high / tSCK_low 时钟高低电平最小宽度 通常为周期的一半 占空比超标,导致时钟质量下降
tCS_setup SS在第一个SCK沿前的建立时间 5 ~ 10 ns 从设备可能无法正确识别传输开始

这里我要重点说一句:建立时间和保持时间,是STA的命根子。你时序约束文件里写的,无非就是这俩参数。SPI虽然是低速协议,但在SoC内部,如果你的SPI控制器跑在100MHz以上,且数据路径经过了组合逻辑,那时序违例的风险相当大。

特别提醒:很多同学以为SPI是同步接口,时序肯定没问题。错了!当SPI控制器工作在系统时钟域,而SCK是分频产生的,如果分频比不是整数(比如3.5分频),时钟沿的抖动就会成为时序违例的元凶。我曾经在一个项目里,用奇数分频给SPI提供时钟,结果SCK的占空比失调,hold time直接崩了。

1.5 三个常见的时序违例场景

最后,我简单列几个常见的问题场景。这些都是我实际踩过的坑:

  • 场景一:SCK频率太高,数据路径延时过大。解决办法:要么降频,要么在数据路径上插入流水线寄存器。
  • 场景二:SS信号没有和SCK同步。解决办法:用两级触发器做跨时钟域同步,或者直接用系统时钟打一拍。
  • 场景三:主从设备模式不匹配。解决办法:查手册!CPOL和CPHA对不上,数据采样全错。

你注意看,前两个其实都是时序问题,第三个是逻辑配置问题。但不管哪种,最终在测试波形上一眼看出来都不难。难的是什么?是你得在写RTL的时候就预判到这些。

这章讲的是SPI协议最基础的东西。信号定义、四种模式、传输过程、时序参数、常见坑。别觉得简单。我见过有人做了五年IC设计,SPI的CPOL和CPHA还是搞反。基本功扎实了,后面的违例捕获技巧才有意义。