一、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 数据传输过程:一拍一拍说清楚
好了,信号知道了,模式也懂了。那实际传输到底怎么走的?我画个流程图给你看。
看懂这个图了吗?我再拆开说说:
- 主设备先拉低SS,告诉从设备「我要开工了」。这个动作一定要先于SCK时钟,我在项目中曾经因为SS和SCK的时序关系没处理好,导致从设备识别到了第一个位。
- 主从同时输出。SPI是全双工的,意思是主发数据的同时,从设备也在发数据。你发一位,我回一位。这个特性很有用,比如读Flash的时候,主设备发命令字节的同时,从设备已经准备好返回状态了。
- SCK提供同步时钟。每个时钟边沿,双方各自移出一位、采样一位。具体哪个边沿采样,由CPHA决定。
- 重复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还是搞反。基本功扎实了,后面的违例捕获技巧才有意义。