STM32 HAL库 STM32CubeMX -- SPI


一、SPI 协议简介

SPI (Serial Peripheral Interface)协议,即串行外围设备接口,是一种高速全双工的通信总线。

它被广泛地使用在ADC、LCD 等设备与MCU 间,要求通讯速率较高的场合。

SPI 物理层

物理层

SPI 通讯使用3 条总线及片选线,3 条总线分别为SCK、MOSI、MISO,片选线为SS(CS),它们的作用介绍如下:

(1) SS( Slave Select): 从设备选择信号线,常称为片选信号线,也称为NSS、CS,以下用NSS 表示。低电平表示选中

当有多个SPI 从设备与SPI 主机相连时,设备的其它信号线SCK、MOSI 及MIS O 同时并联到相同的SPI 总线上,即无论有多少个从设备,都共同只使用这3 条总线;
而每个从设备都有独立的这一条NSS 信号线,本信号线独占主机的一个引脚,即有多少个从设备,就有多少条片选信号线。

I2C 协议中通过设备地址来寻址、选中总线上的某个设备并与其进行通讯;而SPI 协议中没有设备地址,它使用NSS 信号线来寻址,当主机要选择从设备时,把该从设备的NSS 信号线设置为低电平,该从设备即被选中,即片选有效,接着主机开始与被选中的从设备进行SPI 通讯。所以SPI 通讯以NSS 线置低电平为开始信号,以NSS 线被拉高作为结束信号。

(2) SCK (Serial Clock): 时钟信号线,用于通讯数据同步。

它由通讯主机产生,决定了通讯的速率,不同的设备支持的最高时钟频率不一样,如STM32 的SPI 时钟频率最大为fpclk/2,两个设备之间通讯时,通讯速率受限于低速设备。

(3) MOSI (Master Output,Slave Input): 主设备输出/从设备输入引脚。

主机的数据从这条信号线输出,从机由这条信号线读入主机发送的数据,即这条线上数据的方向为主机到从机。

(4) MISO(Master Input,,Slave Output): 主设备输入/从设备输出引脚。

主机从这条信线读入数据,从机的数据由这条信号线输出到主机,即在这条线上数据的方向为从机到主机。

SPI 协议层

SPI 协议定义了通讯的起始和停止信号、数据有效性、时钟同步等环节。

SPI 基本通讯过程

SPI 基本通讯过程

这是一个主机的通讯时序。

NSS、SCK、MOSI 信号都由主机控制产生,而MISO 的信号由从机产生,主机通过该信号线读取从机的数据。MOSI 与MISO 的信号只在NSS 为低电平的时候才有效,在SCK 的每个时钟周期MOSI 和MISO 传输一位数据。
以上通讯流程中包含的各个信号分解如下:

通讯的起始和停止信号 :

标号(1)处,NSS 信号线由高变低,是SPI 通讯的起始信号。NSS 是每个从机各自独占的信号线,当从机在自己的NSS 线检测到起始信号后,就知道自己被主机选中了,开始准备与主机通讯。
标号(6)处,NSS 信号由低变高,是SPI 通讯的停止信号,表示本次通讯结束,从机的选中状态被取消。

数据有效性:

SPI 使用MOSI 及MISO 信号线来传输数据,使用SCK 信号线进行数据同步。
MOSI 及MISO 数据线在SCK 的每个时钟周期传输一位数据,且数据输入输出是同时进行的。数据传输时,MSB先行或LSB 先行并没有作硬性规定,但要保证两个SPI 通讯设备之间使用同样的协定,一般都会采用上图中的MSB 先行模式。

标号(3)处,MOSI 及MISO 的数据在SCK 的上升沿期间变化输出,在SCK 的下降沿时被采样。即在SCK 的下降沿时刻,MOSI 及MISO 的数据有效,高电平时表示数据“1”,为低电平时表示数据“0”。在其它时刻,数据无效,MOSI 及MISO 为下一次表示数据做准备。

SPI 每次数据传输可以8 位或16 位为单位,每次传输的单位数不受限制。

CPOL/CPHA 及通讯模式:

上面讲述的时序只是SPI 中的其中一种通讯模式,SPI 一共有四种通讯模式,它们的主要区别是总线空闲时SCK 的时钟状态以及数据采样时刻。

