STM32——SPI
一.基本介绍
1.1 SPI介绍
SPI:串行外设设备接口(Serial Peripheral Interface),是一种高速的,全双工,同步的通信总线。
功能说明 | SPI****总线 | IIC****总线 |
通信方式 | 同步 串行 全双工 | 同步 串行 半双工 |
总线接口 | MOSI、MISO、SCL、CS | SDA、SCL |
拓扑结构 | 一主多从/一主一从 | 多主从 |
从机选择 | 片选引脚选择 | SDA上设备地址片选 |
通信速率 | 一般50MHz以下 | 100kHz、400kHz、3.4MHz |
数据格式 | 8位/16位 | 8位 |
传输顺序 | MSB/LSB | MSB |
SPI接口主要应用在存储芯片、AD转换器以及LCD中。

1.2 SPI框图

① SPI相关引脚
MOSI(输出数据线)
MISO(输入数据线)
SCK(时钟)
NSS(片选)
② 数据发送和接收
与缓冲区、移位寄存器以及引脚相关
③ 时钟信号
SPI时钟信号是通过SPI_CR1寄存器配置
④ 主控制逻辑
涉及两个控制寄存器SPI_CR1/2用于配置SPI工作,SPI_SR用于查看工作状态
1.3 SPI外设对应的引脚
STM32芯片有多个SPI外设,每个SPI外设输出的信号会到不同的GPIO口。
STM32F1有三个SPI。
F1 | 引脚 | SPI1 | SPI2 | SPI3 |
NSS | PA4 | PB12 | PA15 | |
CLK | PA5 | PB13 | PB3 | |
MISO | PA6 | PB14 | PB4 | |
MOSI | PA7 | PB15 | PB5 |
F4 / F7 / H7 系列芯片SPI外设都有6个,分别为SPI1、SPI2、SPI3、SPI4、SPI5和SPI6。
二.工作原理
2.1 数据发送接收简图


2.2 SPI工作模式
时钟极性(CPOL):
没有数据传输时时钟线的空闲状态电平
0:SCK在空闲状态保持低电平
1:SCK在空闲状态保持高电平
时钟相位(CPHA):
时钟线在第几个时钟边沿采样数据
0:SCK的第一(奇数)边沿进行数据位采样,数据在第一个时钟边沿被锁存
1:SCK的第二(偶数)边沿进行数据位采样,数据在第二个时钟边沿被锁存
SPI工作模式 | CPOL | CPHA | SCL空闲状态 | 采样边沿 | 采样时刻 |
0 | 0 | 0 | 低电平 | 上升沿 | 奇数边沿 |
1 | 0 | 1 | 低电平 | 下降沿 | 偶数边沿 |
2 | 1 | 0 | 高电平 | 下降沿 | 奇数边沿 |
3 | 1 | 1 | 高电平 | 上升沿 | 偶数边沿 |
2.3 SPIHAL库
驱动函数 | 关联寄存器 | 功能描述 |
__HAL_RCC_SPIx_CLK_ENABLE(…) | RCC_APB2ENR | 使能SPIx时钟 |
HAL_SPI_Init**(…)** | SPI_CR1 | 初始化SPI |
HAL_SPI_MspInit**(…)** | 初始化回调 | 初始化SPI相关引脚 |
HAL_SPI_Transmit**(…)** | SPI_DR/SPI_SR | SPI发送 |
HAL_SPI_Receive**(…)** | SPI_DR/SPI_SR | SPI接收 |
HAL_SPI_TransmitReceive**(…)** | SPI_DR/SPI_SR | SPI接收发送 |
__HAL_SPI_ENABLE(…) | SPI_CR1(SPE) | 使能SPI外设 |
__HAL_SPI_DISABLE(…) | SPI_CR1(SPE) | 失能SPI外设 |

三.NOR FLASH
3.1 NOR FLASH介绍
FLASH是常用的用于储存数据的半导体器件,它具有容量大,可重复擦写、按“扇区/块”擦除、掉电后数据可继续保存的特性。
FLASH主要有NOR Flash和NAND Flash两种类型,NOR和NAND是两种数字门电路。
类型 | 特点 | 应用举例 |
NOR FLASH | 基于字节读写,读取速度快,独立地址/数据线,无坏块,支持XIP | 25Qxx、程序ROM |
NAND FLASH | 基于块读写,读取速度稍慢,地址数据线共用,有坏块,不支持XIP | EMMC、SSD、U盘等 |
3.1.1 NM25Q128介绍
NM25Q128,串行闪存器件,属于NOR FLASH中的一种,容量为128 Mb。擦写周期可达10W次,可以将数据保存达20年之久


NM25Q128存储结构:

3.2 NOR FLASH常用指令
指令**(HEX)** | 名称 | 作用 |
0X06 | 写使能 | 写入数据/擦除之前,必须先发送该指令 |
0X05 | 读SR1 | 判定FLASH是否处于空闲状态,擦除用 |
0X03 | 读数据 | 用于读取NOR FLASH数据 |
0X02 | 页写 | 用于写入NOR FLASH数据,最多写256字节 |
0X20 | 扇区擦除 | 扇区擦除指令,最小擦除单位(4096字节) |
写使能:

读状态寄存器Read Status Reg1(05H):

读时序 Read Data Bytes(03H):

页写时序:

扇区擦除时序 Sector Erase(20H):

状态寄存器表:
状态寄存器 | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 |
状态寄存器1 | SPR | RV | TB | BP2 | BP1 | BP0 | WEL | BUSY |
状态寄存器2 | SUS | CMP | LB3 | LB2 | LB1 | (R) | QE | SRP1 |
状态寄存器3 | HOLD/RST | DRV1 | DRV0 | (R) | (R) | WPS | ADP | ADS |
BUSY位 指示当前状态 0:空闲状态(硬件自动清除) 1:当前处于忙碌状态
WEL位 执行WriteEnable指令该位为1,可以页写/扇区or块or片擦除/写状态寄存器 0:写禁止,不能页编程/扇区or块or片擦除/写状态寄存器
3.3 NOR FLASH基本驱动步骤
SPI配置:
步骤 | 操作 | 函数 |
1 | SPI工作参数配置初始化 | 工作模式、时钟极性、时钟相位等HAL_SPI_Init |
2 | 使能SPI时钟和初始化相关引脚 | GPIO模式设为复用推挽输出模式HAL_SPI_MspInit |
3 | 使能SPI | __HAL_SPI_ENABLE |
4 | SPI传输数据 | HAL_SPI_Transmit 发送数据HAL_SPI_Receive 接收数据HAL_SPI_TransmitReceive 进行发送与接收 |
5 | 设置SPI传输速度 | 操作SPI_CR1寄存器中的波特率控制位 |
NM25Q128配置:
步骤 | 操作 | 函数 |
1 | 初始化片选引脚与SPI接口 | 相关GPIO初始化、SPI初始化(模式、位数、分频、MSB等) |
2 | NM25Q128 读取 | 0x03指令 + 24位地址 + 读取数据 |
3 | NM25Q128 扇区擦除 | 0x06指令 + 等待空闲 + 0x20指令 + 24位地址 + 等待空闲 |
4 | NM25Q128 写入 | 擦除扇区(可选)+ 0x06指令 + 0x02指令+ 24位地址 + 写入数据 + 等待空闲 |