当前位置: 首页 > news >正文

【STM32】FLASH闪存

【STM32】FLASH闪存

  • 一、FLASH简介
  • 二、闪存模块组织
  • 三、FLASH基础操作
    • 3.1 FLASH基本结构
    • 3.2 FLASH解锁
    • 3.3 使用指针访问存储器
  • 四、程序存储器
    • 4.1 全擦除
    • 4.2 页擦除
    • 4.3 编程
  • 五、选项字节
    • 5.1 组织结构
    • 5.2 选项字节编程
    • 5.3 选项字节擦除
  • 六、器件电子签名


一、FLASH简介

  • STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分,通过闪存存储器接口(外设)可以对程序存储器和选项字节进行擦除和编程
  • 读写FLASH的用途:
    利用程序存储器的剩余空间来保存掉电不丢失的用户数据
    通过在程序中编程(IAP),实现程序的自我更新
  • 在线编程(In-Circuit Programming – ICP)用于更新程序存储器的全部内容,它通过JTAG、SWD协议或系统加载程序(Bootloader)下载程序
  • 在程序中编程(In-Application Programming – IAP)可以使用微控制器支持的任一种通信接口下载程序

二、闪存模块组织

在这里插入图片描述

1. 主存储器
主存储器以“”为单位组织,是闪存中用于存储用户程序、数据的主要区域。

  • 页的数量与容量:从“页0”到“页127”,共128页;每页长度为1K字节(即1024字节)
  • 地址范围规律:每页地址跨度为0x400(因为0x0800 0400 - 0x0800 0000 = 0x400,对应1024字节)。例如:
    • 页0:0x0800 0000 – 0x0800 03FF
    • 页1:0x0800 0400 – 0x0800 07FF
    • ……
    • 页127:0x0801 FC00 – 0x0801 FFFF
  • 功能:用于存放用户的应用程序代码、运行时数据等,是程序执行的核心存储区域。

2. 信息块
信息块用于存储系统级的关键信息,包括启动程序和用户配置数据。

  • 启动程序代码
    • 地址范围:0x1FFF F000 – 0x1FFF F7FF
    • 长度:2K字节(2048字节)
    • 功能:存储系统启动时的初始化程序(如Bootloader),负责引导主存储器中的应用程序运行。
  • 用户选择字节
    • 地址范围:0x1FFF F800 – 0x1FFF F80F
    • 长度:16字节
    • 功能:存储用户自定义的配置信息(如系统参数、功能选项等),供程序运行时读取或修改。

3. 闪存存储器接口寄存器
这部分是操作闪存的硬件寄存器集合,通过对这些寄存器的读写,可实现闪存的擦除、编程、状态查询等操作。每个寄存器长度为4字节(32位),地址连续且跨度为0x4(符合32位寄存器的地址对齐要求)。

寄存器名称地址范围功能简述
FLASH_ACR0x4002 2000 – 0x4002 2003闪存访问控制寄存器,配置闪存的访问周期等
FLASH_KEYR0x4002 2004 – 0x4002 2007闪存密钥寄存器,用于解锁闪存的编程/擦除操作
FLASH_OPTKEYR0x4002 2008 – 0x4002 200B选项字节密钥寄存器,用于解锁选项字节的操作
FLASH_SR0x4002 200C – 0x4002 200F闪存状态寄存器,指示闪存的忙、错误等状态
FLASH_CR0x4002 2010 – 0x4002 2013闪存控制寄存器,触发闪存的编程、擦除等操作
FLASH_AR0x4002 2014 – 0x4002 2017闪存地址寄存器,指定编程/擦除的目标地址
保留0x4002 2018 – 0x4002 201B预留地址,用户不可操作,用于硬件扩展或未来功能
FLASH_OBR0x4002 201C – 0x4002 201F选项字节寄存器,存储闪存的配置选项(如读写保护)
FLASH_WRPR0x4002 2020 – 0x4002 2023写保护寄存器,配置闪存的区域写保护功能

4. 总结

  • 「主存储器」是用户程序/数据的“主战场”;
  • 「信息块」是系统启动和用户配置的“专属区”;
  • 「闪存存储器接口寄存器」是操作闪存的“控制中心”,通过软件读写这些寄存器,可完成闪存的擦写、状态查询等底层操作。

三、FLASH基础操作

3.1 FLASH基本结构

