2. SPI协议深度解析:模式、时钟极性与相位、多从机片选
SPI协议,说白了就是四根线的事儿——SCLK、MOSI、MISO、CS。但就是这四根线,坑了我不少个通宵。今天咱们把这协议掰开了揉碎了讲,你以后调LCD驱动时,至少能少走一半弯路。
2.1 SPI的四种模式:CPOL与CPHL到底在说啥?
很多新手看到SPI模式0/1/2/3就头大。我刚开始也这样,后来发现其实就两个参数:时钟极性(CPOL)和时钟相位(CPHA)。
| SPI模式 | CPOL | CPHA | 空闲时钟电平 | 数据采样边沿 |
|---|---|---|---|---|
| 模式0 | 0 | 0 | 低电平 | 上升沿采样 |
| 模式1 | 0 | 1 | 低电平 | 下降沿采样 |
| 模式2 | 1 | 0 | 高电平 | 下降沿采样 |
| 模式3 | 1 | 1 | 高电平 | 上升沿采样 |
核心记忆法:CPOL决定空闲电平,CPHA决定采样边沿。模式0和模式3最常用——LCD驱动芯片八成以上默认模式0。
我遇到过最坑的一次:某国产LCD屏手册写支持模式0,结果示波器一抓,它其实在模式3下才稳定。后来发现是手册翻译错了。所以啊,别信手册,信示波器。
2.2 时钟极性与相位:示波器上怎么看?
调驱动时,你不可能每次都去翻芯片手册。我的习惯是:直接抓波形,一眼判断模式。
- 看空闲电平:CS拉高后,SCLK停在低电平→CPOL=0;停在高电平→CPOL=1。
- 看采样边沿:数据在SCLK上升沿变化→CPHA=0(采样在下降沿);数据在下降沿变化→CPHA=1(采样在上升沿)。
实战技巧:用示波器同时抓SCLK和MOSI,把时基放到每格50ns。看MOSI数据变化时刻对应SCLK的哪个边沿——这个边沿就是数据变化边沿,另一个边沿就是采样边沿。
举个例子:你看到SCLK空闲是低,数据在上升沿变化,那下降沿就是采样点。CPOL=0,CPHA=1→模式1。简单吧?
2.3 多从机片选机制:别让CS坑了你
一个SPI总线上挂多个设备,最常见的就是LCD+触摸屏+Flash。片选机制看似简单,其实有门道。
2.3.1 硬件片选 vs 软件片选
- 硬件片选:每个从机独立CS引脚,MCU的GPIO直接控制。优点是响应快,缺点是占引脚。
- 软件片选:通过SPI指令中的地址字节来选择从机。省引脚,但协议复杂,速度慢。
LCD驱动几乎都用硬件片选。我建议你也这么干——软件片选在高速传输时容易出时序问题,我曾经被坑过一次,200ns的片选延迟导致LCD刷屏出现条纹。
2.3.2 片选时序的三个关键点
- CS拉低到第一个SCLK的时间(tCSS):至少大于从机要求的建立时间,一般5ns~50ns。
- 最后一个SCLK到CS拉高的时间(tCSH):保证数据完全锁存,通常10ns以上。
- CS拉高到下一次拉低的时间(tCS间):给从机足够时间处理数据,至少100ns。
我曾经踩过的坑:某项目用STM32的硬件SPI驱动LCD,CS用软件控制。结果发现每次传输完最后一个字节,CS立刻拉高,导致LCD没锁存到数据。后来在SPI传输完成后加了50ns的延时才解决。记住:CS拉高不能紧贴着最后一个SCLK边沿。
2.4 SPI协议核心流程图
下面这张图把SPI一次完整传输的流程画清楚了。你对照着看,以后调驱动时心里就有谱了。
2.5 多从机片选的硬件设计建议
如果你要在一条SPI总线上挂多个设备,有几点经验供你参考:
- CS引脚不要共用:每个从机独立CS,不要用译码器。译码器会引入额外延迟,高速时容易出问题。
- CS线要短:超过10cm的CS线,建议加33Ω串联电阻抑制反射。我见过CS线上振铃导致从机误触发的案例。
- 空闲时CS必须拉高:有些从机内部有弱上拉,但别依赖它。GPIO配置成推挽输出,主动拉高。
- 切换从机时留足时间:CS拉高后,至少等1μs再拉低下一个从机的CS。给总线一个“冷静期”。
我的调试习惯:新板子第一次上电,先用示波器抓CS和SCLK的对应关系。看CS拉低后多久出现第一个SCLK,最后一个SCLK后多久CS拉高。这两个时间决定了你的SPI配置是否匹配从机要求。
2.6 常见SPI模式配置错误与现象
| 错误类型 | 现象 | 排查方法 |
|---|---|---|
| CPOL配置反了 | 第一个字节正确,后续全错 | 抓SCLK空闲电平,对比手册 |
| CPHA配置反了 | 数据整体偏移一位 | 看数据变化边沿是否在采样边沿 |
| CS时序太紧 | 偶尔丢数据,尤其高速时 | 检查tCSS和tCSH是否满足 |
| SCLK频率过高 | 数据全是0xFF或0x00 | 降低频率到1MHz以下测试 |