STM32学习(MCU控制)(SPI and Flash 存储)
文章目录
- SPI 和 Flash 存储
- 1. SPI 基本概述
- 1.1 SPI 概述
- 1.2 SPI 连接方式
- 1.3 SPI 的四种工作模式【背诵】
- 1.4 SPI 数据形式
- 1.5 SPI 环形总线结构
- 2. STM32 SPI 支持
- 2.1 SPI 框图和技术特征
- 2.2 SPI 配置
- 2.2.1 MCU SPI 配置为主模式
- 2.2.2 SPI 对应引脚和时钟分析
- 3. W25Q128 Flash 存储芯片
- 3.1 存储芯片基本内容
- 3.2 W25Q128 芯片技术参考内容
- 3.3 W25Q128 控制线和数据模式
- 3.4 地址规则【重点】
- 3.5 W25Q128 指令对照表
- 4. 标准库 SPI Flash 移植
- 4.1 标准库 SPI 原码移植到项目中
- 4.2 原码修改
SPI 和 Flash 存储
1. SPI 基本概述
1.1 SPI 概述
SPI(Serial Peripheral Interface)是一种高速、全双工、同步的串行通信总线协议,由摩托罗拉(现为 NXP)公司开发。它被广泛应用于微控制器(MCU)、传感器、存储器(如 Flash、SD卡)、实时时钟(RTC)、数字信号处理器(DSP)等各种外围设备之间的短距离通信。
由于其简单性和高效率,SPI 是嵌入式系统中最常用的通信协议之一。
1.2 SPI 连接方式

- SPI 属于一主多从方式。Master 主机 Slave 从机
- SCLK 时钟线,要求主机必须提供主机和从机之间通信使用的时钟频率。用于控制当前 SPI 工作模式
- MOSI/sdo, Master Output, Slave Input,主机发送数据,从机接收数据,主机发送数据端口。
- MISO/sdi, Master Input, Slave Output,从机发送数据,主机接受数据,主机接受数据端口
- SS/cs, SPI Select/chip select, 片选线,根据当前 SS/cs 高电平选择,选择当前主机对应通信的对应从机是哪一个。
补充说明
- SPI 全双工实现是依赖于 MISO/sdi 和 MOSI/sdo,利用两根数据通信线,基于 SCLK 时钟完成数据通信,可以同时进行读写操作。
- SS/cs SPI 实现一主多从方式是依赖于片选线,多组设备连接一组 SPI 协议接口,需要提供多个 SS/cs 片选线控制通信外设选择。
1.3 SPI 的四种工作模式【背诵】
CPOL (Clock Polarity):时钟极性
- 决定了 SCK 时钟信号在空闲时的状态。
- CPOL = 0:时钟空闲时为低电平。
- CPOL = 1:时钟空闲时为高电平。
CPHA (Clock Phase):时钟相位
- 决定了数据是在时钟的第几个边沿被采样/捕获/读取 ==> 对应 MISO/sdi。
- CPHA = 0:数据在时钟的第一个边沿(即第一个跳变沿)被采样。第二个编译
- CPHA = 1:数据在时钟的第二个边沿被采样。
依据以上两个控制变量匹配,对应 SPI 有四种工作模式
通过组合 CPOL 和 CPHA,就构成了 SPI 的四种工作模式:
- 模式 0 (Mode 0): CPOL=0, CPHA=0
- 模式 1 (Mode 1): CPOL=0, CPHA=1
- 模式 2 (Mode 2): CPOL=1, CPHA=0
- 模式 3 (Mode 3): CPOL=1, CPHA=1
工作模式中,使用 SPI0 和 SPI3 较多。
| 模式 | CPOL | CPHA | 时钟空闲状态 | 采样时刻 | 发送时刻 |
|---|---|---|---|---|---|
| SPI0 | 0 | 0 | Low | 第一个边沿 (上升沿) | 第二个边沿 (下降沿) |
| SPI1 | 0 | 1 | Low | 第二个边沿 (下降沿) | 第一个边沿 (上升沿) |
| SPI2 | 1 | 0 | High | 第一个边沿 (下降沿) | 第二个边沿 (上升沿) |
| SPI3 | 1 | 1 | High | 第二个边沿 (上升沿) | 第一个边沿 (下降沿) |