在这里插入图片描述

  • 闪存存储器接口/闪存编程和擦除控制器(FPEC):是操作闪存的“控制核心”,负责执行闪存的擦除、编程(写入)等操作。
  • 程序存储器(C8T6-64K):用于存储用户应用程序,以“页”为单位组织,每页1K字节,从0x0800 0000开始,包含页0、页1……页63等(图中展示了部分页的地址和容量)。
  • 系统存储器:存储Bootloader(启动程序),地址0x1FFF F000,容量2K字节,负责系统启动时的程序引导。
  • 选项字节:地址0x1FFF F800,容量16字节,用于存储闪存的配置信息(如读写保护、功能选项等)。

3.2 FLASH解锁

1. FPEC键值说明
FPEC(闪存编程和擦除控制器)通过“键值验证”实现操作权限控制,共有三个关键键值:

  • RDPRT键(0x000000A5):用于选项字节(如读写保护配置)的操作解锁。
  • KEY1(0x45670123)和KEY2(0xCDEF89AB):用于主闪存(程序存储器、信息块)的编程/擦除操作解锁,是最常用的闪存操作权限密钥。

2. 解锁:

  • 复位后,FPEC 被保护,不能写入 FLASH_CR
  • 在 FLASH_KEYR 先写入 KEY1,再写入 KEY2,解锁
  • 错误的操作序列会在下次复位前锁死 FPEC 和 FLASH_CR
    3. 加锁:
  • 设置 FLASH_CR 中的 LOCK 位锁住 FPEC 和 FLASH_CR

在库函数中都有对应操作函数,直接调用即可

3.3 使用指针访问存储器

  • 使用指针读指定地址下的存储器:
    uint16_t Data = *((__IO uint16_t *)(0x08000000));
  • 使用指针写指定地址下的存储器:
    *((__IO uint16_t *)(0x08000000)) = 0x1234;
  • 其中:
    #define __IO volatile
    在 C 语言中,volatile是一个类型修饰符,它的核心作用是告诉编译器,被它修饰的变量的值可能会在程序未明确修改的情况下被意外改变。__IO被定义为volatile,就是为了确保对硬件地址(如0x08000000对应的 FLASH 或寄存器)的读写操作不会被编译器优化,保证每次都实际访问硬件层的存储单元。

四、程序存储器

4.1 全擦除

在这里插入图片描述

  • 步骤1:检查锁定状态
    读取FLASH_CR寄存器的LOCK位,判断闪存是否处于锁定状态。若LOCK位=1,需先执行“解锁过程”(如之前介绍的写入KEY1和KEY2)。
  • 步骤2:触发全擦除操作
    LOCK位=0(已解锁),设置FLASH_CRMER位(全擦除使能)和STRT位(启动擦除),触发整个程序存储器的擦除操作。
  • 步骤3:等待擦除完成
    持续检查FLASH_SR寄存器的BSY位(忙标志),若BSY位=1,说明擦除仍在进行,需等待;若BSY位=0,表示擦除完成。
  • 步骤4:验证擦除结果
    读出并验证所有页的数据,确认是否均被擦除为0xFF(闪存擦除后的默认值)。
/*** 函    数:FLASH全擦除* 参    数:无* 返 回 值:无* 说    明:调用此函数后,FLASH的所有页都会被擦除,包括程序文件本身,擦除后,程序将不复存在*/
void MyFLASH_EraseAllPages(void)
{FLASH_Unlock();					//解锁FLASH_EraseAllPages();			//全擦除FLASH_Lock();					//加锁
}

4.2 页擦除

在这里插入图片描述
步骤与全擦除类似,多一个传参,传入页地址

/*** 函    数:FLASH页擦除* 参    数:PageAddress 要擦除页的页地址* 返 回 值:无*/
void MyFLASH_ErasePage(uint32_t PageAddress)
{FLASH_Unlock();					//解锁FLASH_ErasePage(PageAddress);	//页擦除FLASH_Lock();					//加锁
}

4.3 编程

在这里插入图片描述

  • 步骤1:检查锁定状态
    读取FLASH_CR寄存器的LOCK位,判断闪存是否锁定。若LOCK位=1,需先执行“解锁序列”(如写入KEY1和KEY2)。
  • 步骤2:使能编程功能
    LOCK位=0(已解锁),设置FLASH_CRPG位(编程使能)。
  • 步骤3:写入数据
    在指定地址写入16位的“半字”数据。
  • 步骤4:等待编程完成
    持续检查FLASH_SR寄存器的BSY位(忙标志),BSY位=1表示编程进行中,需等待;BSY位=0表示编程完成。
