STM32(二十八)——FLASH闪存

一、简介

•STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分,通过闪存存储器接口(外设)可以对程序存储器和选项字节进行擦除和编程
•读写FLASH的用途:

利用程序存储器的剩余空间来保存掉电不丢失的用户数据

通过在程序中编程(IAP),实现程序的自我更新
•在线编程(In-Circuit Programming -- ICP)用于更新程序存储器的全部内容,它通过JTAG、SWD协议或系统加载程序(Bootloader)下载程序
•在程序中编程(In-Application Programming -- IAP)可以使用微控制器支持的任一种通信接口下载程序

二、闪存模块组织

一、闪存模块组织架构总览

这款中容量产品的闪存被划分为三大核心区域

  • 主存储器:程序代码与数据的核心存储区,按页(Page)组织
  • 信息块:存储启动代码、用户配置等关键系统信息
  • 闪存存储器接口寄存器:控制闪存读写、擦除等操作的硬件寄存器组

二、主存储器区域详解

  • 组织方式:以"页(Page)" 为最小单位,共 128 页(页 0~ 页 127)
  • 单页容量:1KB(1024 字节)
  • 地址范围0x0800 0000 ~ 0x0801 FFFF
  • 总容量 :128 × 1KB = 128KB
  • 特点 :这是用户程序的主要存放区域,STM32 中通常从0x0800 0000开始存放中断向量表和应用代码。

三、信息块区域详解

信息块是系统级的特殊存储区域,包含两类关键信息:

  1. 启动程序代码

    • 地址:0x1FFF F000 ~ 0x1FFF F7FF
    • 容量:2KB
    • 作用:存储芯片出厂时的 Bootloader,负责芯片上电后的初始化、程序加载(如串口 / USB 下载)等。
  2. 用户选择字节

    • 地址:0x1FFF F800 ~ 0x1FFF F80F
    • 容量:16 字节
    • 作用:存储用户配置信息,如读保护、写保护、看门狗设置等选项字节。

四、闪存接口寄存器区域详解

这组寄存器(基地址0x4002 2000)是 CPU 与闪存硬件交互的桥梁,每个寄存器占 4 字节(32 位),核心寄存器功能如下:

三、FLASH基本结构

1. 核心存储分区

主存储器:

  • 程序存储器(64KB)

    • 地址范围:0x0800 0000 ~ 0x0800 FFFF
    • 组织形式:共 64 页 ,每页大小 1KB(页 0~ 页 63)
    • 用途:存放用户应用程序代码、常量数据,是 CPU 执行指令的主存储区

信息块:

  • 系统存储器(2KB)

    • 地址范围:0x1FFF F000 ~ 0x1FFF F7FF
    • 内容:芯片出厂时固化的 Bootloader,负责上电初始化、串口 / USB 等方式的程序下载
    • 特性:用户不可擦写,保障芯片基础启动功能
  • 选项字节(16 字节)

    • 地址范围:0x1FFF F800 ~ 0x1FFF F80F
    • 用途:存储系统安全与配置信息,如读保护、写保护、看门狗设置、复位引脚配置等

2. 闪存控制核心:FPEC

  • 全称:Flash Program and Erase Controller(闪存编程与擦除控制器)
  • 核心作用:
    1. 负责程序存储器的页擦除、全擦除与字编程操作
    2. 管理选项字节的擦除与编程,实现系统安全配置
    3. 提供寄存器接口(如FLASH_KEYR解锁、FLASH_CR控制命令、FLASH_SR状态查询),供 CPU 调用

3. 典型开发应用

  • 固件升级:通过 FPEC 擦除目标页,再将新固件写入程序存储器对应地址
  • 安全加固:配置选项字节开启读保护,防止外部调试器读取固件代码
  • 参数存储:利用未使用的程序存储器页,存储用户配置参数(如校准数据、设备序列号)

四、FLASH解锁

FPEC共有三个键值:

RDPRT键 = 0x000000A5

KEY1 = 0x45670123

KEY2 = 0xCDEF89AB

解锁**:**

复位后,FPEC被保护,不能写入FLASH_CR

在FLASH_KEYR先写入KEY1,再写入KEY2,解锁

错误的操作序列会在下次复位前锁死FPEC和FLASH_CR

加锁:

设置FLASH_CR中的LOCK位锁住FPEC和FLASH_CR

五、使用指针访问寄存器

使用指针读指定地址下的存储器

uint16_t Data = *((__IO uint16_t *)(0x08000000));

去地址 0x08000000 这个位置,把里面存的 16 位数读出来,放到 Data 里。