1.4 SPI 数据形式
- 主要分析 SPI 数据 0 和 数据 1
- SPI 数据是依赖于 SCLK 时钟线,MISO/sdi 和 MOSI/sdo 数据线完成分析,同时需要考虑当前 SPI 的工作模式
- 按照 SPI0 工作模式 CPOL = 0 (时钟空闲位低电平), CPHA = 0 (第一个跳变沿采集数据) 分析 SPI 数据 0 和 1

1.5 SPI 环形总线结构


2. STM32 SPI 支持
2.1 SPI 框图和技术特征


- 需要控制的寄存器有
- SPIx_CR1 SPIx_CR2 SPIx_SR
2.2 SPI 配置
2.2.1 MCU SPI 配置为主模式



2.2.2 SPI 对应引脚和时钟分析
- 利用开发版中的 W25Q128 演示 SPI 操作


- 根据当前原理图分析,时钟使能对应 GPIOB 和 SPI2
- GPIOB 对应使用控制寄存器是 APB2ENR
- SPI2 对应使用控制寄存器是 APB1ENR ,注意 APB1 外设最大的时钟频率为 36 MHz


3. W25Q128 Flash 存储芯片
3.1 存储芯片基本内容
W25Q128 是华邦电子(Winbond)生产的一款非常流行和经典的 128M-bit 串行 Flash 存储器芯片。它采用 SPI(串行外设接口) 进行通信,因其容量适中、接口简单、成本低廉、可靠性高,被广泛应用于各种电子设备中。
除 W25Q128 版本还有
- W25Q128 ==> 实际容量是 16 MB
- W25Q64 ==> 实际容量是 8 MB
- W25Q32 ==> 实际容量是 4 MB
- W25Q16 ==> 实际容量是 2 MB
基于当前 STM32 单片机内部的 Flash 存储空间较少,可以利用外部的 Flash 芯片作为存储设备。可以用于车辆里程信息存储,指纹锁密码和指纹信息存储,RFID 读卡器数据存储。
3.2 W25Q128 芯片技术参考内容
- W25Q128 是一款 高性能、低功耗、高可靠性 的串行闪存芯片,适用于 嵌入式、IoT、汽车电子、工业控制 等多种应用场景。其 SPI/QSPI 接口、高速读写、工业级温度范围 等特点,使其成为现代电子系统中的理想存储解决方
- 存储容量:128Mbit(16MB),采用 16M × 8 的组织结构。
- 接口类型:
- 标准 SPI(Serial Peripheral Interface)
- Dual SPI(双线 SPI)
- Quad SPI(四线 SPI)
- QPI(快速四线 SPI)
- 时钟频率:最高 104MHz(标准 SPI),在 Quad SPI 模式下可进一步提升数据传输速率。
- 写入速度:
- 字写周期 50μs
- 页写周期 3ms(256字节/页)。
- 擦除单位:
- 扇区擦除(4KB)
- 块擦除(64KB)
- 整片擦除(16MB)。
- 工作电压:2.7V~3.6V,适用于多种嵌入式系统。满足 3.3V 标准 MCU 工作电压需求。
- 温度范围:工业级 -40°C ~ +85°C,适用于严苛环境。
- 封装形式:
- SOP-8(小型封装)
- WSON-8(更紧凑的封装)。
- 数据保持时间:20年(非易失性存储)。
- 擦写寿命:100,000次(每个存储单元可擦写10万次)。
- 电流数据
- 工作电流低于 5 mA
- 掉电电流低于 1uA
3.3 W25Q128 控制线和数据模式
- 片选 CS / SS
- CS引脚用于启用或禁用设备操作:
- 当CS为高电平时:
- 设备处于未选中状态,串行数据输出引脚(DO或IO0、IO1、IO2、IO3)呈高阻抗态;
- 若设备未执行内部擦除、编程或状态寄存器写入操作,其功耗将降至待机水平。电流 1 uA
- 当CS拉低时:
- 设备被选中,功耗升至工作状态 电流不大于 5 mA,此时可向设备写入指令或读取数据;
- 上电后,必须确保/CS经历一次从高到低的跳变,设备才会接受新指令。
- 输入输出 DO DI
- 4.2 串行数据输入、输出及输入/输出端口(DI、DO与IO0、IO1、IO2、IO3)
W25Q128FV支持标准SPI、双线SPI和四线SPI操作。在标准SPI模式下:
- 单向DI(输入)引脚用于在串行时钟(CLK)输入引脚的上升沿,向设备串行写入指令、地址或数据;DI 连接的引脚是 MCU MOSI/sdo
- 单向DO(输出)引脚则在CLK的下降沿从设备读取数据或状态。DO 链接引脚是 MCU 的MISO/sdi
- 写保护 WP
- WP引脚用于防止状态寄存器被意外写入,其特性如下:
- 硬件写保护机制:
- 通过与状态寄存器的块保护位(CMP、SEC、TB、BP2、BP1、BP0)及状态寄存器保护位(SRP)配合,可实现从最小4KB扇区到整个存储阵列的硬件保护。
- 该引脚为低电平有效(Active Low),当拉低时激活保护功能。
- 四线模式下的功能切换:
- 若状态寄存器-2中的QE位(Quad使能位)被置1,设备将进入四线I/O模式,此时/WP引脚功能失效,转而作为IO2信号线使用。
- 四线I/O模式的引脚配置详见图1a至1c。
- Hold 引脚
- 暂停与恢复控制:
- 当CS为低电平(设备选中)且HOLD被拉低时:
- DO引脚将进入高阻态;
- DI和CLK引脚上的信号将被忽略(无效状态)。
- 当HOLD恢复高电平后,设备操作将继续执行。
- 多设备共享SPI总线时的应用:
- 该功能特别适用于多个设备共享同一组SPI信号线的场景,可通过/HOLD临时挂起当前设备以切换总线控制权。
- 引脚为低电平有效(Active Low)。
- 四线模式下的功能切换:
- 若状态寄存器-2中的QE位(Quad使能位)被置1,设备进入四线I/O模式,此时/HOLD引脚功能失效,转而作为IO3信号线使用。
- 四线I/O模式的引脚配置详见
3.4 地址规则【重点】
- 块 Block
- 块区域字节数是 64 KB,按照一块字节数数量,地址范围是 0x0000 ~ 0xFFFF
- 当前设备是 W25Q128 对应 16 MB 空间,当前设备一共有 256 块(64KB),按照块进行编号 0x00 ~ 0xFF
- 整个 Flash 空间中每一个字节对应的地址是 0x000000 ~ 0xFFFFFF
- 扇区
- 每一个扇区占用 4 KB,一块 ==> 16 扇区
- 在当前块中,对应扇区的编号是 0x0 ~ 0xF (0 ~ 15)
- 页
- 每一页占用 256 字节,一个扇区 ==> 16 页
- 在当扇区中,对应页的编号是 0x0 ~ 0xF (0 ~ 15)
- 页内字节
- 每一页占用 256 字节
- 页内字节对应的地址凡是 0x00 ~ 0xFF (0 ~ 255)
需要在第 12 块中,第 10 个扇区,第 5 页中的页内 108 个字节写入一个字节数据
- 对应地址0x0B946B

