Flash地址空间的数据读取——STM32

本文介绍了STM32内部FLASH的组成与应用,包括主存储块和信息块的作用,并通过实例演示了如何在STM32内部FLASH中保存数据,即使在断电后也能保持不变。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在嵌入式应用开发中,经常会遇到掉电后还要保存的信息,这些信息通常只能保存在外部的一些存储芯片中,如外部flash,外部EEPROM, 其实这些信息同样可以保存在STM32自带的内部flash中

一、STM32 的内部 FLASH 简介

在 STM32 芯片内部有一个 FLASH 存储器,它主要用于存储代码,我们在电脑上编写好应用程序后,使用下载器把编译后的代码文件烧录到该内部 FLASH 中,由于 FLASH 存储器的内容在掉电后不会丢失,芯片重新上电复位后,内核可从内部 FLASH 中加载代码并运行。

根据用途,STM32 片内的 FLASH 分成两部分:主存储块信息块
主存储块用于存储程序,我们写的程序一般存储在这里;
信息块又分成两部分:系统存储器、选项字节。 系统存储器存储用于存放在系统存储器自举模式下的启动程序(BootLoader),当使用 ISP 方式加载程序时,就是由这个程序执行。这个区域由芯片厂写入 BootLoader,然后锁死,用户是无法改变这个区域的。 选项字节存储芯片的配置信息及对主存储块的保护信息。
在这里插入图片描述
除了使用外部的工具(如下载器)读写内部 FLASH 外,STM32 芯片在运行的时候,也能对自身的内部 FLASH 进行读写,因此,若内部 FLASH 存储了应用程序后还有剩余的空间,我们可以把它像外部 SPI-FLASH 那样利用起来,存储一些程序运行时产生的需要掉电保存的数据。

由于访问内部 FLASH 的速度要比外部的 SPI-FLASH 快得多,所以在紧急状态下常常会使用内部 FLASH 存储关键记录;为了防止应用程序被抄袭,有的应用会禁止读写内部FLASH 中的内容,或者在第一次运行时计算加密信息并记录到某些区域,然后删除自身的部分加密代码,这些应用都涉及到内部 FLASH 的操作。

二、工程验证

flash工程下载链接:https://pan.baidu.com/s/11Tn8TocHT8qithneDyKFIQ
提取码:pmvn

下载完成后打开文件夹,将路径stm32_Flash\Drivers\CMSIS\Device\ST\STM32F1xx\Include下的system_stm32f1xx_20190722_092746.h文件修改为system_stm32f1xx.h,否则后面编译会报错
在这里插入图片描述
修改好后,打开工程,可以将想要存入Flash中的内容修改为自定义内容

uint8_t FlashTest[] = "Hello!631907030123";

编译无报错在这里插入图片描述
进行程序调试前,先完成配置:
注意:下载的工程代码调试用的是硬件 st-link debuger,不是软件仿真,因此用软件仿真做,可能情况略有不同(小编这里软件仿真就没有出现结果)
点击Options->Debug->右边使用硬件ST-Link Debugger
在这里插入图片描述
接着点击S T-Link Debugger右边的Settings
在这里插入图片描述
进入到Cortex-M Target Driver SetupDebug页面,其中的Port选择为SW
在这里插入图片描述
依次点击Flash Download->勾选Reset and Run->Add->选择STM32F10x Med-density Flash->Add->确定即可
在这里插入图片描述
最后点击OK完成硬件配置

由于要连接硬件ST-Link,所以要下载一个STLink驱动,不然下载不成功

链接:https://pan.baidu.com/s/13k0PVQfg5qAHXBKJ2IZiYA
提取码:1234

