【STM32】读写内部Flash初步使用

news2024/11/25 4:45:50

基于stm32f103,作为个人学习记录使用

STM32 芯片内部有一个 FLASH 存储器,它主要用于存储代码,在紧急状态下常常会使用内部 FLASH 存储关键记录;
在这里插入图片描述

内部 FLASH 的构成

STM32 的内部 FLASH 包含主存储器系统存储器以及选项字节区域

大容量产品内部 FLASH 的构成(摘自《STM32F10x 闪存编程参考手册》
在这里插入图片描述

主存储器

一般我们说 STM32 内部 FLASH 的时候,都是指这个主存储器区域,它是存储用户应用程序的空间,芯片型号说明中的 256K FLASH、512K FLASH 都是指这个区域的大小。

主存储器分为 256 页,每页大小为 2KB,共 512KB。这个分页的概念,实质就是FLASH 存储器的扇区,与其它 FLASH 一样,在写入数据前,要先按页(扇区)擦除

不同容量的芯片,Flash的主存储器的页数量、页大小均有不同

系统存储区

系统存储区是用户不能访问的区域,它在芯片出厂时已经固化了启动代码,它负责实现串口、USB 以及 CAN 等 ISP 烧录功能。

选项字节

选项字节用于配置 FLASH 的读写保护、待机/停机复位、软件/硬件看门狗等功能,这部分共 16 字节。可以通过修改 FLASH 的选项控制寄存器修改。

查看keil工程的空间分布,确定空余空间

内部 FLASH 本身存储有程序数据,若不是有意删除某段程序代码,一般不应修改程序空间的内容。所以在使用内部 FLASH 存储其它数据前需要了解哪一些空间已经写入了程序代码,存储了程序代码的扇区都不应作任何修改。

通过.map文件,可以了解程序存储到了哪些区域。
打开方式
打开 map 文件后,查看文件最后部分的区域,可以看到一段以“Memory Map of the image”开头的记录。
在这里插入图片描述
这一段是某工程的 ROM 存储器分布映像,在 STM32芯片中,ROM 区域的内容就是指存储到内部 FLASH 的代码

1. 计算程序 ROM 的加载与执行空间

例子中
Load Region LR_ROM1:程序的加载空间 :Base 0x800 0000,Size:0x0000 17a8
Execution Region ER_IROM1:程序的执行空间: Base 0x0800 0000,Size:0x0000 177c

在芯片刚上电运行时,会加载程序及数据,例如它会从程序的存储区域加载到程序的执行区域,还把一些已初始化的全局变量从 ROM 复制到 RAM 空间,以便程序运行时可以修改变量的内容。加载完成后,程序开始从执行区域开始执行。

在上面 map 文件的描述中

加载及执行空间的基地址 (Base)都是0x08000000,它正好是 STM32 内部 FLASH 的首地址,也是 STM32 的程序存储空间就直接是执行空间;
它们的大小(Size)分别为 0x000017a8 及 0x0000177c,执行空间的 ROM 比较小的原因就是因为部分 RW-data 类型的变量被拷贝到 RAM 空间了;
拷贝RW到RAM中

最大空间(Max):0x00080000,即 512K 字节,此款STM32内部 FLASH 的最大空间。

用大的那个

计算程序占用的空间时,需要使用加载区域的大小进行计算,本例子中应用程序使用的内部 FLASH 是从 0x08000000 至(0x08000000+0x000017a8)地址的空间区域。

2. ROM 空间分布表

在加载及执行空间总体描述之后,紧接着一个ROM详细地址分布表,它列出了工程中的各个段(如函数、常量数据)所在的地址 Base Addr 及占用的空间 Size。在这里插入图片描述
Type 说明了该段的类型;
CODE 表示代码;
DATA 表示数据;
PAD 表示段之间的填充区域,它是无效的内容,PAD 区域往往是为了解决地址对齐的问题。
在这里插入图片描述
观察表中的最后一项,它的基地址是 0x0800175c,大小为 0x00000020,可知它占用的最高的地址空间为 0x0800177c,跟执行区域的最高地址 0x0000177c 一样,但它们比加载区域说明中的最高地址 0x80017a8 要小,所以我们以加载区域的大小为准。

所以这边一共使用了4k不到的空间,那么从第三页开始就可以作为其他功用了。

对内部 FLASH 的写入的一般过程

1.解锁

由于内部 FLASH 空间主要存储的是应用程序,是非常关键的数据,为了防止误操作修改了这些内容,芯片复位后默认会给控制寄存器 FLASH_CR 上锁,这个时候不允许设置FLASH 的控制寄存器,不能修改 FLASH 中的内容。
所以对 FLASH 写入数据前,需要先给它解锁。解锁的操作步骤如下:
(1) 往 FPEC 键寄存器 FLASH_KEYR 中写入 KEY1 = 0x45670123
(2) 再往 FPEC 键寄存器 FLASH_KEYR 中写入 KEY2 = 0xCDEF89AB

#define FLASH_KEY1 ((uint32_t)0x45670123)
#define FLASH_KEY2 ((uint32_t)0xCDEF89AB)

//对 FLASH 控制寄存器解锁,使能访问
void FLASH_Unlock(void)
 {
 if ((FLASH->CR & FLASH_CR_LOCK) != RESET) {
	 /* 写入确认验证码 */
	 FLASH->KEYR = FLASH_KEY1;
	 FLASH->KEYR = FLASH_KEY2;
 }}

顺带一提,给flash上锁的方法

void FLASH_Lock(void)
{
	FLASH->CR |= FLASH_CR_LOCK;/* 设置 FLASH 寄存器的 LOCK 位 */
}

2. 页擦除

在写入新的数据前,需要先擦除存储区域,STM32 提供了页(扇区)擦除指令和整个FLASH 擦除(批量擦除)的指令,批量擦除指令仅针对主存储区。
页擦除的过程:
(1) 检查 FLASH_SR 寄存器中的“忙碌寄存器位 BSY”,以确认当前未执行任何Flash 操作;
(2) 在 FLASH_CR 寄存器中,将“激活页擦除寄存器位 PER ”置 1;
(3) 用 FLASH_AR 寄存器选择要擦除的页;
(4) 将 FLASH_CR 寄存器中的“开始擦除寄存器位 STRT ”置 1,开始擦除;
(5) 等待 BSY 位被清零时,表示擦除完成。

/**
* @brief 擦除指定的页
* @param Page_Address: 要擦除的页地址.
* @retval FLASH Status:
可能的返回值: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
{
	 FLASH_Status status = FLASH_COMPLETE;
	 /* 检查参数 */
	 assert_param(IS_FLASH_ADDRESS(Page_Address));
	 /*...此处省略 XL 超大容量芯片的控制部分*/
	 /* 等待上一次操作完成 */
	 status = FLASH_WaitForLastOperation(EraseTimeout);
	 
	 if (status == FLASH_COMPLETE) {
	 /* 若上次操作完成,则开始页擦除 */
	 FLASH->CR|= CR_PER_Set;
	 FLASH->AR = Page_Address;
	 FLASH->CR|= CR_STRT_Set;
	 
	 /* 等待操作完成 */
	 status = FLASH_WaitForLastOperation(EraseTimeout);
	 
	 /* 复位 PER 位 */
	 FLASH->CR &= CR_PER_Reset;
	 }
 	 return status; /* 返回擦除结果 */
}

