4、SPI总线协议:四线制、主从模式、时钟极性(CPOL)与相位(CPHA)、多从机连接

SPI,全称是Serial Peripheral Interface,串行外设接口。这玩意儿在嵌入式世界里,可以说是最常用的通信接口之一了。我刚开始做硬件驱动那会儿,打交道最多的就是它。说白了,SPI就是让主设备(比如单片机)和从设备(比如传感器、显示屏、存储芯片)之间快速交换数据的一种方式。

它简单、高效,而且速度可以做得很快。今天咱们就来好好聊聊这个协议的核心要点。

4.1 四线制:SPI的物理基础

SPI之所以叫“四线制”,是因为它至少需要四根信号线才能工作。你想想看,这比I2C的两根线要多,但换来的是更高的速度和更简单的协议逻辑。

这四根线分别是:

  • SCLK (Serial Clock):串行时钟线。由主设备产生,决定了数据传输的节奏。就像乐队里的指挥棒,一拍一动。
  • MOSI (Master Out Slave In):主设备输出,从设备输入。数据从主设备流向从设备。
  • MISO (Master In Slave Out):主设备输入,从设备输出。数据从从设备流向主设备。
  • SS (Slave Select):从设备选择线,也叫片选线。同样是主设备控制,用来选中你要跟哪个从设备说话。

嗯,这里要注意一点:MOSI和MISO是两条独立的数据线。这意味着SPI可以同时发送和接收数据,这叫“全双工”通信。我在项目中遇到过不少新手,以为SPI和UART一样是分时收发,其实不是的,它俩是同时进行的。

核心要点:SPI的每一次时钟脉冲,主设备都会通过MOSI发送一个bit,同时从设备也会通过MISO返回一个bit。所以一次完整的SPI传输,主设备发送一个字节,也必然会收到一个字节。

4.2 主从模式:谁说了算?

SPI通信中,只有一个主设备(Master),它可以有多个从设备(Slave)。主设备负责产生时钟信号,并决定什么时候跟哪个从设备通信。

从设备呢?它只能被动地等待主设备来“召唤”。主设备把某个从设备的SS线拉低,这个从设备就知道:“哦,轮到我了。”然后它就开始在时钟的驱动下,跟主设备交换数据。

我个人习惯把主设备想象成“老板”,从设备是“员工”。老板(主设备)掌握着时钟这个“发号施令”的权力,他什么时候想跟哪个员工(从设备)谈话,就把那个员工的“工牌”(SS线)激活一下。

避坑指南:我曾经在一个项目中,因为主设备的SS引脚初始化时没有拉高,导致多个从设备同时被选中,数据全乱套了。记住,SS线在空闲时必须保持高电平,这是“片选无效”的状态。

4.3 时钟极性(CPOL)与相位(CPHA):SPI的四种模式

这部分是SPI协议里最容易让人迷糊的地方。我刚开始学的时候也绕了好久。其实说白了,就是定义时钟信号在什么状态下采集数据。

SPI协议定义了四个参数,但核心就是两个:CPOL(时钟极性)和CPHA(时钟相位)。

  • CPOL:决定时钟空闲时的电平。
    • CPOL = 0:空闲时时钟为低电平。
    • CPOL = 1:空闲时时钟为高电平。
  • CPHA:决定数据在时钟的哪个边沿被采样。
    • CPHA = 0:在时钟的第一个边沿(上升沿或下降沿)采样数据。
    • CPHA = 1:在时钟的第二个边沿采样数据。

这两个参数组合起来,就形成了SPI的四种工作模式:

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

为什么会这样设计?其实是为了兼容不同厂家的从设备。有的芯片喜欢在时钟上升沿采样,有的喜欢在下降沿。你只要查一下从设备的数据手册,看看它支持哪种模式,然后把主设备配置成一样的就行了。

重要提醒:主设备和从设备的CPOL和CPHA必须完全一致,否则数据会完全错位。我曾经调试一块LCD屏幕,死活显示不出来,最后发现是SPI模式配置错了。折腾了我整整一个下午。

下面我用一张图来展示模式0和模式3的时序差异,这样更直观一些。

模式0 (CPOL=0, CPHA=0) SCLK MOSI 采样点 模式3 (CPOL=1, CPHA=1) SCLK MOSI 采样点 图例: 时钟边沿 数据采样点

4.4 多从机连接:如何挂载多个设备?

一个SPI主设备可以连接多个从设备。连接方式主要有两种:独立片选菊花链

独立片选是最常用的方式。每个从设备都有一根独立的SS线连接到主设备。主设备想跟谁说话,就把谁的SS线拉低,其他从设备的SS线保持高电平。这样,同一时刻只有一个从设备在跟主设备通信,不会冲突。

我建议你在设计电路时,如果从设备数量不多(比如3-5个),优先使用独立片选。这种方式简单可靠,调试起来也方便。

菊花链则是一种节省引脚的方式。所有从设备共用一根SS线,数据像链条一样从一个从设备传到下一个。这种方式用得比较少,因为延迟会累积,而且协议更复杂。我在一个LED驱动项目中用过一次,说实话,调试过程挺痛苦的。

实际经验:多从机连接时,要注意总线的负载能力。每个从设备的引脚都有寄生电容,挂的从设备多了,信号质量会下降。我曾经在一个板子上挂了8个SPI从设备,结果时钟信号都变形了。后来加了缓冲器才解决。

下面是一个简单的多从机连接示意图:

主设备 (MCU) 从设备1 从设备2 从设备3 SCLK, MOSI, MISO SCLK, MOSI, MISO SCLK, MOSI, MISO SS1 SS2 SS3

好了,关于SPI总线协议的核心内容,咱们就聊到这儿。记住那几个关键点:四根线、主从关系、四种模式、多从机连接。下次你拿到一个SPI设备的 datasheet,应该能很快上手了。


专注资料整理