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的时序差异,这样更直观一些。
4.4 多从机连接:如何挂载多个设备?
一个SPI主设备可以连接多个从设备。连接方式主要有两种:独立片选和菊花链。
独立片选是最常用的方式。每个从设备都有一根独立的SS线连接到主设备。主设备想跟谁说话,就把谁的SS线拉低,其他从设备的SS线保持高电平。这样,同一时刻只有一个从设备在跟主设备通信,不会冲突。
我建议你在设计电路时,如果从设备数量不多(比如3-5个),优先使用独立片选。这种方式简单可靠,调试起来也方便。
菊花链则是一种节省引脚的方式。所有从设备共用一根SS线,数据像链条一样从一个从设备传到下一个。这种方式用得比较少,因为延迟会累积,而且协议更复杂。我在一个LED驱动项目中用过一次,说实话,调试过程挺痛苦的。
实际经验:多从机连接时,要注意总线的负载能力。每个从设备的引脚都有寄生电容,挂的从设备多了,信号质量会下降。我曾经在一个板子上挂了8个SPI从设备,结果时钟信号都变形了。后来加了缓冲器才解决。
下面是一个简单的多从机连接示意图:
好了,关于SPI总线协议的核心内容,咱们就聊到这儿。记住那几个关键点:四根线、主从关系、四种模式、多从机连接。下次你拿到一个SPI设备的 datasheet,应该能很快上手了。