3. 写入数据

擦除完毕后即可写入数据,写入数据的过程并不是仅仅使用指针向地址赋值,赋值前还还需要配置一系列的寄存器,步骤如下:
(1) 检查 FLASH_SR 中的 BSY 位,以确认当前未执行任何其它的内部 Flash 操作;
(2) 将 FLASH_CR 寄存器中的 “激活编程寄存器位 PG” 置 1;
(3) 向指定的 FLASH 存储器地址执行数据写入操作,每次只能以 16 位的方式写入;
(4) 等待 BSY 位被清零时,表示写入完成。

/**
* @brief 向指定的地址写入一个字的数据(32 位)
* @param Address: 要写入的地址
* @param Data: 要写入的数据
* @retval FLASH Status:
可能的返回值: FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
 {
 FLASH_Status status = FLASH_COMPLETE;
 __IO uint32_t tmp = 0;
 
 /* 检查参数 */
 assert_param(IS_FLASH_ADDRESS(Address));
 /*...此处省略 XL 超大容量芯片的控制部分*/
 /* Wait for last operation to be completed */
 status = FLASH_WaitForLastOperation(ProgramTimeout);
 
 if (status == FLASH_COMPLETE) {
 /* 若上次操作完成,则开始页入低 16 位的数据(输入参数的第 1 部分) */
 FLASH->CR |= CR_PG_Set;
 
 *(__IO uint16_t*)Address = (uint16_t)Data;
 /* 等待上一次操作完成 */
 status = FLASH_WaitForLastOperation(ProgramTimeout);
 
 if (status == FLASH_COMPLETE) {
 /* 若上次操作完成,则开始页入高 16 位的数据(输入参数的第 2 部分) */
 tmp = Address + 2;
 
 *(__IO uint16_t*) tmp = Data >> 16;
 
 /* 等待操作完成 */
 status = FLASH_WaitForLastOperation(ProgramTimeout);
 
 /* 复位 PG 位 */
 FLASH->CR &= CR_PG_Reset;
 } else {
 /* 复位 PG 位 */
 FLASH->CR &= CR_PG_Reset;
 }

	}
 return status; /* 返回写入结果 */
 }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1043134.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

