1. SPI协议深度解析:从起源到实战
大家好,我是你们的SPI课程讲师。今天我们来聊聊SPI协议——这个在嵌入式世界里无处不在的串行通信接口。
说实话,我刚开始做数字IC设计那会儿,SPI给我的感觉就是「四个信号线,一主多从,简单得很」。但真正在项目里踩过几次坑之后,才发现这玩意儿远没有表面看起来那么简单。时钟极性和相位搞反了,数据就全乱了;多从机配置没想清楚,板子调三天都跑不通。
所以这一章,咱们把SPI协议从头到尾掰开揉碎了讲。你想想看,搞懂这些基础,后面做控制器设计和验证才能心里有底。
1.1 SPI总线起源:Motorola的经典之作
SPI的全称是Serial Peripheral Interface,串行外设接口。它最早由Motorola公司在上世纪80年代推出,初衷很简单——给微控制器和外围芯片之间找个高效、简单的通信方式。
那时候的并行接口虽然快,但引脚太多,成本高。SPI只用4根线,就能搞定全双工通信,而且速度可以做到很高。我记得第一次在FPGA上实现SPI控制器时,看到示波器上那干净利落的波形,心里还挺感慨:这设计,真经典。
SPI不是像I2C那样有严格标准的协议,它更像是一种「事实标准」。各家芯片厂商的实现大同小异,但细节上各有千秋。嗯,这里要注意:正因为没有统一的标准,我们做设计时更要吃透原理,不能死搬硬套。
1.2 4线制工作原理:SCK/MOSI/MISO/SS
SPI总线通常用4根信号线,咱们一个一个来看:
- SCK (Serial Clock):串行时钟,由主机产生。说白了就是同步时钟信号,所有数据都在这个时钟的边沿上采样或变化。
- MOSI (Master Out Slave In):主机输出,从机输入。主机发送数据给从机的通道。
- MISO (Master In Slave Out):主机输入,从机输出。从机回复数据给主机的通道。
- SS (Slave Select):从机选择信号,也叫片选信号。低电平有效,主机通过拉低某个从机的SS来选中它。
这里有个关键点:SPI是全双工通信。什么意思?就是主机发数据的同时,从机也在发数据。你发一个字节,从机同时回一个字节。我在项目中遇到过不少新手,以为SPI是「一问一答」的轮询方式,其实不是——收发是同时进行的。
核心要点:SPI的每次数据传输,主机和从机都在同时移位一个字节。主机通过MOSI发送数据,从机通过MISO回复数据。如果你只关心主机发出去的数据,那从机回复的数据可以忽略,但硬件上它确实在发。
举个简单的例子:主机想读从机的一个寄存器。通常的做法是,主机先发一个命令字节(告诉从机要读哪个地址),然后主机再发一个「空字节」(通常是0x00或0xFF),同时从机在MISO上把数据送回来。你看,两次传输都是全双工的。
1.3 时钟极性(CPOL)与时钟相位(CPHA):4种模式详解
这部分是SPI协议里最容易搞混的地方,也是我当年踩坑最多的点。咱们慢慢说。
CPOL和CPHA是两个配置位,它们共同决定了数据采样的时机:
- CPOL (Clock Polarity):时钟极性。决定SCK空闲时的电平状态。
- CPOL = 0:空闲时SCK为低电平
- CPOL = 1:空闲时SCK为高电平
- CPHA (Clock Phase):时钟相位。决定数据在哪个时钟边沿被采样。
- CPHA = 0:在SCK的第一个边沿采样数据
- CPHA = 1:在SCK的第二个边沿采样数据
组合起来就是4种模式:
| 模式 | CPOL | CPHA | 空闲时钟电平 | 数据采样边沿 |
|---|---|---|---|---|
| 模式0 | 0 | 0 | 低电平 | 上升沿(第一个边沿) |
| 模式1 | 0 | 1 | 低电平 | 下降沿(第二个边沿) |
| 模式2 | 1 | 0 | 高电平 | 下降沿(第一个边沿) |
| 模式3 | 1 | 1 | 高电平 | 上升沿(第二个边沿) |
我个人习惯把模式0和模式3记成「上升沿采样」,模式1和模式2记成「下降沿采样」。但更准确的说法是:CPHA决定采样边沿是第一个还是第二个,CPOL决定这个边沿是上升还是下降。
避坑指南:我曾经在一个项目中,把从机的手册看错了,以为它支持模式0,结果实际是模式3。板子调了两天,波形怎么看都对,但数据就是不对。最后用逻辑分析仪一抓,才发现采样边沿差了半个时钟周期。从那以后,我每次选模式都会先看从机手册里那个时序图,确认采样边沿和时钟空闲电平。
为什么会这样?因为很多从机芯片的时序图画得不够清晰,或者标注方式不同。我的建议是:不要只看文字描述,一定要看时序图。图上会明确标出数据在哪个边沿被采样,哪个边沿变化。
1.4 多从机配置:菊花链与独立片选
实际项目中,一个主机往往要挂多个从机。SPI支持两种多从机连接方式:独立片选和菊花链。
1.4.1 独立片选(Independent Chip Select)
这是最常见的方式。每个从机都有自己的SS引脚,主机通过拉低某个从机的SS来选中它。其他从机的SS保持高电平,它们的MISO引脚处于高阻态,不会干扰总线。
优点:简单、灵活,每个从机独立操作。
缺点:从机数量多时,主机需要很多GPIO来充当SS信号。比如挂8个从机,就需要8个SS引脚。
我在项目中用过这种方式,挂4个传感器,每个传感器一个片选。代码写起来很直观,就是主机引脚有点紧张。
1.4.2 菊花链(Daisy Chain)
菊花链方式下,所有从机共享SCK和SS,但MOSI和MISO在从机之间串联起来。主机的MOSI连到第一个从机的MOSI输入,第一个从机的MISO连到第二个从机的MOSI输入,以此类推,最后一个从机的MISO连回主机的MISO。
这种方式的好处是:只需要一个SS信号,就能控制多个从机。但代价是:数据传输有延迟。主机发一个字节,要经过N个从机才能回到主机。而且所有从机必须同时被选中,不能单独操作某个从机。
个人经验:菊花链适合那些「批量更新数据」的场景,比如多个DAC同时更新输出值。但如果你需要频繁读写单个从机,独立片选会更方便。我一般只在从机数量特别多、主机引脚不够用的时候才考虑菊花链。
1.5 知识体系总览
下面这张图,是我画的本章节知识结构。你可以把它当作一个「思维导图」,快速回顾SPI协议的核心内容。
这张图把SPI协议的四个核心维度串起来了。从起源到4线制,从时钟模式到多从机配置,每一块都是后面做控制器设计和验证的基础。
好了,这一章的内容就到这里。SPI协议看起来简单,但里面的细节真不少。我个人建议你找个逻辑分析仪,实际抓几个SPI波形看看,把CPOL和CPHA的四种模式都跑一遍。纸上得来终觉浅,绝知此事要躬行嘛。