SPI协议深度解析:4线模式、3线模式、时钟极性(CPOL)、时钟相位(CPHA)、片选管理、多从机拓扑

SPI这个协议,说实话,是嵌入式开发里最常用的串行总线之一。它简单、快速、可靠。但很多工程师用了好几年,遇到一些奇怪的问题还是抓瞎。比如时钟极性配错了,数据死活读不对;或者多从机拓扑下,片选信号没处理好,总线冲突了。

我刚开始做驱动开发时,也踩过这些坑。今天咱们就把SPI协议掰开揉碎了讲清楚。从最基本的4线模式,到3线模式,再到时钟极性和相位的配置,最后聊聊多从机拓扑下的片选管理。嗯,内容不少,但都是干货。

一、SPI的4线模式:标准配置

标准的SPI接口,说白了就是4根线:SCLK(时钟)、MOSI(主出从入)、MISO(主入从出)、CS(片选)。这4根线各司其职,缺一不可。

信号线 全称 方向 作用
SCLK Serial Clock 主→从 提供同步时钟,由主机产生
MOSI Master Out Slave In 主→从 主机发送数据给从机
MISO Master In Slave Out 从→主 从机发送数据给主机
CS Chip Select 主→从 片选信号,低电平有效,选中从机

我个人习惯把SPI通信想象成「主从对话」。主机控制时钟,想什么时候说话就什么时候说话。从机只能被动响应。CS信号就是「点名」,谁被拉低谁就应答。

关键点:SPI是同步全双工通信。什么意思?就是主机发一个bit的同时,从机也发一个bit回来。所以每次传输,主机和从机都在交换数据。你发出去的数据,和你收到的数据,是同时发生的。

二、3线模式:省一根线,多一份麻烦

有些场景下,我们想省一根线。比如引脚不够用了,或者从机只需要单向通信。这时候就有了3线模式。

3线模式有两种常见变体:

  • 半双工3线:MOSI和MISO合并成一根数据线(SDIO)。主机和从机分时复用这根线。发的时候不能收,收的时候不能发。
  • 单向3线:从机不需要回数据,所以MISO直接省掉。比如一些只写的DAC芯片,或者只读的传感器。

我在项目中遇到过一种情况:一个温湿度传感器,只支持3线半双工模式。我一开始按4线全双工去配驱动,结果数据读出来全是乱的。后来才发现,这个芯片在发送命令后,需要把数据线方向切换成输入,才能读到数据。嗯,这里要注意,3线模式下,GPIO的方向切换时机非常关键。

避坑指南:我曾经在3线半双工模式下,没有在发送完命令后及时释放数据线,导致从机拉不动总线,数据一直读0。后来加了方向切换延时,问题才解决。3线模式对时序要求更严格,建议在切换方向后加一个微秒级的延时。

三、时钟极性(CPOL)和时钟相位(CPHA):SPI的灵魂

这两个参数,是SPI协议里最容易搞混的地方。我见过不少工程师,配错了CPOL和CPHA,然后怀疑芯片坏了。

咱们先明确概念:

  • CPOL(Clock Polarity):决定空闲时时钟线的电平。CPOL=0,空闲时低电平;CPOL=1,空闲时高电平。
  • CPHA(Clock Phase):决定数据在哪个时钟沿采样。CPHA=0,在第一个时钟沿采样;CPHA=1,在第二个时钟沿采样。

组合起来就是4种模式:

模式 CPOL CPHA 空闲时钟电平 数据采样沿
模式0 0 0 低电平 上升沿(第一个沿)
模式1 0 1 低电平 下降沿(第二个沿)
模式2 1 0 高电平 下降沿(第一个沿)
模式3 1 1 高电平 上升沿(第二个沿)

你想想看,为什么会有4种模式?因为不同的从机芯片,内部逻辑设计不一样。有的芯片喜欢在上升沿采样,有的喜欢在下降沿。配错了,数据就会错位一个bit。

