目录
[STM32 SPI 常用HAL库函数](#STM32 SPI 常用HAL库函数)
介绍
SPI 是串行外设接口( Serial Peripheral Interface )的缩写,是一种 高速的,全双工,同步的 通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB 的布局上节省空间,提供方便,正是出于这种简单易用的特性,越来越多的芯片集成了这种通信协议,比如 AT91RM9200 。

SPI 总线包含 4 条通讯线,分别为 SS 、 SCK 、 MOSI 、 MISO 。它们的作用介绍如下:
(1) MISO -- Master Input Slave Output ,主设备数据输入,从设备数据输出
(2) MOSI -- Master Output Slave Input ,主设备数据输出,从设备数据输入
(3) SCK -- Serial Clock ,时钟信号,由主设备产生
(4) CS -- Chip Select ,片选信号,由主设备控制
STM32F1 系列芯片有 3 个 SPI 接口。
工作原理
通过操作移位寄存器来实现数据收发

数据手册框图


SPI 工作模式
时钟极性( CPOL ) :
没有数据传输时时钟线的空闲状态电平
0 : SCK 在空闲状态保持低电平
1 : SCK 在空闲状态保持高电平
时钟相位( CPHA ) :
时钟线在第几个时钟边沿采样数据
0 : SCK 的第一(奇数)边沿进行数据位采样,数据在第一个时钟边沿被锁存
1 : SCK 的第二(偶数)边沿进行数据位采样,数据在第二个时钟边沿被锁存

模式 0 和模式 3 最常用。
以模式0为例展开介绍,其余的通过时序图举一反三。
时序关键点
空闲状态
时钟线(SCLK)保持低电平,从设备选择线(SS/CS)为高电平(未选中状态)。当SS线拉低时,通信开始。
数据采样与切换
数据在SCLK的上升沿被采样(读取),在下降沿切换(输出)。主机和从机在下降沿准备数据,在随后的上升沿锁存数据。
数据传输顺序
每次传输以字节为单位,MSB(最高位)或LSB(最低位)优先取决于配置。数据在SS线有效期间连续传输,无额外间隔。
模式0时序图:

起始条件
SS线从高电平拉低,标志传输开始。SCLK保持低电平(CPOL=0)。
数据位传输
主机在SCLK下降沿切换MOSI数据,从机在下降沿切换MISO数据。双方在上升沿读取数据线状态。
结束条件
SS线从低电平拉高,SCLK返回空闲低电平状态。
模式3时序图:

SPI****寄存器及库函数介绍
控制寄存器1





控制寄存器2
重点关注6、7位

状态寄存器
重点关注0、1位


数据寄存器

STM32 SPI 常用HAL库函数
SPI初始化函数
HAL_SPI_Init(SPI_HandleTypeDef *hspi)用于初始化SPI外设,参数为指向
SPI_HandleTypeDef结构体的指针。该结构体包含SPI的配置信息,如模式、时钟极性、数据大小等。
示例:
c
SPI_HandleTypeDef hspi1;
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
HAL_SPI_Init(&hspi1);
SPI数据传输函数
HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)发送指定长度的数据。参数包括SPI句柄、数据缓冲区指针、数据长度和超时时间(毫秒)。
示例:
c
uint8_t txData[] = {0xAA, 0xBB, 0xCC};
HAL_SPI_Transmit(&hspi1, txData, 3, 100);
HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)接收指定长度的数据。参数与发送函数类似。
示例:
c
uint8_t rxData[3];
HAL_SPI_Receive(&hspi1, rxData, 3, 100);
HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)同时发送和接收数据。适用于全双工模式。
示例:
c
uint8_t txData[] = {0xAA, 0xBB, 0xCC};
uint8_t rxData[3];
HAL_SPI_TransmitReceive(&hspi1, txData, rxData, 3, 100);
SPI中断和DMA函数
HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)通过中断方式发送数据。
HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)通过中断方式接收数据。
HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)通过中断方式同时发送和接收数据。
HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)通过DMA方式发送数据。
HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)通过DMA方式接收数据。
HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)通过DMA方式同时发送和接收数据。