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

相关推荐
不做无法实现的梦~16 小时前
ros2实现路径规划---nav2部分
linux·stm32·嵌入式硬件·机器人·自动驾驶
熊猫_豆豆21 小时前
同步整流 Buck 降压变换器
单片机·嵌入式硬件·matlab
chenchen000000001 天前
49元能否买到四核性能?HZ-RK3506G2_MiniEVM开发板评测:MCU+三核CPU带来的超高性价比
单片机·嵌入式硬件
孤芳剑影1 天前
反馈环路设计总结
嵌入式硬件·学习
dump linux1 天前
设备树子系统与驱动开发入门
linux·驱动开发·嵌入式硬件
专注VB编程开发20年1 天前
简易虚拟 PLC 服务器-流水线自动化,上位机程序维护升级,西门子PLC仿真
服务器·单片机·自动化·上位机·plc·流水线·工控
LeoZY_1 天前
CH347/339W开源项目:集SPI、I2C、JTAG、SWD、UART、GPIO多功能为一体(3)
stm32·单片机·嵌入式硬件·mcu·开源
chenchen000000001 天前
国产显示芯势力新篇章:内置DDR+四核A35!MY-SSD2351-MINI开发板深度评测
驱动开发·嵌入式硬件
BackCatK Chen1 天前
第13篇:TMC2240 StallGuard4失速检测|寄存器配置+状态读取(保姆级)
单片机·嵌入式硬件·tmc2240·stm32实战·stallguard4·失速检测·电机故障识别
Hello_Embed1 天前
libmodbus STM32 板载串口实验(双串口主从通信)
笔记·stm32·单片机·学习·modbus