手机相机系统介绍

目录 一张照片是如何生成的? 相机的成像原理 相机硬件 颜色四要素 相机硬件三大块 模组结构 镜头 镜头光路 镜头常见参数 镜头-FOV&EFL 镜头-焦距 镜头-光圈 图像传感器 图像传感器-像素-底 RGB排布 图像传感器-Pattern & PDAF Sensor CMOS sensor …

Python中的单元测试与代码覆盖率:实践与问题解决

当我们开发软件时,单元测试和代码覆盖率是非常重要的工具。它们可以帮助我们验证代码的正确性,并确保代码的质量和稳定性。在Python中,我们有很多强大的工具和库来进行单元测试和代码覆盖率分析。本文将向你分享在Python中进行单元测试和代码…

C++单例模式各种实现方式,终极版即简单又线程安全,无脑用就完了

📋 前言 🖱 博客主页:在下马农的碎碎念🤗 欢迎关注🔎点赞👍收藏⭐️留言📝✍ 本文由在下马农原创,首发于CSDN📆 首发时间:2023/8/25📅 最近更新时…

学生宿舍管理系统(前端java+后端Vue)实现-含前端与后端程序

界面介绍 登录 ###宿舍管理 ###菜单管理 ###角色管理 ###班级管理

编程每日一练(多语言实现):判断偶数

文章目录 一、实例描述二、技术要点三、代码实现3.1 C 语言实现3.2 Python 语言实现3.3 Java 语言实现 一、实例描述 利用单条件单分支选择语句判断输入的一个整数 是否是偶数。 运行程序,输入一个 整数18, 然后按回车键,将提示该数字是偶数…

性能压力测试的定义及步骤是什么

在今天的数字化时代,软件系统的性能和稳定性对于企业的成功至关重要。为了确保软件在高负载和压力情况下的正常运行,性能压力测试成为了不可或缺的环节。本文将介绍性能压力测试的定义、步骤。 一、性能压力测试的定义和目标 性能压力测试是通过模拟实际…

Spring整合RabbitMQ——生产者

添加依赖坐标,在producer和consumer模块的pom文件中各复制一份。 配置producer的配置文件 配置producer的xml配置文件 编写测试类发送消息

[GXYCTF2019]BabySQli 1

进去就是两个登录框 先试了试adminadmin,然后显示wrong pass 试了下万能密码 1 or 11 查看下页面源代码 放到瑞士军刀解密一下 用fuzz字典跑一下 会发现order被过滤了 所以order用Order来过滤 admin Order by 3-- 得到字段数为3 然后判断一下注入点 判断得到这题…

ESD门禁闸机的用途及优点

ESD门禁闸机是一种专门用于防止静电干扰的门禁设备,其主要用途包括: 防止静电干扰:ESD门禁闸机可以有效地防止静电干扰,保护电子元器件、电路板等敏感设备不受静电破坏。 控制人员进出:ESD门禁闸机可以通过身份验证等…

