通信接口介绍: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方式同时发送和接收数据。

相关推荐
悠哉悠哉愿意7 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
Lester_11017 天前
STM32霍尔传感器输入口设置为复用功能输入口时,还能用GPIO函数直接读取IO的状态吗
stm32·单片机·嵌入式硬件·电机控制
LCG元7 天前
低功耗显示方案:STM32L0驱动OLED,动态波形绘制与优化
stm32·嵌入式硬件·信息可视化
三佛科技-187366133977 天前
120W小体积碳化硅电源方案(LP8841SC极简方案12V10A/24V5A输出)
单片机·嵌入式硬件
z20348315207 天前
STM32F103系列单片机定时器介绍(二)
stm32·单片机·嵌入式硬件
古译汉书7 天前
【IoT死磕系列】Day 7:只传8字节怎么控机械臂?学习工业控制 CANopen 的“对象字典”(附企业级源码)
数据结构·stm32·物联网·http
Alaso_shuang7 天前
STM32 核心输入、输出模式
stm32·单片机·嵌入式硬件
脚后跟7 天前
AI助力嵌入式物联网项目全栈开发
嵌入式硬件·物联网·ai编程
2501_918126917 天前
stm32死锁是怎么实现的
stm32·单片机·嵌入式硬件·学习·个人开发
z20348315207 天前
STM32F103系列单片机定时器介绍(一)
stm32·单片机