1. SPI协议概述:SPI是什么、SPI的起源与发展、SPI与I2C/UART的对比

1.1 SPI到底是什么?

SPI,全称是Serial Peripheral Interface,串行外设接口。说白了,就是让主控芯片和外围设备之间快速交换数据的一种通信方式。

我个人习惯把它叫做“四线制同步串行总线”。为什么叫四线制?因为它至少需要四根线:SCLK(时钟)、MOSI(主出从入)、MISO(主入从出)、SS(片选)。你想想看,这四根线各司其职,分工非常明确。

我在项目中遇到过不少刚入行的工程师,一上来就问:“SPI和I2C到底选哪个?”其实这个问题没有标准答案,关键看你的应用场景。SPI最大的特点就是快,而且全双工——也就是说,发送和接收可以同时进行。

核心要点:SPI是一种同步、全双工、主从架构的串行通信协议。它的传输速率通常可以达到几十MHz,远高于I2C和UART。

1.2 SPI的起源与发展

SPI最早是由摩托罗拉公司在20世纪80年代提出的。我记得当时摩托罗拉推出MC68000系列处理器时,配套的SPI接口就一起问世了。嗯,这里要注意,SPI从来就不是一个国际标准,它更像是一个“事实标准”——大家都照着摩托罗拉的做法来。

为什么SPI能活到现在?原因很简单:它太实用了。从早期的EEPROM、ADC/DAC,到现在的传感器、显示屏、无线模块,几乎所有的嵌入式设备都在用SPI。

我曾经在一个老项目中看到过用SPI连接多个温度传感器的设计。当时那个项目用的是8位单片机,主频只有16MHz,但SPI跑到了8MHz,数据传输一点问题都没有。换成I2C的话,估计得卡死。

发展到现在,SPI已经衍生出不少变种:

  • 标准SPI:4线制,最常用
  • 双线SPI:有些低功耗场景会省掉MISO或MOSI
  • QSPI:四线SPI,用于高速Flash存储器
  • DSPI:双数据速率SPI,时钟上升沿和下降沿都采样

个人经验:如果你在做低功耗产品,可以考虑用双线SPI。但要注意,双线SPI只能半双工通信,传输效率会打折扣。

1.3 SPI与I2C、UART的对比

很多初学者会纠结这三种协议的区别。我直接给你一张对比表,一目了然:

特性 SPI I2C UART
线数 4线(最少3线) 2线(SDA+SCL) 2线(TX+RX)
通信方式 全双工 半双工 全双工
同步/异步 同步(有时钟) 同步(有时钟) 异步(无时钟)
最大速率 几十MHz 几MHz(标准模式100kHz) 几Mbps
从设备数量 每个从设备需独立片选 最多127个(7位地址) 点对点
硬件复杂度 中等
典型应用 高速ADC/DAC、Flash、显示屏 传感器、EEPROM、RTC GPS模块、蓝牙模块、调试口

你看这张表,SPI在速率上完胜。但代价是什么?线多。每增加一个从设备,就要多一根片选线。我曾经在一个项目里接了8个SPI设备,光片选线就占了8个GPIO,板子布线的时候真是头疼。

再说说I2C。I2C只有两根线,可以挂很多设备,但速度慢。我记得有一次调试一个I2C的触摸屏,数据量稍微大一点,屏幕就卡顿。后来换成SPI,问题立刻解决。

UART呢?它是最简单的,两根线就能点对点通信。但UART有个致命问题:没有时钟线,收发双方必须约定好波特率。如果晶振不准或者环境干扰大,就容易丢数据。我在调试GPS模块时就遇到过,波特率设置不对,数据全是乱码。

避坑指南:我曾经在一个项目中用SPI连接多个从设备,结果发现片选信号有毛刺,导致设备误触发。后来加了上拉电阻和去耦电容才解决。所以,SPI的片选信号一定要处理好,不然会出各种奇怪的问题。

1.4 什么时候选SPI?

根据我的经验,以下几种场景优先考虑SPI:

  • 需要高速数据传输:比如驱动TFT显示屏、读写Flash存储器
  • 需要全双工通信:比如音频编解码器、高速ADC
  • 从设备数量少:一般不超过3-4个,否则GPIO不够用
  • 对实时性要求高:SPI没有I2C的仲裁机制,不会出现总线冲突

反过来,如果设备数量多、速率要求不高、想省GPIO,那就选I2C。如果只是简单的点对点通信,UART就够用了。

我的建议:新手做项目时,如果拿不准选哪个,可以先看外设的数据手册。手册里通常会给出推荐的接口类型。比如Flash芯片,99%都是用SPI;而温湿度传感器,大部分用I2C。

1.5 小结

SPI是一种高速、全双工、主从架构的串行通信协议。它由摩托罗拉提出,虽然没有成为国际标准,但凭借其出色的性能,在嵌入式领域站稳了脚跟。与I2C和UART相比,SPI的优势在于速度和全双工能力,劣势在于线数多、扩展性差。

下一章,我会详细讲解SPI的四根信号线——SCLK、MOSI、MISO、SS——到底是怎么工作的。到时候我会结合示波器的波形图,让你看得明明白白。