3. SPI协议详解
SPI(Serial Peripheral Interface)是一种高速、全双工、同步串行总线,最早由Motorola提出,广泛用于MCU与Flash、传感器、显示屏、ADC等外设之间的短距离通信。与I²C相比,SPI没有设备地址,靠片选信号区分从机,协议简单、速率高,但占用引脚较多。理解SPI的关键在于四根信号线、主从角色、时钟极性与相位的组合,以及由此决定的四种工作模式。
一、SPI接口信号与主从模式
标准SPI接口由四根信号线组成,通常称为“四线SPI”:
- SCLK(Serial Clock):时钟信号,由主机产生,决定数据传输速率。
- MOSI(Master Out Slave In):主机输出、从机输入,用于主机向从机发送数据。
- MISO(Master In Slave Out):主机输入、从机输出,用于从机向主机返回数据。
- CS/SS(Chip Select / Slave Select):片选信号,低电平有效,主机通过拉低某根CS选中对应从机。
SPI采用主从架构:主机掌握时钟,从机被动响应。一个主机可以挂多个从机,但每个从机需要独立的CS线;同一时刻只能有一个从机被选中,否则MISO会出现总线冲突。SPI是全双工总线,主机在MOSI上发送一位的同时,从机也在MISO上返回一位,因此读写可以同时进行。对于SPI Flash,主机发送命令和地址的同时,Flash会在后续时钟周期返回数据或状态。
二、时钟极性与相位:CPOL与CPHA
SPI的时钟行为由两个参数决定:时钟极性CPOL(Clock Polarity)和时钟相位CPHA(Clock Phase)。它们共同定义了数据在时钟的哪个边沿采样、在哪个边沿变化。
- CPOL=0:空闲时SCLK为低电平;CPOL=1:空闲时SCLK为高电平。
- CPHA=0:在第一个时钟边沿采样数据,第二个边沿输出数据。
- CPHA=1:在第一个时钟边沿输出数据,第二个边沿采样数据。
换句话说,CPOL决定“空闲电平”和“有效边沿”的基准,CPHA决定“采样边沿”是第一个还是第二个边沿。主机和从机必须使用相同的CPOL和CPHA,否则采样点错位,读到的数据会整体移位或完全错误。
三、四种SPI模式
CPOL和CPHA组合出四种模式,通常记为Mode 0~Mode 3。不同外设支持的模式不同,SPI Flash最常用的是Mode 0和Mode 3。
| 模式 | CPOL | CPHA | 空闲电平 | 采样边沿 | 输出边沿 |
|---|---|---|---|---|---|
| Mode 0 | 0 | 0 | 低 | 上升沿 | 下降沿 |
| Mode 1 | 0 | 1 | 低 | 下降沿 | 上升沿 |
| Mode 2 | 1 | 0 | 高 | 下降沿 | 上升沿 |
| Mode 3 | 1 | 1 | 高 | 上升沿 | 下降沿 |
以Mode 0为例:空闲时SCLK为低,第一个边沿是上升沿,主机和从机在上升沿采样,在下降沿更新数据。Mode 3则相反:空闲为高,第一个边沿是下降沿,但采样仍发生在上升沿,因此数据在下降沿变化、上升沿被采样。对于SPI Flash,Mode 0和Mode 3都能正常工作,因为Flash在时钟上升沿采样MOSI,在下降沿输出MISO,两种模式下有效采样边沿一致。
四、时序参数与波形分析
SPI时序分析的核心是确认“数据在哪个边沿稳定、在哪个边沿被采样”。以Mode 0发送一个字节0x5A(二进制01011010)为例,MSB先发,波形关系如下:
CS \________________________________________/
SCLK ___/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\______
MOSI X D7 D6 D5 D4 D3 D2 D1 D0 X
0 1 0 1 1 0 1 0
采样点 ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
图中每个上升沿采样一位,8个时钟完成一个字节。若CPHA=1,则第一个边沿用于输出,第二个边沿用于采样,数据会相对时钟延迟半个周期。实际调试时,用逻辑分析仪或示波器同时抓取CS、SCLK、MOSI、MISO四路信号,重点检查:CS拉低到第一个时钟边沿的建立时间、数据相对采样边沿的建立/保持时间、以及最后一个时钟边沿到CS拉高的保持时间。
SPI Flash数据手册中常见的时序参数包括:
- fSCLK:最大时钟频率,如50MHz、104MHz。
- tSLCH:CS低到第一个时钟上升沿的建立时间。
- tCHSH:最后一个时钟上升沿到CS拉高的保持时间。
- tDVCH:数据有效到时钟上升沿的建立时间。
- tCHDX:时钟上升沿后数据保持时间。
这些参数决定了驱动中CS控制、时钟分频和延时配置是否满足从机要求。若时钟过快或CS切换过早,Flash可能无法正确锁存命令,表现为读ID失败、读数据全0或全FF。
五、案例与常见误区
在SPI Flash驱动开发中,一个典型场景是:MCU的SPI控制器配置为Mode 0、8位数据、MSB先发、时钟分频后为10MHz,CS由软件GPIO控制。上电后读取Flash的JEDEC ID,命令为0x9F。若读回0x000000,常见原因不是Flash损坏,而是模式不匹配或CS时序错误。例如,主机配置为Mode 1,而Flash要求Mode 0,采样边沿从上升沿变成下降沿,命令字被错位采样,Flash自然不响应。
复盘时建议按以下顺序排查:先确认CPOL/CPHA与Flash手册一致;再用示波器检查CS、SCLK、MOSI的边沿关系;然后降低时钟频率验证是否时序余量不足;最后检查CS是否由软件精确控制,确保命令、地址、数据阶段之间CS保持低电平。掌握这些要点后,SPI Flash的底层读写就有了可靠的时序基础。