通信接口介绍:SPI

目录

介绍

工作原理

SPI工作模式

时序关键点

SPI寄存器及库函数介绍

控制寄存器1

控制寄存器2

状态寄存器

数据寄存器

[STM32 SPI 常用HAL库函数](#STM32 SPI 常用HAL库函数)

SPI初始化函数

SPI数据传输函数

SPI中断和DMA函数

介绍

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时序图:

  1. 起始条件

    SS线从高电平拉低,标志传输开始。SCLK保持低电平(CPOL=0)。

  2. 数据位传输

    主机在SCLK下降沿切换MOSI数据,从机在下降沿切换MISO数据。双方在上升沿读取数据线状态。

  3. 结束条件

    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方式同时发送和接收数据。

相关推荐
菥蓂寻生4 小时前
STM32移植到GD32中以105为例
stm32·单片机·嵌入式硬件
Zw-awa7 小时前
让屏幕动起来:OLED动画效果,丝滑光标、帧动画和一只贪吃蛇
stm32
橘为己有44114 小时前
51单片机:定时/计数器
单片机·51单片机
杯子不吃紫菜16 小时前
LangGraph 体系实战(下):中断恢复、流式、子图与设计模式
单片机·嵌入式硬件·设计模式
qq_4480111617 小时前
中断服务函数简介
嵌入式硬件
Risehuxyc17 小时前
STM32程序逻辑---入口函数逻辑和NVIC嵌套向量中断控制器初始化
stm32·单片机·嵌入式硬件
【 STM32开发 】17 小时前
CubeMX+STM32】SD卡U盘实现__USB+FATFS (F103 篇)
stm32·单片机·嵌入式硬件
jianqiang.xue17 小时前
3倍向量算力:Arm给最小MCU装上本地AI
arm开发·人工智能·单片机
蜀黍@猿19 小时前
ARM 汇编入门(十二):MMU、页表与虚拟内存全解析
汇编·arm开发·stm32·mcu
无敌最俊朗-1 天前
【电感专题2:电感的感抗、电路的阻抗、电流的滞后】
单片机·嵌入式硬件·元器件·电感