目录
函数SPI_NSSInternalSoftwareConfig
什么是SPI?
spi是串行外设接口,SPI
是一个同步的数据总线,也就是说它是用单独的数据线和一个单独的时钟信号来保证发送端和接收端的完美同步。
SPI 接口提供两个主要功能
- SPI 协议
- IIS 音频协议
默认情况下,选择的是 SPI 功能。可通过软件将接口从 SPI 切换到IIS。
SPI协议
SPI 特性:
- 基于三条线的全双工同步传输
- 基于双线的单工同步传输,其中一条可作为双向数据线
- 8 位或 16 位传输帧格式选择
- 主模式或从模式操作
- 多主模式功能
- 8 个主模式波特率预分频器(最大值为 f PCLK /2)
- 从模式频率(最大值为 f PCLK /2)
- 对于主模式和从模式都可实现更快的通信
- 对于主模式和从模式都可通过硬件或软件进行 NSS 管理:动态切换主/从操作
- 可编程的时钟极性和相位
- 可编程的数据顺序,最先移位 MSB 或 LSB
- 可触发中断的专用发送和接收标志
- SPI 总线忙状态标志
- 具有 DMA 功能的 1 字节发送和接收缓冲器:发送和接收请求
串行外设接口 (SPI) 可与外部器件进行半双工/全双工的同步串行通信。该接口可配置为主模 式,在这种情况下,它可为外部从器件提供通信时钟 (SCK)。该接口还能够在多主模式配置 下工作。 它可用于多种用途,包括基于双线的单工同步传输,其中一条可作为双向数据线,或使用 CRC 校验实现可靠通信
IIS特征
- 全双工通信
- 半双工通信(仅作为发送器或接收器)
- 主模式或从模式操作
- 8 位可编程线性预分频器,可实现精确的音频采样频率(从 8 kHz 到 192 kHz)
- 数据格式可以是 16 位、24 位或 32 位
- 数据包帧由音频通道固定为 16 位(可容纳 16 位数据帧)或 32 位(可容纳 16 位、 24 位、32 位数据帧)
- 可编程的时钟极性(就绪时的电平状态)
- 从发送模式下的下溢标志、接收模式下的上溢标志(主模式和从模式),以及接收和发 送模式下的帧错误标志(仅从模式)
- 发送和接收使用同一个 16 位数据寄存器
- 用于发送和接收的 DMA 功能(16 位宽)
SPI 功能说明
SPI 框图
通常,SPI 通过 4 个引脚与外部器件连接:
- MISO:主输入/从输出数据。此引脚可用于在从模式下发送数据和在主模式下接收数据。
- MOSI:主输出/从输入数据。此引脚可用于在主模式下发送数据和在从模式下接收数据。
- SCK:用于 SPI 主器件的串行时钟输出以及 SPI 从器件的串行时钟输入。
- NSS:从器件选择。这是用于选择从器件的可选引脚。
单个主器件/ 单个从器件应用
注意:此处,NSS 引脚配置为输入
MOSI 引脚连接在一起,MISO 引脚连接在一起。通过这种方式,主器件和从器件之间以串 行方式传输数据(最高有效位在前)
通信始终由主器件发起。当主器件通过 MOSI 引脚向从器件发送数据时,从器件同时通过 MISO 引脚做出响应。这是一个数据输出和数据输入都由同一时钟进行同步的 1 全双工通信 过程。
从器件选择 (NSS) 引脚管理
可以使用 SPI_CR1 寄存器中的 SSM 位设置硬件或软件管理从器件选择。
-
软件管理 NSS (SSM = 1)
从器件选择信息在内部由 SPI_CR1 寄存器中的 SSI 位的值驱动。外部 NSS 引脚空 闲,可供其它应用使用。
-
硬件管理 NSS (SSM = 0) 根据 NSS 输出配置(SPI_CR1 寄存器中的 SSOE 位),硬件管理 NSS 有两种模式。
- NSS 输出使能(SSM = 0,SSOE = 1) 仅当器件在主模式下工作时才使用此配置。当主器件开始通信时,NSS 信号驱动 为低电平,并保持到 SPI 被关闭为止。
- NSS 输出禁止(SSM = 0,SSOE = 0) 对于在主模式下工作的器件,此配置允许多主模式功能。对于设置为从模式的器 件,NSS 引脚用作传统 NSS 输入:在 NSS 为低电平时片选该从器件,在 NSS 为 高电平时取消对它的片选。
时钟相位和时钟极性
通过 SPI_CR1 寄存器中的 CPOL 和 CPHA 位,可以用软件选择四种可能的时序关系。 CPOL(时钟极性)位控制不传任何数据时的时钟电平状态。此位对主器件和从 器件都有作 用。如果复位 CPOL,SCK 引脚在空闲状态处于低电平。如果将 CPOL 置 1,SCK 引脚在 空闲状态处于高电平。
如果将 CPHA(时钟相位)位置 1,则 SCK 引脚上的第二个边沿(如果复位 CPOL 位,则 为下降沿;如果将 CPOL 位置 1,则为上升沿)对 MSBit 采样。即,在第二个时钟边沿锁存数据。如果复位 CPHA 位,则 SCK 引脚上的第一个边沿(如果将 CPOL 位置 1,则为下降沿;如果复位 CPOL 位,则为上升沿)对 MSBit 采样。即,在第一个时钟边沿锁存数据。CPOL(时钟极性)和 CPHA(时钟相位)位的组合用于选择数据捕获时钟边沿。
数据时钟时序图
所示的时序为 SPI_CR1 寄存器中的 LSBFIRST 位复位时的时序。
把 SPI 配置成从器件
在从模式配置中,从 SCK 引脚上接收主器件的串行时钟。SPI_CR1 寄存器的 BR[2:0] 位中 设置的值不会影响数据传输率。
**注意:**建议在主器件发送时钟前使能 SPI 从器件。否则,数据传输可能会不正常。在主时钟的第一个边沿到来之前或者正在进行的通信结束之前,从器件的数据寄存器就需要准备就绪。在使能从器件和主器件之前,必须将通信时钟的极性设置为空闲时的时钟电平。
发送序列
数据字节在写周期内被并行加载到发送缓冲区中。
当从器件在其 MOSI 引脚上收到时钟信号和数据的最高有效位时,发送序列开始。其余位 (8 位数据帧格式中的 7 个位,16 位数据帧格式中的 15 个位)将加载到移位寄存器中。 SPI_SR 寄存器中的 TXE 标志在数据从发送缓冲区传输到移位寄存器时置 1,并且在 SPI_CR2 寄存器中的 TXEIE 位置 1 时将生成中断。
接收序列
对于接收器,在数据传输完成时
- 移位寄存器中的数据将传输到接收缓冲区,并且 RXNE 标志(SPI_SR 寄存器)置 1
- 如果 SPI_CR2 寄存器中的 RXNEIE 位置 1,则生成中断。
在出现最后一个采样时钟边沿后,RXNE 位置 1,移位寄存器中接收的数据字节被拷贝到接 收缓冲区中。当读取 SPI_DR 寄存器时,SPI 外设将返回此缓冲值。
通过读取 SPI_DR 寄存器将 RXNE 位清零。
SPI库函数
函数 SPI_DeInit
函数名 | SPI_DeInit |
---|---|
函数原形 | void SPI_DeInit(SPI_TypeDef* SPIx) |
功能描述 | 将外设 SPIx 寄存器重设为缺省值 |
输入参数 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输出参数 | 无 |
返回值 | 无 |
先决条件 | 无 |
被调用函数 | 对 SPI1RCC_APB2PeriphClockCmd(). 对 SPI2RCC_APB1PeriphClockCmd(). |
函数SPI_Init
函数名 | SPI_Init |
---|---|
函数原形 | void SPI_DeInit(SPI_TypeDef* SPIx) |
功能描述 | 根据 SPI_InitStruct 中指定的参数初始化外设 SPIx 寄存器 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输入参数 2 | SPI_InitStruct:指向结构 SPI_InitTypeDef 的指针,包含了外设 SPI 的配置信息 |
输出参数 | 无 |
返回值 | 无 |
先决条件 | 无 |
被调用函数 | 无 |
typedef struct
{
u16 SPI_Direction; //SPI 方向
u16 SPI_Mode; //SPI 工作模式
u16 SPI_DataSize; //SPI 的数据大小
u16 SPI_CPOL; //选择了串行时钟的稳态
u16 SPI_CPHA; //设置了位捕获的时钟活动沿
u16 SPI_NSS; //指定了 NSS 信号由硬件(NSS 管脚)还是软件(使用 SSI 位)管理
u16 SPI_BaudRatePrescaler; //定义波特率预分频的值
u16 SPI_FirstBit; //指定了数据传输从 MSB 位还是 LSB 位开始
u16 SPI_CRCPolynomial; //定义了用于 CRC 值计算的多项式
} SPI_InitTypeDef;
- SPI_Direction SPI_Dirention 设置了 SPI 单向或者双向的数据模式。
- SPI_Mode 值
- SPI_DataSize
- SPI_CPOL
- SPI_CPHA
- SPI_NSS 值
- SPI_BaudRatePrescaler 值
**注意:**通讯时钟由主 SPI 的时钟分频而得,不需要设置从 SPI 的时钟。
- SPI_FirstBit 值
- SPI_CRCPolynomial
函数SPI_StructInit
函数名 | SPI_StructInit |
---|---|
函数原形 | void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct) |
功能描述 | 把 SPI_InitStruct 中的每一个参数按缺省值填入 |
输入参数 | SPI_InitStruct:指向结构 SPI_InitTypeDef 的指针,待初始化 |
输出参数 | 无 |
返回值 | 无 |
先决条件 | 无 |
被调用函数 | 无 |
函数SPI_Cmd
函数名 | SPI_ Cmd |
---|---|
函数原形 | void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) |
功能描述 | 使能或者失能 SPI 外设 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输入参数 2 | NewState: 外设 SPIx 的新状态 这个参数可以取:ENABLE 或者 DISABLE |
输出参数 | 无 |
返回值 | 无 |
先决条件 | 无 |
被调用函数 | 无 |
函数SPI_ITConfig
函数名 | SPI_ITConfig |
---|---|
函数原形 | void SPI_ITConfig(SPI_TypeDef* SPIx, u16 SPI_IT, FunctionalState NewState) |
功能描述 | 使能或者失能指定的 SPI 中断 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输入参数 2 | SPI_IT:待使能或者失能的 SPI 中断源 |
输入参数 3 | NewState:SPIx 中断的新状态 |
输出参数 | 无 |
返回值 | 无 |
先决条件 | 无 |
被调用函数 | 无 |
SPI_IT :输入参数 SPI_IT 使能或者失能 SPI 的中断
函数SPI_DMACmd
函数名 | SPI_ DMACmd |
---|---|
函数原形 | void SPI_DMACmd(SPI_TypeDef* SPIx, u16 SPI_DMAReq,FunctionalState NewState) |
功能描述 | 使能或者失能指定 SPI 的 DMA 请求 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输入参数 2 | SPI_DMAReq:待使能或者失能的 SPI DMA 传输请求 |
输入参数 3 | NewState:SPIx 中断的新状态 |
输出参数 | 无 |
返回值 | 无 |
先决条件 | 无 |
被调用函数 | 无 |
SPI_DMAReq :使能或者失能 SPI Tx 和/或 SPI Rx 的 DMA 传输请求
函数SPI_SendData
函数名 | SPI_ SendData |
---|---|
函数原形 | void SPI_SendData(SPI_TypeDef* SPIx, u16 Data) |
功能描述 | 通过外设 SPIx 发送一个数据 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输入参数 2 | Data: 待发送的数据 |
输出参数 | 无 |
返回值 | 无 |
先决条件 | 无 |
被调用函数 | 无 |
函数SPI_ReceiveData
函数名 | SPI_ ReceiveData |
---|---|
函数原形 | u16 SPI_ReceiveData(SPI_TypeDef* SPIx) |
功能描述 | 返回通过 SPIx 最近接收的数据 |
输入参数 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输出参数 | 无 |
返回值 | 接收到的字 |
先决条件 | 无 |
被调用函数 | 无 |
函数SPI_NSSInternalSoftwareConfig
函数名 | SPI_NSSInternalSoftwareConfig |
---|---|
函数原形 | void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, u16 SPI_NSSInternalSoft) |
功能描述 | 为选定的 SPI 软件配置内部 NSS 管脚 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输入参数 2 | SPI_NSSInternalSoft:SPI NSS 内部状态 |
输出参数 | 无 |
返回值 | 无 |
先决条件 | 无 |
被调用函数 | 无 |
SPI_NSSInternalSoft :内部设置或者重置 NSS 管脚
函数SPI_SSOutputCmd
函数名 | SPI_SSOutputCmd |
---|---|
函数原形 | void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState) |
功能描述 | 为选定的 SPI 软件配置内部 NSS 管脚 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输入参数 2 | SPI_NSSInternalSoft:SPI NSS 内部状态 |
输出参数 | 无 |
返回值 | 无 |
先决条件 | 无 |
被调用函数 | 无 |
函数SPI_DataSizeConfig
函数名 | SPI_DataSizeConfig |
---|---|
函数原形 | void SPI_DataSizeConfig(SPI_TypeDef* SPIx, u16 SPI_DatSize) |
功能描述 | 设置选定的 SPI 数据大小 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输入参数 2 | SPI_DataSize:SPI 数据大小 |
输出参数 | 无 |
返回值 | 无 |
先决条件 | 无 |
被调用函数 | 无 |
函数SPI_TransmitCRC
函数名 | SPI_ TransmitCRC |
---|---|
函数原形 | SPI_TransmitCRC(SPI_TypeDef* SPIx, FunctionalState NewState) |
功能描述 | 使能或者失能指定 SPI 的 CRC 传输 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输入参数 2 | NewState:SPIxCRC 传输的新状态 |
输出参数 | 无 |
返回值 | 无 |
先决条件 | 无 |
被调用函数 | 无 |
函数SPI_CalculateCRC
函数名 | SPI_ CalculateCRC |
---|---|
函数原形 | void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState) |
功能描述 | 使能或者失能指定 SPI 的传输字 CRC 值计算 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输入参数 2 | NewState:SPIxCRC 传输的新状态 |
输出参数 | 无 |
返回值 | 无 |
先决条件 | 无 |
被调用函数 | 无 |
函数SPI_GetCRC
函数名 | SPI_ GetCRC |
---|---|
函数原形 | u16 SPI_GetCRC(SPI_TypeDef* SPIx) |
功能描述 | 返回指定 SPI 的 CRC 值 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输入参数 2 | SPI_CRC:待读取的 CRC 寄存器 |
输出参数 | 无 |
返回值 | CRC 值 |
先决条件 | 无 |
被调用函数 | 无 |
SPI_CRC :选择 SPI Rx 或者 SPI Tx 的 CRC 寄存器
函数SPI_GetCRCPolynomial
函数名 | SPI_GetCRCPolynomial |
---|---|
函数原形 | u16 SPI_GetCRCPolynomial(SPI_TypeDef* SPIx) |
功能描述 | 返回指定 SPI 的 CRC 多项式寄存器值 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输出参数 | 无 |
返回值 | CRC 多项式寄存器值 |
先决条件 | 无 |
被调用函数 | 无 |
函数SPI_BiDirectionalLineConfig
函数名 | SPI_BiDirectionalLineConfig |
---|---|
函数原形 | SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, u16 SPI_Direction) |
功能描述 | 选择指定 SPI 在双向模式下的数据传输方向 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输入参数 2 | SPI_Direction:待读取的 CRC 寄存器 |
输出参数 | 无 |
返回值 | CRC 值 |
先决条件 | 无 |
被调用函数 | 无 |
函数SPI_GetFlagStatus
函数名 | SPI_ GetFlagStatus |
---|---|
函数原形 | FlagStatus SPI_GetFlagStatus(SPI_TypeDef* SPIx, u16 SPI_FLAG) |
功能描述 | 检查指定的 SPI 标志位设置与否 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输入参数 2 | SPI_FLAG:待检查的 SPI 标志位 |
输出参数 | 无 |
返回值 | SPI_FLAG 的新状态(SET 或者 RESET) |
先决条件 | 无 |
被调用函数 | 无 |
函数SPI_ClearFlag
函数名 | SPI_ ClearFlag |
---|---|
函数原形 | void SPI_ClearFlag(SPI_TypeDef* SPIx, u16 SPI_FLAG) |
功能描述 | 清除 SPIx 的待处理标志位 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输入参数 2 | SPI_FLAG:待检查的 SPI 标志位 |
输出参数 | 无 |
返回值 | SPI_FLAG 的新状态(SET 或者 RESET) |
先决条件 | 无 |
被调用函数 | 无 |
函数SPI_GetITStatus
函数名 | SPI_ GetITStatus |
---|---|
函数原形 | ITStatus SPI_GetITStatus(SPI_TypeDef* SPIx, u8 SPI_IT) |
功能描述 | 检查指定的 SPI 中断发生与否 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输入参数 2 | SPI_IT:待检查的 SPI 中断源 |
输出参数 | 无 |
返回值 | SPI_IT 的新状态 |
先决条件 | 无 |
被调用函数 | 无 |
函数SPI_ClearITPendingBit
函数名 | SPI_ ClearITPendingBit |
---|---|
函数原形 | void SPI_ClearITPendingBit(SPI_TypeDef* SPIx, u8 SPI_IT) |
功能描述 | 清除 SPIx 的中断待处理位 |
输入参数 1 | SPIx:x 可以是 1 或者 2,来选择 SPI 外设 |
输入参数 2 | SPI_IT:待检查的 SPI 中断源 |
输出参数 | 无 |
返回值 | SPI_IT 的新状态 |
先决条件 | 无 |
被调用函数 | 无 |