/*** 函    数:FLASH编程字* 参    数:Address 要写入数据的字地址* 参    数:Data 要写入的32位数据* 返 回 值:无*/
void MyFLASH_ProgramWord(uint32_t Address, uint32_t Data)
{FLASH_Unlock();							//解锁FLASH_ProgramWord(Address, Data);		//编程字FLASH_Lock();							//加锁
}/*** 函    数:FLASH编程半字* 参    数:Address 要写入数据的半字地址* 参    数:Data 要写入的16位数据* 返 回 值:无*/
void MyFLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
{FLASH_Unlock();							//解锁FLASH_ProgramHalfWord(Address, Data);	//编程半字FLASH_Lock();							//加锁
}

五、选项字节

5.1 组织结构

在这里插入图片描述

  • RDP:写入RDPRT键(0x000000A5)后解除读保护
  • USER:配置硬件看门狗和进入停机/待机模式是否产生复位
  • Data0/1:用户可自定义使用
  • WRP0/1/2/3:配置写保护,每一个位对应保护4个存储页(中容量)

5.2 选项字节编程

  • 检查FLASH_SR的BSY位,以确认没有其他正在进行的编程操作
  • 解锁FLASH_CR的OPT WRE位
  • 设置FLASH_CR的OPTPG位为1
  • 写入要编程的半字到指定的地址
  • 等待BSY位变为0
  • 读出写入的地址并验证数据

5.3 选项字节擦除

  • 检查FLASH_SR的BSY位,以确认没有其他正在进行的闪存操作
  • 解锁FLASH_CR的OPT WRE位
  • 设置FLASH_CR的OPTER位为1
  • 设置FLASH_CR的STRT位为1
  • 等待BSY位变为0
  • 读出被擦除的选择字节并做验证

六、器件电子签名

  • 电子签名存放在闪存存储器模块的系统存储区域,包含的芯片识别信息在出厂时编写,不可更改,使用指针读指定地址下的存储器可获取电子签名
  • 闪存容量寄存器:
    基地址:0x1FFF F7E0
    大小:16位
  • 产品唯一身份标识寄存器:
    基地址:0x1FFF F7E8
    大小:96位

有关【STM32】FLASH闪存 就到这,希望对你有所帮助,感谢观看!

码文不易,留个赞再走吧~

http://www.dtcms.com/a/549641.html

相关文章:

  • 东莞网站关键词推广义乌百度推广公司
  • Spring远程调用与Web服务全解析
  • 手机站喝茶影视茂名市建设银行网站
  • 青岛做网站公司排名淄博网站建设yx718
  • 303-Spring AI Alibaba NL2SQL 向量管理示例
  • 【CVPR 2025】即插即用GBC模块:小体积,大能量,重塑特征提取新范式
  • Linux系统编程 -- 进程概念(一)
  • React 入门 02:从单页面应用到多页面应用
  • 石家庄网站建设找哪家好河西网站建设优化seo
  • h5网站怎么做api对接赣州人才招聘网
  • 生产管理系统详解:物料清单bom 工序,工艺路线中的工序和工艺资源他们之间有什么关联和区别
  • 发布元服务配置应用分类、标签和资质信息(仅分发手表设备)
  • 成绩查询系统如何制作?
  • 中国建设银行信用卡官网站首页个人做商机网站如何盈利
  • springboot酒店客房管理系统设计与实现(代码+数据库+LW)
  • 交叉编译工具链深度解析 --静态库与动态库编译实战指南
  • uni-app 开发APP应用媒体处理与文件管理功能
  • 网站建设scyiyou百度竞价推广一个月多少钱
  • 基于整数MCU的FOC控制定标策略深度解析
  • [HDiffPatch] 差异算法 | `serialize_compressed_diff`
  • Pycatia二次开发基础代码解析:实例名称获取与几何显示控制技术解析
  • 小迪安全v2023学习笔记(一百四十天)—— Linux系统权限篇VulnhubPATH变量NFS服务Cron任务配合SUID
  • 做网站前端wordpress打字烟花
  • 新能源汽车动力系统拆装与检测实训MR软件介绍-比亚迪秦EV标准版
  • 力扣:214. 最短回文串(Python3)
  • 基于Jdk17+SpringBoot3AI智慧教育平台,告别低效学习,AI精准导学 + 新架构稳跑
  • 论坛网站太难做没人百度推广客户端app
  • Shell实用实例2
  • Go语言:解决 “package xxx is not in std”的思路
  • 给排水干管工程量-连续测量得心应手