1. SPI通信协议深度解析
SPI(Serial Peripheral Interface)是一种高速、全双工、同步的串行通信协议,广泛应用于嵌入式系统中连接微控制器和各种外设。作为一位嵌入式开发工程师,我经常使用SPI接口与各类传感器、存储芯片通信。下面我将结合STM32平台,详细剖析SPI的工作原理和实际应用。
1.1 SPI总线物理结构
SPI总线采用主从架构,通常由一个主设备(Master)和一个或多个从设备(Slave)组成。物理连接包含四条信号线:
- MOSI(Master Out Slave In):主设备数据输出,从设备数据输入
- MISO(Master In Slave Out):主设备数据输入,从设备数据输出
- SCK(Serial Clock):由主设备产生的时钟信号
- NSS(Negative Slave Select):从设备片选信号(低电平有效)
在实际电路设计中,我通常会注意以下几点:
- 信号线长度不宜过长,一般控制在10cm以内
- 高频应用时建议添加33Ω串联匹配电阻
- 对于长距离传输,可以考虑使用差分SPI(如ADI的ADSP-CM40x系列支持)
1.2 SPI通信时序详解
SPI通信的核心是时钟同步的数据传输。每个时钟周期完成一位数据的传输,通信流程分为三个阶段:
- 建立通信:主设备拉低目标从设备的NSS信号线
- 时钟同步:主设备通过SCK提供时钟信号
- 数据传输:在时钟边沿触发数据采样
数据传输有两种基本模式:
- 模式0(CPOL=0, CPHA=0):时钟空闲为低电平,在上升沿采样
- 模式3(CPOL=1, CPHA=1):时钟空闲为高电平,在下降沿采样
经验分享:不同厂商设备可能默认使用不同模式,比如NOR Flash常用模式0/3,而某些传感器可能使用模式1/2。务必查阅器件手册确认。
1.3 SPI配置参数解析
配置SPI接口时需要关注以下关键参数:
| 参数 | 选项 | 说明 |
|---|---|---|
| 数据宽度 | 8bit/16bit | 决定每次传输的数据单位 |
| 波特率 | 分频系数 | 时钟频率=主频/分频系数 |
| 传输顺序 | MSB/LSB | 高位先行或低位先行 |
| NSS管理 | 硬件/软件 | 硬件自动控制或手动控制 |
在STM32中,这些参数通过SPI_InitTypeDef结构体配置:
c复制SPI_InitTypeDef SPI_InitStruct = {
.SPI_Direction = SPI_Direction_2Lines_FullDuplex,
.SPI_Mode = SPI_Mode_Master,
.SPI_DataSize = SPI_DataSize_8b,
.SPI_CPOL = SPI_CPOL_Low,
.SPI_CPHA = SPI_CPHA_1Edge,
.SPI_NSS = SPI_NSS_Soft,
.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64,
.SPI_FirstBit = SPI_FirstBit_MSB
};
2. STM32 SPI外设驱动开发
2.1 GPIO引脚配置
以STM32F103的SPI1为例,需要配置以下引脚:
c复制// PB3 - SCK, PB4 - MISO, PB5 - MOSI, PA15 - NSS
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 使能GPIO时钟
RCC_APB2Peri