我的经验:拿到一个新芯片,先看数据手册里的时序图。图上会明确标出数据是在哪个时钟沿采样的。如果手册没写,直接默认用模式0(CPOL=0, CPHA=0),这是最通用的配置。80%的芯片都支持模式0。

这里我画了一张时序对比图,帮你直观理解4种模式的区别:

SPI四种模式时序对比图 模式0 (CPOL=0, CPHA=0) SCLK MOSI 模式1 (CPOL=0, CPHA=1) SCLK MOSI 模式2 (CPOL=1, CPHA=0) SCLK MOSI 模式3 (CPOL=1, CPHA=1) SCLK MOSI 图例说明 红色圆点 = 数据采样点 绿色/红色/橙色/紫色块 = 数据bit

四、片选管理:谁拉低谁说话

片选信号(CS)是SPI总线里最容易被忽视的细节。很多人觉得CS就是拉低一下,发完数据再拉高。但实际项目中,CS的时序控制直接影响通信的可靠性。

片选管理有几个关键点:

  • CS建立时间:拉低CS后,需要等待一段时间再开始发时钟。这个时间叫CS Setup Time。不同芯片要求不同,有的需要几微秒。
  • CS保持时间:最后一个时钟结束后,CS不能立刻拉高,需要保持一段时间。这叫CS Hold Time。
  • CS去抖:有些从机对CS的上升沿和下降沿有毛刺敏感。我建议在CS线上加一个RC滤波,或者用软件做去抖。

避坑指南:我曾经在一个项目中,CS拉低后立刻发时钟,结果从机没响应。查了半天数据手册,发现这个芯片要求CS拉低后至少等待5个时钟周期才能开始通信。加了延时后,问题解决。记住:CS的建立时间和保持时间,一定要看数据手册。

五、多从机拓扑:菊花链 vs 独立片选

当总线上有多个从机时,有两种常见的连接方式:

拓扑方式 连接方式 优点 缺点
独立片选 每个从机一根独立的CS线 简单、灵活、每个从机独立控制 占用GPIO多,从机数量受限于GPIO数量
菊花链 所有从机共享SCLK、MOSI、MISO,CS也共享 节省GPIO,适合大量从机 时序复杂,数据延迟大,从机需要支持菊花链模式

独立片选是最常用的方式。每个从机一根CS线,主机通过拉低不同的CS来选择不同的从机。这种方式下,MISO线需要特别注意:所有从机的MISO是开漏输出,或者三态输出。当CS为高时,从机的MISO必须处于高阻态,否则多个从机同时驱动MISO,会烧毁引脚。

菊花链模式,说白了就是把从机串起来。数据从第一个从机的MOSI进去,从它的MISO出来,再接到第二个从机的MOSI。这样只需要一根CS线,就能控制多个从机。但代价是数据延迟会累加,而且所有从机必须支持菊花链功能。

我的建议:如果从机数量不超过4个,优先用独立片选。简单、可靠、调试方便。如果从机数量很多(比如8个以上),再考虑菊花链。但菊花链的驱动代码要复杂得多,建议先评估从机是否支持。

最后,我画了一张多从机拓扑的结构图,帮你理清这两种方式的区别:

SPI多从机拓扑结构图 独立片选拓扑 主机 (Master) 从机1 从机2 从机3 CS1 CS2 CS3 菊花链拓扑 主机 (Master) 从机A 从机B 从机C MOSI MISO→MOSI MISO→MOSI 共享CS 关键区别 独立片选:每个从机独立CS,MISO需要三态输出。菊花链:共享CS,数据串行通过,从机必须支持菊花链模式。

好了,SPI协议的核心内容就这些。从4线到3线,从CPOL/CPHA到片选管理,再到多从机拓扑。这些知识点,你在实际项目中都会遇到。下次调试SPI设备时,先检查时钟模式配对了没有,再看CS时序对不对。嗯,基本就能解决90%的问题。