1. SPI FIFO的本质与核心价值
在嵌入式系统开发中,SPI(Serial Peripheral Interface)总线是最常用的通信接口之一。但很多开发者在使用SPI时都会遇到一个共同痛点:当CPU与外设速度不匹配时,要么频繁中断导致效率低下,要么数据丢失造成通信失败。这正是SPI FIFO要解决的核心问题。
SPI FIFO本质上是一个硬件实现的先进先出(First In First Out)缓冲区。它就像快递柜的寄存格,发送时CPU可以一次性放入多个包裹(数据),SPI控制器会按顺序自动派送;接收时外设发来的包裹先暂存在格子中,等CPU有空时再批量取走。这种机制完美解决了传统SPI通信中"来一件处理一件"的低效模式。
提示:FIFO深度是指缓冲区能暂存的数据量,比如8级FIFO表示可以缓存8字节数据。这个参数直接影响传输效率。
我在STM32项目实测中发现,启用8级FIFO后,传输1KB数据的CPU中断次数从1024次降低到128次(假设阈值为8),效率提升近8倍。具体优势体现在三个方面:
-
速度缓冲器:当SPI时钟设为36MHz时,每个字节传输只需约0.22μs,而普通Cortex-M内核的指令周期在0.1μs左右。没有FIFO时,CPU几乎无法及时响应每个字节的中断。
-
批量处理专家:对SPI Flash进行页编程时,传统方式需要256次中断处理,而使用FIFO后只需32次(8级FIFO),大大减少了上下文切换开销。
-
安全卫士:在电机控制等实时性要求高的场景中,FIFO可以防止因CPU暂时繁忙导致的关键数据丢失。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. SPI FIFO的硬件实现剖析
2.1 典型硬件架构
以STM32F4系列为例,其SPI控制器的FIFO模块包含以下关键部件:
- 发送缓冲区:8字节的移位寄存器组,CPU写入的数据会暂存于此
- 接收缓冲区:同样8字节容量,存储从MOSI线收到的数据
- 状态寄存器:包含TXE(发送空)、RXNE(接收非空)等标志位
- 阈值控制器:可配置触发中断或DMA请求的阈值点

(注:此处应为SPI FIFO硬件架构示意图,实际使用时需替换为具体图示)
2.2 关键寄存器详解
理解这些寄存器是掌握FIFO编程的关键:
| 寄存器位 | 名称 | 功能描述 | 典型应用场景 |
|---|---|---|---|
| SPI_SR.TXE | 发送空 | 1表示发送FIFO完全空 | 判断传输是否完成 |
| SPI_SR.TXFNF | 发送未满 | 1表示可继续写入数据 | 发送数据前的检查 |
| SPI_SR.RXNE | 接收非空 | 1表示有数据可读 | 接收数据前的检查 |
| SPI_SR.RXFF | 接收满 | 1表示接收FIFO已达阈值 | DMA请求触发条件 |
| SPI_CR2.FRXTH | 接收阈值 | 1=1字节阈值,0=4字节阈值 | 配置接收灵敏度 |
在NXP的Kinetis系列MCU中,这些标志位的命名略有不同,比如发送未满标志叫SPI_SR_TXFULL的反相,使用时需要特别注意。
3. FIFO配置与编程实战
3.1 初始化配置要点
下面是一个完整的STM32 SPI FIFO初始化示例,包含关键注释:
c复制void SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SP
