3、SPI协议精讲:四线模式、三线模式、时钟极性与相位、片选信号、多从机配置
SPI这个协议,说实话,是我在嵌入式开发中用得最多的串行接口之一。它简单、高效,但坑也不少。我见过太多工程师在SPI上栽跟头,尤其是刚接触的时候。今天我就把SPI的底裤扒干净,从四线到三线,从时钟极性到多从机,咱们一个一个说清楚。
3.1 四线模式:最经典的SPI
标准的SPI四线模式,大家应该都熟悉。四根线分别是:SCLK(时钟)、MOSI(主出从入)、MISO(主入从出)、CS(片选)。
我个人习惯把SPI想象成一个环形移位寄存器。主设备发起时钟,数据就在MOSI和MISO上同时流动。你想想看,主设备发一个bit,从设备同时回一个bit,这就是全双工通信。
四线模式的核心要点:
- SCLK由主设备产生,从设备只能被动接收
- MOSI和MISO是独立的,可以同时传输
- CS低电平有效,选中从设备
- 一次传输完成后,CS拉高,总线释放
我在项目中遇到过一个问题:某款传感器在CS拉高后,MISO引脚没有立即释放,导致下一轮通信时数据冲突。后来查手册才发现,这款芯片的MISO释放时间需要几个微秒。嗯,这里要注意,不同芯片的CS释放时间差异很大。
3.2 三线模式:省一根线,多一份麻烦
三线模式,说白了就是把MOSI和MISO合并成一根双向数据线。为什么要这么做?省引脚啊!有些小封装芯片,引脚就那么几个,能省一根是一根。
但省线的代价是什么?半双工通信。同一时刻只能一个方向传输数据。主设备发的时候,从设备不能回;从设备回的时候,主设备不能发。
三线模式的避坑指南:
我曾经在一个低功耗项目里用了三线SPI,结果发现通信速率上不去。为什么?因为每次切换方向都需要额外的GPIO控制时间。如果你对速率有要求,老老实实用四线吧。
三线模式还有一种变体,叫「单线SPI」。它连时钟都省了,用曼彻斯特编码或者脉冲宽度调制来传输数据。这种模式我一般不建议用,除非你实在没引脚了。
3.3 时钟极性与相位:SPI的灵魂
时钟极性(CPOL)和时钟相位(CPHA),这两个参数决定了数据在时钟的哪个边沿采样。搞不清楚这两个参数,你的SPI通信大概率会失败。
| 模式 | CPOL | CPHA | 采样边沿 | 空闲时钟电平 |
|---|---|---|---|---|
| 模式0 | 0 | 0 | 上升沿 | 低电平 |
| 模式1 | 0 | 1 | 下降沿 | 低电平 |
| 模式2 | 1 | 0 | 下降沿 | 高电平 |
| 模式3 | 1 | 1 | 上升沿 | 高电平 |
你想想看,如果主设备配置的是模式0,从设备却是模式2,那数据采样点就完全错位了。我刚开始做SPI时,就因为这个原因折腾了一整天。后来学乖了,每次拿到新芯片,第一件事就是看手册里的时序图。
我的个人经验:
用示波器看SPI波形时,先看空闲时SCLK的电平。如果是低电平,CPOL=0;如果是高电平,CPOL=1。然后看数据变化发生在哪个边沿,就能反推出CPHA。这个方法我用了十年,从来没失手过。
3.4 片选信号:别小看这根线
片选信号(CS),很多人觉得不就是拉低选中、拉高释放吗?其实没那么简单。
首先,CS的建立时间和保持时间。主设备拉低CS后,需要等待一段时间才能开始发时钟。这个时间叫CS建立时间。同样,最后一个时钟结束后,CS不能立刻拉高,需要保持一段时间。这个时间叫CS保持时间。
我曾经在一个项目里,因为CS建立时间不够,导致从设备没有正确识别到片选信号,数据全部丢失。后来在代码里加了一个微秒级的延时,问题就解决了。
CS信号的注意事项:
- CS拉低后,至少等待一个时钟周期再开始传输
- 传输结束后,CS保持低电平至少半个时钟周期再拉高
- 两次传输之间,CS必须拉高至少一个时钟周期
- 有些芯片要求CS在传输过程中不能有毛刺
3.5 多从机配置:菊花链 vs 独立片选
当你有多个SPI从设备时,有两种连接方式:独立片选和菊花链。
独立片选:每个从设备有自己的CS线,主设备用多个GPIO分别控制。这种方式最常用,也最可靠。缺点是GPIO占用多。
菊花链:所有从设备共享SCLK、MOSI、MISO,但CS也共享。数据从第一个从设备的MOSI进,从它的MISO出,再接到第二个从设备的MOSI,以此类推。这种方式省GPIO,但延迟大,而且任何一个从设备出问题,整条链都废了。
多从机配置的坑:
我记得有一次做多从机项目,用了独立片选,但没注意从设备的输出阻抗。结果两个从设备的MISO同时输出,导致总线冲突。后来在每个MISO上加了一个三态缓冲器才解决。所以,多从机配置时,一定要确保未选中的从设备MISO处于高阻态。
还有一种情况,就是不同从设备支持的最高速率不同。你想想看,如果主设备用10MHz的时钟,但某个从设备只能跑5MHz,那这个从设备就会出错。解决办法是:要么统一用最低速率,要么给每个从设备单独配置速率。
3.6 实战经验:用示波器抓SPI异常
说了这么多理论,咱们来点实际的。怎么用示波器抓SPI异常?
第一步,先看时钟。SCLK的波形是否干净?有没有毛刺?频率对不对?我见过很多SPI问题,其实就是时钟不稳定。
第二步,看CS。CS拉低和拉高的时机对不对?有没有在传输过程中抖动?
第三步,看数据。MOSI和MISO上的数据,在采样边沿是否稳定?如果数据在采样边沿附近变化,那就是时序问题。
我的调试技巧:
用示波器的「余辉」模式,可以观察到信号的抖动情况。如果数据线的抖动超过半个时钟周期,那通信大概率会出错。这时候就要检查PCB走线长度、阻抗匹配、驱动能力等因素了。
最后说一句,SPI虽然简单,但细节决定成败。每个参数、每根线、每个时序,都值得你认真对待。好了,这一章就到这里,下一章咱们聊聊SPI的高级应用和常见故障排查。