后端配置(宝塔):处理php禁用函数

一、找到php的文件路径 在软件商店中,找到已安装文件,选择需要更改的php文件,选择“设置” 二、选择需要取消禁用的文件进行删除 扩展:可解决 The Process class relies on proc_open, which is not available on your PHP i nst…

deepin DTK(Development ToolKit)已正式适配 Qt6!

导读近日,深度 deepin 宣布 deepin DTK(Development ToolKit)已正式适配 Qt6 (6.4.2),实现全面升级。 DTK 作为 deepin 基于 Qt 开发的一整套简单且实用的通用开发框架,处于 deepin 操作系统中的核心位置,此…

基于YOLOv8模型的空中视角下车辆检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要:基于YOLOv8模型的空中视角下车辆检测系统可用于日常生活中检测与定位bus、cycle、truck、van、vehicle目标,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统…

[AFCTF 2018]你能看出这是什么加密么

最开始是我对rsa的小小的理解 rsa也就是非对称加密算法,拥有公开的加密密钥和解密密钥,这也是我们写脚本的基础 选取素数p和q,计算乘积npq,以及(n)(p-1)(q-1)。(欧拉函数) 选择一个e值作为密钥…

组合数4 高精度计算组合数

一般来说需要高精乘和高精除&#xff0c;但化简为质因子形式后只用高精乘。 一个阶乘n中因子p的个数&#xff1a; #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define endl \nusing namespace std;typedef pair<int, int&…

开源一个基于的rt-thread系统的烟感采集系统

一、硬件 CPU&#xff1a;stm32f401 NBIOT模块&#xff1a;移远BC26 存储&#xff1a;W25Q128JVSIQTR 扩展&#xff1a;HC595输出&#xff0c;165输入 二、软件应用 FAL&#xff1a;分区 littlefs: 应用存储用的文件系统 EashFlash&#xff1a;日记存储、系统变量存储 kawaii_…

AP2400 DC-DC降压恒流驱动器 汽车摩托LED大灯电源驱动 全亮半亮瀑闪三功能循环

产品特点 宽输入电压范围&#xff1a;5V&#xff5e;100V 可设定电流范围&#xff1a;10mA&#xff5e;6000mA 固定工作频率&#xff1a;150KHZ 内置抖频电路&#xff0c;降低对其他设备的 EMI干扰 平均电流模式采样&#xff0c;恒流精度更高 0-100%占空比控制&#xff0…

邮件功能-python中的SMTP协议邮件发送

文章目录 一、SMTP协议邮件准备二、smtplib模块1.使用smtplib封装一个邮件类2.发送邮件 补充 一、SMTP协议邮件准备 需要一个smtp服务器 二、smtplib模块 smtplib模块是python自带的模块 1.使用smtplib封装一个邮件类 import smtplib import logging # 加入日志&#xff…

向着趋势奔跑:银行客户中心转型,重构商业模式是关键

随着金融市场化改革的推进 国内银行同业间的竞争日趋激烈 各商业银行在全新的监管要求和市场环境下 纷纷开始推行“以客户为中心”的经营新模式 迅速提升核心竞争力 然而&#xff01;&#xff01;&#xff01; 奇怪的事情发生了 &#x1f447; &#x1f447; &#x1f44…

DP读书:《openEuler操作系统》(三)操作系统的分类

操作系统的发展趋势 微内核库操作系统外内核多内核离散化内核openEuler操作系统简介 操作系统处于应用层与硬件层之间&#xff0c;上看应用、下看硬件。 应用层上&#xff0c;无人驾驶、工业驾驶等场景中&#xff0c;操作系统的可靠性被放在更重要的位置&#xff0c;微内核更受…

即刻报名!飞桨黑客马拉松第五期开启,创新挑战等你来!

新赛制&#xff0c;新玩法 飞桨黑客马拉松第五期 全新挑战&#xff0c;重磅回归&#xff01; 开源贡献个人挑战赛、大模型应用与创意赛、飞桨护航计划集训营 三大赛道&#xff0c;邀你挑战&#xff01; 多难度梯度开源任务、大模型应用创意挑战、导师1V1指导开发实践 硬核较量一…