为方便说明,在此引入“时钟极性CPOL”和“时钟相位CPHA”的概念。
时钟极性CPOL 是指SPI 通讯设备处于空闲状态时,SCK 信号线的电平信号(即SPI 通讯开始前、NSS 线为高电平时SCK 的状态)。

CPOL=0 时,SCK 在空闲状态时为低电平,CPOL=1 时,则相反。时钟相位CPHA 是指数据的采样的时刻,当CPHA=0 时,MOSI 或MISO 数据线上的信号将会在SCK 时钟线的“奇数边沿”被采样。

当CPHA=1 时,数据线在SCK 的“偶数边沿”采样。就是下图

S

由CPOL 及CPHA 的不同状态,SPI 分成了四种模式,主机与从机需要工作在相同的模式下才可以正常通讯,实际中采用较多的是 “模式0”与“模式3”

SPI模式CPOLCPHA空闲时SCK 时钟采样时刻
000低电平奇数边沿
101低电平偶数边沿
210高电平奇数边沿
311高电平偶数边沿

二、SPI 的架构

STM32 的SPI 外设可用作通讯的主机及从机,支持最高的SCK 时钟频率为fpclk/2 (STM32F103 型号的芯片默认f:sub:pclk1 为36MHz,fpclk2 为72MHz),完全支持SPI 协议的4 种模式,数据帧长度可设置为8 位或16 位,可设置数据MSB 先行或LSB 先行。

它还支持双线全双工、双线单向以及单线模式。其中双线单向模式可以同时使用MOSI 及MISO 数据线向一个方向传输数据,可以加快一倍的传输速度。而单线模式则可以减少硬件接线,当然这样速率会受到影响。

SPI的架构

通讯引脚

SPI 的所有硬件架构都从上图中左侧MOSI、MISO、SCK 及NSS 线展开的。

STM32 芯片有多个SPI 外设,它们的SPI 通讯信号引出到不同的GPIO 引脚上,使用时必须配置到这些指定的引脚。

引脚SPI 编号
SPI1SPI2SPI3
NSSPA4PB12PA15 下载口的TDI
CLKPA5PB13PB3 下载口的TDO
MISOPA6PB14PB4下载口的NTRST
MOSIPA7PB15PB5

其中SPI1 是APB2 上的设备,最高通信速率达36Mbtis/s,SPI2、SPI3 是APB1 上的设备,最高通信速率为18Mbits/s。

除了通讯速率,在其它功能上没有差异。其中SPI3 用到了下载接口的引脚,这几个引脚默认功能是下载,第二功能才是IO 口,如果想使用SPI3 接口,则程序上必须先禁用掉这几个IO 口的下载功能。一般在资源不是十分紧张的情况下,这几个IO 口是专门用于下载和调试程序,不会复用为SPI3。

时钟控制逻辑

SCK 线的时钟信号,由波特率发生器根据“控制寄存器CR1”中的BR[0:2] 位控制,该位是对fpclk时钟的分频因子,对fpclk 的分频结果就是SCK 引脚的输出时钟频率,计算方法见下表。

BR[0:2]分频结果(SCK 频率)BR[0:2]分频结果(SCK 频率)
000fpclk/2100fpclk/32
001fpclk/4101fpclk/64
010fpclk/8110fpclk/128
011fpclk/16111fpclk/256

其中的fpclk 频率是指SPI 所在的APB 总线频率,APB1 为fpclk1,APB2 为fpckl2。

数据控制逻辑

SPI 的MOSI 及MISO 都连接到数据移位寄存器上,数据移位寄存器的数据来源及目标接收、发送缓冲区以及MISO、MOSI 线。

当向外发送数据的时候,数据移位寄存器以“发送缓冲区”为数据源,把数据一位一位地通过数据线发送出去;当从外部接收数据的时候,数据移位寄存器把数据线采样到的数据一位一位地存储到“接收缓冲区”中。通过写SPI 的“数据寄存器DR”把数据填充到发送缓冲区中,通讯读“数据寄存器DR”,可以获取接收缓冲区中的内容。

其中数据帧长度可以通过“控制寄存器CR1”的“DFF 位”配置成8 位及16 位模式;配置“LSBFIRST 位”可选择MSB 先行还是LSB 先行。

整体控制逻辑