3.5 W25Q128 指令对照表
| 指令名称 (Instruction Name) | 操作码 (Hex) (Opcode) | 功能描述 (Description) | 时钟周期 (Clock Cycles) | 地址字节 (Address Bytes) | 哑字节 (Dummy Bytes) | 数据字节 (Data Bytes) |
|---|---|---|---|---|---|---|
| 写使能 | 0x06 | 允许后续的写入或擦除操作 | 8 | 0 | 0 | 0 |
| 写禁止 | 0x04 | 禁止后续的写入或擦除操作 | 8 | 0 | 0 | 0 |
| 读状态寄存器-1 | 0x05 | 读取状态寄存器1的值(位S7到S0) | 8+8 | 0 | 0 | 1+ (可连续读) |
| 读状态寄存器-2 | 0x35 | 读取状态寄存器2的值(位S15到S8) | 8+8 | 0 | 0 | 1+ (可连续读) |
| 写状态寄存器 | 0x01 | 写入状态寄存器(同时配置S7-S0和S15-S8) | 8+16 | 0 | 0 | 2 |
| 页编程 | 0x02 | 将数据写入芯片(最大256字节为一页) | 8+24 | 3 | 0 | 1-256 |
| 扇区擦除 (4KB) | 0x20 | 擦除一个4KB大小的扇区 | 8+24 | 3 | 0 | 0 |
| 块擦除 (32KB) | 0x52 | 擦除一个32KB大小的块 | 8+24 | 3 | 0 | 0 |
| 块擦除 (64KB) | 0xD8 | 擦除一个64KB大小的块 | 8+24 | 3 | 0 | 0 |
| 整片擦除 | 0xC7 / 0x60 | 擦除整个芯片的所有数据 | 8 | 0 | 0 | 0 |
| 读取数据 | 0x03 | 从指定地址开始读取数据 | 8+24 | 3 | 0 | 1+ (可连续读) |
| 快速读取 | 0x0B | 比标准读取更快的读取方式 | 8+24 | 3 | 1 | 1+ (可连续读) |
| 双线快速读取 | 0x3B | 使用两条数据线进行快速读取(提高速度) | 8+24 | 3 | 1 | 1+ (可连续读) |
| 四线快速读取 | 0x6B | 使用四条数据线进行快速读取(速度最快) | 8+24 | 3 | 1 | 1+ (可连续读) |
| 功率下降 | 0xB9 | 使芯片进入低功耗睡眠模式 | 8 | 0 | 0 | 0 |
| 释放功率下降 | 0xAB | 将芯片从低功耗睡眠模式中唤醒 | 8+24 | 3 (虚设地址) | 0 | 0 |
| 读JEDEC ID | 0x9F | 读取制造商标识、内存类型和设备容量ID | 8+24 | 0 | 0 | 3 (返回3字节ID) |
0x06 写使能操作
- CS/SS 片选线,从高电平跳变到低电平,表示选择当前的外部设备
- CLK 时钟线开始工作,对应 SPI 的工作模式是 SPI0(CPOL=0 CPHA=0) 或者 SPI1(CPOL=1 CPHA=1)
- 对于当前的外表设备,在整个时钟的上升沿阶段进行数据读取。此时根据 DI 数据线分析,设备读取到的数据内容为 0000 0110 ==> 0x06 W25QXXX 系列芯片进入【写使能状态】

0x04 禁止写
- CS/SS 片选线,从高电平跳变到低电平,表示选择当前的外部设备
- CLK 时钟线开始工作,对应 SPI 的工作模式是 SPI0(CPOL=0 CPHA=0) 或者 SPI1(CPOL=1 CPHA=1)
- 对于当前的外表设备,在整个时钟的上升沿阶段进行数据读取。此时根据 DI 数据线分析,设备读取到的数据内容为 0000 0100 ==> 0x04 W25QXXX 系列芯片进入【禁止写状态】


4. 标准库 SPI Flash 移植
4.1 标准库 SPI 原码移植到项目中
项目 user api 目录下的内容

项目中引入对应的 SPI_Flash内容

4.2 原码修改
spi_flash.h 头文件修改内容

spi_flash.c 源码文件修改内容

在 spi_flash.h 头文件修改 W25Q128 存储芯片支持的指令内容

修改 SPI_Flash.h 头文件中修改 CS/SS 高低电平宏控制

