STM32 SPI通信详解与动画演示

STM32 SPI通信详解

一、SPI简介

SPI(Serial Peripheral Interface) 是由Motorola公司提出的一种高速、全双工、同步的串行通信总线。它广泛应用于MCU与各种外设之间的通信,如Flash存储器、LCD显示屏、传感器、AD/DA转换器等。

SPI的主要特点

特性 说明
通信方式 同步串行、全双工
主从模式 支持单主多从
通信速率 可达数十MHz
信号线数 4线(可简化为3线)
数据位宽 通常8位或16位

二、SPI信号线说明

SPI总线由4根信号线组成:

信号线 全称 方向 功能说明
SCK Serial Clock Master → Slave 时钟信号,由主机产生
MOSI Master Out Slave In Master → Slave 主机发送、从机接收
MISO Master In Slave Out Slave → Master 从机发送、主机接收
CS/SS Chip Select / Slave Select Master → Slave 片选信号,低电平有效

信号时序关系

  • CS:片选信号,拉低表示选中从机,开始通信
  • SCK:时钟信号,每个时钟周期传输1位数据
  • MOSI/MISO:数据在时钟边沿进行采样或切换

三、SPI工作模式

SPI有4种工作模式,由 CPOL(时钟极性)CPHA(时钟相位) 两个参数决定:

模式 CPOL CPHA 空闲时SCK 采样边沿
Mode 0 0 0 低电平 上升沿采样
Mode 1 0 1 低电平 下降沿采样
Mode 2 1 0 高电平 下降沿采样
Mode 3 1 1 高电平 上升沿采样

最常用的是Mode 0和Mode 3,大多数SPI外设默认支持这两种模式。

四、SPI通信动画演示

下面是一个交互式的SPI通信动画演示,展示了Mode 0模式下的数据传输过程:

🎮 操作说明:

  • DATA 输入框中输入要发送的十六进制数据(如 A5FF00 等)
  • 点击「发送」按钮开始传输动画
  • 观察波形图中 CS、SCK、MOSI、MISO 四个信号的变化
  • 点击波形区域可添加标记线,方便分析时序
  • 使用右下角 速度按钮 调整动画播放速度(支持0.2x~1.5x)

五、STM32 SPI外设特性

STM32系列MCU内置硬件SPI控制器,主要特性包括:

硬件特性

  • 支持主机/从机模式
  • 支持全双工、半双工、单工通信
  • 数据帧格式:8位或16位
  • 波特率预分频器:2~256分频
  • MSB/LSB先行可配置
  • 支持DMA传输
  • 支持中断和轮询方式

时钟配置

SPI时钟由APB总线时钟分频得到:

1
SPI_CLK = APB_CLK / Prescaler

分频系数可选:2, 4, 8, 16, 32, 64, 128, 256

六、STM32 HAL库SPI配置示例

初始化配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SPI_HandleTypeDef hspi1;

void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER; // 主机模式
hspi1.Init.Direction = SPI_DIRECTION_2LINES; // 全双工
hspi1.Init.DataSize = SPI_DATASIZE_8BIT; // 8位数据
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; // CPOL = 0
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; // CPHA = 0 (Mode 0)
hspi1.Init.NSS = SPI_NSS_SOFT; // 软件片选
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; // MSB先行
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

HAL_SPI_Init(&hspi1);
}

数据发送接收

1
2
3
4
5
6
7
8
9
10
11
12
// 发送数据
uint8_t tx_data = 0xA5;
HAL_SPI_Transmit(&hspi1, &tx_data, 1, HAL_MAX_DELAY);

// 接收数据
uint8_t rx_data;
HAL_SPI_Receive(&hspi1, &rx_data, 1, HAL_MAX_DELAY);

// 全双工收发(同时发送和接收)
uint8_t tx_buf[4] = {0x01, 0x02, 0x03, 0x04};
uint8_t rx_buf[4];
HAL_SPI_TransmitReceive(&hspi1, tx_buf, rx_buf, 4, HAL_MAX_DELAY);

片选控制

1
2
3
4
5
6
7
8
9
10
11
// 软件控制CS引脚
#define SPI_CS_LOW() HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET)
#define SPI_CS_HIGH() HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET)

// 完整的SPI读写流程
void SPI_WriteRead(uint8_t *tx_buf, uint8_t *rx_buf, uint16_t len)
{
SPI_CS_LOW(); // 拉低片选
HAL_SPI_TransmitReceive(&hspi1, tx_buf, rx_buf, len, HAL_MAX_DELAY);
SPI_CS_HIGH(); // 释放片选
}

七、SPI应用注意事项

硬件设计

  1. 信号线长度:高速SPI时,信号线应尽量短,避免阻抗不匹配
  2. 上拉电阻:CS线建议加上拉电阻,防止误触发
  3. 去耦电容:SPI外设电源引脚需加去耦电容

软件配置

  1. 模式匹配:主从设备的CPOL/CPHA必须一致
  2. 速率选择:不要超过从设备支持的最大速率
  3. 时序间隔:某些器件在CS拉低后需要等待一段时间

常见问题

问题 可能原因 解决方案
数据全0xFF MISO线未连接或从机无响应 检查接线和从机供电
数据错位 时钟模式不匹配 核对CPOL/CPHA配置
通信不稳定 速率过高或干扰 降低波特率,检查布线
只能发不能收 GPIO配置错误 检查MISO引脚配置

八、总结

SPI作为一种高速同步串行通信协议,在嵌入式系统中应用广泛。掌握SPI的工作原理和配置方法,对于嵌入式开发者来说非常重要。通过上面的动画演示,相信你对SPI的时序已经有了直观的理解。

相关资源


STM32 SPI通信详解与动画演示
http://example.com/2025/12/04/stm32-spi-introduction/
作者
John Doe
发布于
2025年12月4日
许可协议