连线如下图
在这里插入图片描述
点击左上角的LOAD按钮将程序下载到STM32中
在这里插入图片描述
现在点击dubug按钮,进入硬件仿真调试
在这里插入图片描述
点击View->memory windows->memory 1打开内存观察窗口,并在地址栏中输入:0x800C000,观察将要修改的flash区间区容:
在这里插入图片描述
其中点击某一字符右击可选择显示格式
在这里插入图片描述
继续View->Watch windows->Watch 1打开一个变量观察窗口
在这里插入图片描述
将变量FlashWBuffFlashRBuff加入到Watch 1观察窗口
在这里插入图片描述
在这里插入图片描述
另外View->勾选Periodic Windows Update,开启变量自动更新
在这里插入图片描述
按如图所示的全速运行按钮或者F5
在这里插入图片描述
这时就可以看到Watch 1窗口的数组FlashRBuff中的内容与数组FlashWBuff中的内容是一样的
在这里插入图片描述
同时在Memory 1窗口中可以看到在FLASH地址0x0800C000区成功写入对应内容
在这里插入图片描述
断电后再重新上电进行调试,程序停在main入口处时还可以看到Flash对应区间的内容保持上一次写入内容值
在这里插入图片描述

三、小结

完成本次实验内容后,对STM32 的内部 FLASH 有了一定的了解,明白了FLASH 的基本功能后,以后基于STM32的开发就可以省去一些外部FLASH或EEPROM了。

四、参考链接

1.https://blog.csdn.net/zhanglifu3601881/article/details/96632971
2.https://www.eefocus.com/embedded/399467

### STM32C8T6 Flash数据读取与写入 为了实现在STM32C8T6上从指定地址读取Flash中的数据并将其写入到另一个指定地址,需遵循特定的操作流程。此过程涉及配置闪存接口、解锁闪存编程/擦除控制寄存器以及执行实际的读写操作。 #### 配置环境 确保已通过STM32CubeMX创建好工程文件,并完成必要的外设初始化设置[^1]。对于Flash操作而言,重要的是要包含`stm32f1xx_hal_flash.h`头文件以便访问相应的API函数。 #### 解锁Flash编程/擦除功能 在进行任何更改之前,必须先解除对Flash存储区保护状态: ```c HAL_FLASH_Unlock(); ``` #### 定义源目标地址变量 定义两个指针类型的变量用于指向源和目的地址位置: ```c uint32_t sourceAddress = 0x08000000; // 源起始地址, 用户可根据需求调整 uint32_t destinationAddress = 0x0800FFFF; // 目的地起始地址, 同样可以根据实际情况设定 ``` 注意:上述地址仅为示例用途,请根据具体应用场景选取合适的内存区域作为源和目的地。 #### 执行读取与写入逻辑 接下来编写具体的读取与写入逻辑。考虑到安全性和稳定性因素,在每次写入前应确认当前页面未被锁定,并且新内容不会覆盖已有有效信息。此外,由于Flash一次只能按页或扇区单位来擦除,因此可能还需要额外处理这些细节。 以下是简化版的例子展示如何逐字节复制一段固定长度的数据块: ```c #define DATA_LENGTH 16 /* 要传输的数据量 */ uint8_t buffer[DATA_LENGTH];/* 中间缓冲数组 */ // 将数据从sourceAddress加载至buffer中 for(int i=0;i<DATA_LENGTH;i++){ *(volatile uint8_t*)(buffer+i)=*(volatile uint8_t*)(sourceAddress+i); } // 准备向destinationAddress写入数据 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR); if(HAL_OK != HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, destinationAddress, *buffer)){ Error_Handler(); // 如果发生错误则调用错误处理器 } else{ for(int j=1;j<DATA_LENGTH;j++){ // 继续后续各字节的写入 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR); if(HAL_OK != HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, destinationAddress+j, *(buffer+j))){ Error_Handler(); } } } ``` 这段代码展示了基本思路——即先读再写的模式;然而实践中往往更倾向于采用批量方式提高效率,比如一次性处理整个半页甚至整页的内容而不是单个字节。这不仅减少了循环次数也降低了潜在的风险。 #### 锁定Flash编程/擦除权限 当所有预期的任务完成后记得重新锁定Flash防止意外修改: ```c HAL_FLASH_Lock(); ``` 以上便是关于如何利用STM32标准库实现简单Flash读写的一个概述性介绍。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值