整体控制逻辑负责协调整个SPI 外设,控制逻辑的工作模式根据我们配置的“控制寄存器(CR1/CR2)”的参数而改变,基本的控制参数包括前面提到的SPI 模式、波特率、LSB 先行、主从模式、单双向模式等等。

在外设工作时,控制逻辑会根据外设的工作状态修改“状态寄存器(SR)”,我们只要读取状态寄存器相关的寄存器位,就可以了解SPI 的工作状态了。

除此之外,控制逻辑还根据要求,负责控制产生SPI 中断信号、DMA 请求及控制NSS 信号线。

实际应用中,我们一般不使用STM32 SPI 外设的标准NSS 信号线,而是更简单地使用普通的GPIO,软件控制它的电平输出,从而产生通讯起始和停止信号。

三、通讯过程

STM32 使用SPI 外设通讯时,在通讯的不同阶段它会对“状态寄存器SR”的不同数据位写入参数,通过读取这些寄存器标志来了解通讯状态。

通讯过程

主模式收发流程及事件说明如下:

(1) 控制NSS 信号线,产生起始信号;

(2) 把要发送的数据写入到“数据寄存器DR”中,该数据会被存储到发送缓冲区;

(3) 通讯开始,SCK 时钟开始运行。MOSI 把发送缓冲区中的数据一位一位地传输出去;MISO则把数据一位一位地存储进接收缓冲区中;

(4) 当发送完一帧数据的时候,“状态寄存器SR”中的“TXE 标志位”会被置1,表示传输完一帧,发送缓冲区已空;类似地,当接收完一帧数据的时候,“RXNE 标志位”会被置1,表示传输完一帧,接收缓冲区非空;

(5) 等待到“TXE 标志位”为1 时,若还要继续发送数据,则再次往“数据寄存器DR”写入数据即可;等待到“RXNE 标志位”为1 时,通过读取“数据寄存器DR”可以获取接收缓冲区中的内容。

假如我们使能了TXE 或RXNE 中断,TXE 或RXNE 置1 时会产生SPI 中断信号,进入同一个中断服务函数,到SPI 中断服务程序后,可通过检查寄存器位来了解是哪一个事件,再分别进行处理。也可以使用DMA 方式来收发“数据寄存器DR”中的数据。

四、STM32Cube MX配置

SPI

Mode: 模式
Full-Duplex Master 主机全双工模式
Full-Duplex Slave 从机全双工模式
Half-Duplex Master 主机半双工模式
Half-Duplex Slave 从机半双工模式
Receive Only Master 只接收主机模式
Receive Only Slave 只接收从机模式
Transmit Only Master 只发送从机模式

Hardware NSS Signal : 硬件NSS信号

可以选择这里的固定引脚使能,也可以使用其他IO口接到外设的NSS上进行代替;

其中SIP1的片选NSS : SPI1_NSS(PA4)
其中SIP2的片选NSS : SPI2_NSS(PB12)

如果片选引脚没有连接硬件NSS信号,则需要选择软件片选

NSS管脚就是片选信号,作为主设备NSS管脚为高电平,从设备NSS管脚为低电平。

当NSS管脚为低电平时,该SPI设备被选中,可以和主设备进行通信。

在STM32中,每个SPI控制器的NSS信号引脚都具有两种功能,即输入和输出。输入就是NSS管脚接收外界的信号。输出就是将NSS的信号发给外界。

对于NSS的输入,分为软件输入和硬件输入
软件输入:
NSS分为内部管脚和外部管脚,通过设置spi_cr1寄存器的ssm位和ssi位都为1可以设置NSS管脚为软件输入模式且内部管脚提供的电平为高电平,其中SSM位为使能软件输入位。SSI位为设置内部管脚电平位。同理通过设置SSM和SSI位1和0则此时的NSS管脚为软件输入模式但内部管脚提供的电平为0。若从设备是一个其他的带有spi接口的芯片,并不能选择NSS管脚的方式,则可以有两种办法,一种是将NSS管脚直接接低电平。另一种就是通过主设备的任何一个gpio口去输出低电平选中从设备。
硬件输入:
主机接高电平,从机接低电平。

五、SPI HAL库函数

HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);//发送数据
功能:HAL库 SPI发送数据函数
参数:
*hspi: 选择SPI1/2,比如&hspi1,&hspi2
*pData : 需要发送的数据,可以为数组
Size: 发送数据的字节数,1 就是发送一个字节数据
Timeout: 超时时间,就是执行发送函数最长的时间,超过该时间自动退出发送函数
HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);//接收数据
功能:SPI接收数据函数
参数:
*hspi: 选择SPI1/2,比如&hspi1,&hspi2
*pData : 接收发送过来的数据的数组
Size: 接收数据的字节数,1 就是接收一个字节数据
Timeout: 超时时间,就是执行接收函数最长的时间,超过该时间自动退出接收函数
HAL_SPI_TransmitReceive_IT(&hspi1, TXbuf,RXbuf,CommSize);
当SPI上接收出现了 CommSize个字节的数据后,中断函数会调用SPI回调函数:

HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
用户可以重新定义回调函数,编写预定功能即可,在接收完成之后便会进入回调函数
  • 8
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 很高兴为您服务!STM32 HALSPI DMA功能可帮助您在不使用CPU的情况下转移数据,从而节省CPU的资源。DMA可以自动地将数据从SPI口发送到内存,而无需CPU的参与。它可以提高系统的性能和数据传输速度。 ### 回答2: STM32 HAL中的SPI DMA是指通过直接内存访问(DMA)来实现SPI数据传输的功能。 SPI (串行外设接口)是一种常用的串行通信协议,它可以连接MCU与外部设备进行通信。而DMA是一种直接内存访问技术,它可以在不经过CPU的干预下,直接将数据从一个地方传输到另一个地方。通过使用DMA进行SPI数据传输,可以提高效率和性能。 在STM32 HAL中,使用SPI DMA可以通过以下步骤来实现SPI数据传输: 1. 配置SPI外设和DMA通道:首先要配置SPI外设的参数,例如设置SPI通信模式、数据大小、时钟极性和相位等。然后要配置DMA通道的参数,例如选择DMA传输方向、传输数据大小和MODE模式等。 2. 配置DMA传输缓冲区:为SPI和DMA设置传输缓冲区,这些缓冲区将用于存储传输的数据。 3. 启动DMA传输:使用HAL中的函数来启动DMA传输。这将使DMA开始从传输缓冲区中读取数据并将其传输到SPI外设中。 4. 等待传输完成:使用HAL中的函数来等待DMA传输完成。一旦传输完成,可以触发一个传输完成中断。 通过以上步骤,我们可以在STM32 HAL中实现SPI DMA数据传输。这种方式可以使CPU更有效地利用时间来执行其他任务,提高系统的性能和效率。同时,SPI DMA也可以更好地支持大容量数据传输,减少了CPU的负载,提供了更好的实时性能。 ### 回答3: STM32 HAL提供了一种简化SPI DMA(Direct Memory Access,直接内存存取)传输的方法。SPI是串行外设接口的一种通信协议,它能够同时传输和接收数据,而DMA是一种无需CPU参与的数据传输方法,可以提高数据传输效率和系统性能。 STM32 HAL中的SPI DMA功能主要通过一系列API函数来实现。首先,我们需要初始化SPI外设的基本参数,包括通信模式(全双工、单工等)、时钟极性和相位配置、主从模式等。然后,开启DMA传输和中断以及SPI外设本身。接下来,通过调用HAL_SPI_Transmit_DMA和HAL_SPI_Receive_DMA函数来配置DMA传输缓冲区和传输长度,并启动传输。在传输完成后,通过检查相关中断标志位或回调函数来检测传输状态。 SPI DMA的优点在于减少了CPU的工作负担,使得CPU在数据传输期间可以处理其他任务,提高了系统的实时性和效率。同时,DMA传输还可以减少因CPU参与而产生的传输延迟,加快数据传输速度。此外,SPI DMA应用于具有高速数据传输需求的场景,如存储器读写、音频、图形显示等,能够更好地满足系统对快速、稳定数据传输的要求。 需要注意的是,在使用SPI DMA时,需要仔细考虑数据的传输顺序和互斥访问问题,以免造成数据冲突和错误。此外,DMA传输涉及到DMA缓冲区的管理和回调函数的设置,需要仔细调试和测试,以确保数据的正确传输和处理。 总之,STM32 HAL提供了一种方便简化的SPI DMA传输方法,通过充分利用DMA传输的特点,可以提高系统性能和数据传输效率,适用于高速数据传输的应用场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值