一步步拆:

  • (uint16_t *)0x08000000→ 把数字 0x08000000 当成 16 位指针
  • *→ 取指针指向的内容(读数据

使用指针写指定地址下的存储器:

*((__IO uint16_t *)(0x08000000)) = 0x1234;

把 0x1234 这个 16 位数,直接写入地址 0x08000000。

STM32 闪存必须按规则写入:解锁 → 擦除 → 编程,不能直接赋值!这里只是拿来看一下,要写闪存 Flash的话,必须按规则来,不过0x02000000 → 内存 RAM ✅ 可以直接写。

注:

#define __IO volatile

告诉编译器:这个地址的值会 "自己变",不许优化,每次都必须真的去硬件读 / 写!

如果不加:

  • 编译器可能觉得 "地址没变,数据也没变",直接给你优化掉
  • 硬件读出来的值 可能是错的

加了 volatile(__IO):

  • 每次都老老实实访问真实地址
  • 嵌入式操作寄存器、闪存、内存 必须加

六、程序存储器全擦除、页擦除、编程

注:下面的流程图中有进行判断是否解锁,在标准库函数中不进行判断,不管是否解锁都执行解锁过程。

程序存储器全擦除

过程图

流程步骤拆解

1、检查锁定状态

操作:读取 FLASH_CR 寄存器的 LOCK

逻辑:

  • LOCK = 1(闪存处于锁定状态):必须先执行解锁流程 (向 FLASH_KEYR 写入固定密钥序列)
  • LOCK = 0(已解锁):直接进入下一步

2、启动全擦除命令

操作:

  • FLASH_CRMER(Mass Erase)位为 1,开启全擦除模式
  • FLASH_CRSTRT(Start)位为 1,触发擦除操作(让CPU工作)

3、等待操作完成

操作:循环读取 FLASH_SR 寄存器的 BSY(Busy)位

逻辑:

  • BSY = 1:闪存正在执行擦除,继续等待
  • BSY = 0:擦除操作完成,退出等待

4、验证擦除结果

操作:逐页读取闪存数据,验证所有页是否已被擦除(擦除后闪存内容为 0xFF

程序存储器页擦除

过程图

流程步骤拆解

1、检查锁定状态

  • 操作:读取 FLASH_CR 寄存器的 LOCK
  • 逻辑:
    • LOCK = 1(闪存锁定):必须先执行解锁流程 (向 FLASH_KEYR 写入 0x456701230xCDEF89AB 两个密钥)
    • LOCK = 0(已解锁):直接进入下一步

2、配置并启动页擦除

  • 操作:
    1. FLASH_CRPER(Page Erase)位为 1,开启页擦除模式
    2. FLASH_AR(地址寄存器)中写入目标页的起始地址,选择要擦除的页
    3. FLASH_CRSTRT(Start)位为 1,触发擦除操作

3、等待操作完成

  • 操作:循环读取 FLASH_SR 寄存器的 BSY(Busy)位
  • 逻辑:
    • BSY = 1:闪存正在执行擦除,继续等待
    • BSY = 0:擦除操作完成,退出等待

4、验证擦除结果

  • 操作:读取目标页的所有数据,验证是否已被擦除(擦除后闪存内容为 0xFF

程序存储器编程

流程图

流程步骤拆解

1、检查锁定状态

  • 操作:读取 FLASH_CR 寄存器的 LOCK
  • 逻辑:
    • LOCK = 1(闪存锁定):必须先执行解锁序列 (向 FLASH_KEYR 依次写入 0x456701230xCDEF89AB 两个密钥)
    • LOCK = 0(已解锁):直接进入下一步

2、开启编程模式

  • 操作:置 FLASH_CRPG(Programming)位为 1,使能闪存编程模式

3、写入半字数据

  • 操作:在指定的闪存地址写入半字(16 位数据)
  • 注意:STM32F1 闪存编程最小单位为半字(16 位),不支持单字节写入

4、等待操作完成

  • 操作:循环读取 FLASH_SR 寄存器的 BSY(Busy)位
  • 逻辑:
    • BSY = 1:闪存正在执行编程操作,继续等待
    • BSY = 0:编程操作完成,退出等待

5、验证写入结果

  • 操作:读取刚编程的地址,检查写入的数据是否与预期一致

七、选项字节编程、擦除,电子签名

信息块中选项字节(Option Bytes) 的 32 位寄存器布局

•RDP:写入RDPRT键(0x000000A5)后解除读保护

•USER:配置硬件看门狗和进入停机/待机模式是否产生复位

•Data0/1:用户可自定义使用

•WRP0/1/2/3:配置写保护,每一个位对应保护4个存储页(中容量)

选项字节编程

•检查FLASH_SR的BSY位,以确认没有其他正在进行的编程操作

•解锁FLASH_CR的OPTWRE位

•设置FLASH_CR的OPTPG位为1

•写入要编程的半字到指定的地址

•等待BSY位变为0

读出写入的地址并验证数据

选项字节擦除

•检查FLASH_SR的BSY位,以确认没有其他正在进行的闪存操作

•解锁FLASH_CR的OPTWRE位

•设置FLASH_CR的OPTER位为1

•设置FLASH_CR的STRT位为1

•等待BSY位变为0

读出被擦除的选择字节并做验证

电子签名

•电子签名存放在闪存存储器模块的系统存储区域,包含的芯片识别信息在出厂时编写,不可更改,使用指针读指定地址下的存储器可获取电子签名

•闪存容量寄存器:

基地址:0x1FFF F7E0

大小:16位

相关推荐
9稳2 小时前
基于plc的自动化立体仓库控制系统设计
开发语言·网络·数据库·嵌入式硬件·plc
ToneChip2 小时前
USBi 调试 与 MCU 运行 共存方案总结
单片机·嵌入式硬件·音频
学嵌入式的小杨同学2 小时前
STM32 进阶封神之路(二十一):DMA 深度解析 —— 从直接内存访问到无 CPU 干预数据传输(底层原理 + 寄存器配置)
stm32·单片机·嵌入式硬件·mcu·硬件架构·硬件工程·智能硬件
Hello World . .2 小时前
51单片机基础
单片机·嵌入式硬件·51单片机
’长谷深风‘3 小时前
51单片机入门(3:串口通信)
单片机·嵌入式硬件·51单片机·串口·串口通信
9稳3 小时前
基于智能巡检机器人与PLC系统联动控制设计
开发语言·网络·数据库·嵌入式硬件·plc
BackCatK Chen3 小时前
STM32U3B5/3C5深度解析:HSP加速器赋能边缘AI与DSP,超低功耗新标杆
人工智能·stm32·嵌入式硬件
_Ningye11 小时前
STM32 — 2.2 新建工程
stm32·单片机·嵌入式硬件
森利威尔电子-12 小时前
森利威尔SL3062替代 LM3485 60V降压恒压芯片
单片机·嵌入式硬件·集成电路·芯片·电源芯片