1. SPI总线协议基础:SPI的起源、四线制详解、与I2C/UART的对比

1.1 SPI的起源——从摩托罗拉说起

SPI,全称是Serial Peripheral Interface,串行外设接口。它最早由摩托罗拉公司在上世纪80年代提出。说实话,那时候的嵌入式系统里,芯片之间要通信,要么用并口(占引脚多),要么用UART(速度慢)。摩托罗拉为了让自家的微控制器能更快地挂载外设,就设计了这套四线制的同步串行总线。

我最早接触SPI是在做一款工业数据采集卡的时候。当时主控芯片是MC68332,挂了一个SPI接口的ADC。那时候资料少,全靠啃数据手册。嗯,现在回想起来,SPI能活到现在,靠的就是它简单、高速、全双工这三个硬道理。

核心特点:SPI是一种同步、全双工、主从式的串行通信总线。它没有像I2C那样复杂的地址机制,也没有UART那样需要双方约定波特率。说白了,就是主设备主动提供时钟,数据在时钟的边沿上同时收发。

1.2 四线制详解——SCLK、MOSI、MISO、CS

SPI总线通常由四根信号线组成。你想想看,这四根线各司其职,缺一不可。我习惯把它们分成两组:一组是控制线(SCLK、CS),一组是数据线(MOSI、MISO)。

信号线 全称 方向 作用
SCLK Serial Clock 主→从 由主设备产生,决定通信速率
MOSI Master Out Slave In 主→从 主设备发送数据给从设备
MISO Master In Slave Out 从→主 从设备发送数据给主设备
CS Chip Select 主→从 片选信号,低电平有效,选中从设备

SCLK(串行时钟):这是SPI的节拍器。主设备控制时钟的频率,从设备跟着这个节奏走。我在项目中遇到过一个问题:某款传感器对时钟极性有严格要求,当时没仔细看数据手册,结果读出来的数据全是乱的。后来才发现,时钟的极性和相位(CPOL、CPHA)必须和从设备匹配。

MOSI和MISO(数据线):这两根线实现了全双工通信。什么意思?就是主设备在发送数据的同时,也能接收从设备的数据。这一点比I2C强,I2C是半双工的,同一时刻只能一个方向传输。我记得有一次调试一个SPI接口的LCD屏,发现屏幕刷新率上不去,后来把MISO线断开(因为LCD不需要回传数据),改成只发不收,速度立马就上来了。

CS(片选线):这是SPI的“点名”机制。主设备想跟哪个从设备通信,就把对应的CS线拉低。其他没被选中的从设备,会把自己的MISO线置为高阻态,不干扰总线。我曾经犯过一个低级错误:在一条SPI总线上挂了三个从设备,结果CS线没做上拉电阻,上电瞬间所有设备都被选中,总线直接短路。嗯,从那以后,我每个CS引脚都加了一个10kΩ的上拉电阻。

避坑指南:我曾经调试一个SPI Flash驱动,发现写数据总是失败。排查了两天,最后发现是CS信号的时序问题——CS拉低后,需要等待一小段时间(通常几十纳秒)才能开始发时钟。这个等待时间在数据手册里叫"CS Setup Time",很多人容易忽略。

1.3 SPI与I2C/UART的对比

做嵌入式开发,这三类总线你迟早都会碰到。我个人的选择标准很简单:速度优先选SPI,多设备互联选I2C,远距离或简单通信选UART。下面这张表可以帮你快速决策:

特性 SPI I2C UART
通信方式 同步 同步 异步
传输方向 全双工 半双工 全双工
信号线数量 4根(最少3根) 2根(SDA、SCL) 2根(TX、RX)
最大速率 几十MHz(常见) 3.4MHz(高速模式) 几Mbps(取决于硬件)
多设备支持 每设备一根CS线 7位/10位地址 点对点
硬件复杂度
典型应用 ADC/DAC、Flash、LCD 传感器、EEPROM GPS模块、蓝牙模块

为什么SPI比I2C快?说白了,I2C有地址帧、应答帧这些协议开销,而且靠开漏输出和上拉电阻驱动,上升沿慢。SPI没有这些花里胡哨的东西,主设备只管发时钟,数据就在时钟边沿上传输。我做过一个测试:同样读取一个8字节的数据,SPI(10MHz)耗时不到10微秒,I2C(400kHz)要花将近200微秒。差距就是这么明显。

为什么I2C比SPI省引脚?I2C只用两根线就能挂几十个设备,靠的是地址寻址。SPI每增加一个从设备,就要多一根CS线。如果你要挂8个传感器,SPI需要4+7=11根线(SCLK+MOSI+MISO+8根CS),而I2C只需要2根线。所以,引脚紧张的时候,我一般优先考虑I2C。

UART的定位:UART是异步的,不需要时钟线,所以通信双方必须约定好波特率。它天生就是点对点的,没法直接挂多个设备。我通常用UART来连接那些“自带智能”的模块,比如蓝牙模块、4G模块、GPS模块。这些模块内部有MCU,它们把UART当作“命令通道”。

注意事项:SPI虽然快,但抗干扰能力不如差分信号。如果你的板子有强干扰源(比如电机驱动),SPI线最好加屏蔽,或者降低时钟频率。我曾经在一个电机控制板上,SPI时钟跑到20MHz,结果电机一启动,数据就全乱了。后来降到5MHz,问题解决。

1.4 SPI的核心知识体系

下面这张图,是我自己总结的SPI知识框架。你可以把它当作一个“思维导图”,快速把握本章的核心内容。

SPI总线协议基础 起源与历史 摩托罗拉 1980年代 同步、全双工、主从式 四线制详解 SCLK 时钟线 MOSI 主发从收 MISO 主收从发 CS 片选线 与I2C/UART对比 SPI:速度优先 I2C:省引脚 UART:点对点 异步通信 关键参数 CPOL 时钟极性 CPHA 时钟相位 LSB/MSB 先行 典型应用场景 ADC/DAC 转换 Flash 存储器 LCD 显示屏 传感器读取 核心:简单、高速、全双工,适合高性能外设通信

这张图把SPI的起源、四线制、对比、参数和应用串在了一起。我个人觉得,学SPI最关键的还是理解那四根线各自扮演的角色,以及时钟极性和相位这两个概念。搞懂了这些,后面写驱动就是水到渠成的事。


公众号:蓝海资料掘金营,微信deep3321