洋桃电子STM32F407单片机入门教程笔记二:嵌入式Flash读写详解

此文档作为对洋桃电子STM32F407单片机视频的整理,B站链接:第16集)嵌入式Flash读写_哔哩哔哩_bilibili

1. Flash的概述及注意事项

在单片机内部集成了一块单片机存储器,相当于电脑的硬盘,可以存放我们下载的代码也可以存储程序运行中的临时数据,Flash存储器的特色是写入的数据在断电后不会丢失,但其写入速度比SRAM慢,所以我们的用户程序先下载到Flash存储器,单片机运行时的临时数据比如功能寄存器的操作、变量数值的修改都放在SRAM存储器中。但SRAM存储器中的数据掉电会丢失。当需要把临时数据保存则可以把临时数据写入Flash存储器。Flash读写功能就是在用户程序运行过程中自己操作Flash的数据读写。

此功能在项目中的应用:注意:Flash存储器有擦除寿命问题,主流芯片制造工艺的厂商的质保擦除约10万次,超出最大次数将会导致擦写不稳定的问题(保存时间短、擦除不彻底、无法擦除)超过10万次并不是不能使用,只是会有不稳定的问题。重要的项目开发都会尽量避免不稳定因素,也就会避免频繁擦写Flash。

2.  Flash在单片机内部的连接

从上图中可以看出Flash存储器与内核、SRAM等核心功能都都挂接在AHB总线上,是单片机的核心功能之一,另外 Flash存储器需要有具体的读写地址。所以涉及到单片机整体的地址映射表如下图所示。

图中列出了STM32F407单片机所有地址分布关系,由于STM32系列是32位单片机最大寻址可达OXFFFFFFFF,所以在图的左侧从最小地址0x00000000到最大地址OXFFFFFFFF,平均分成8个区块 从block0到block7,每个区块的地址被规定用于不同的功能,我们的Flash存储器被划分在block0区块中。

从上图中可以看出block0的地址从0x00000000到0X1FFFFFFF共划分成10个子区块,其中0x08000000~0x080FFFFF被指定为1MB容量的Flash存储器地址,我们对Flash的所有读写操作要在此地址区间内完成,而Flash存储器的内部又被划分成多个扇区。        

表格中的“主存储器”区块就是Flash存储器的地址范围,STM32F407ZG芯片的Flash存储器为1MB,有效地址从0x08000000~0x080FFFFF,这里将地址范围不均等地划分成12个扇区(从扇区0到扇区11),其中扇区0~3的地址空间是16KB,扇区4的地址空间是64KB,扇区5~11的地址空间是128KB。之所以如此设计是因为Flash存储器在写入数据之前必须进行擦除操作,而由于硬件电路的限制不能单个字节擦除必须以扇区为单位擦除,那怕只想修改某个扇区里的一个字节也需要将整个扇区擦除,再把修改好的所有数据重新新写入,由于扇区越大擦除速度越慢,所以不同大小的扇区给我们选择的余地,数据量少或要求快速写入数据就可存放在16KB小扇区中,数据量大或不要求写入速度的数据就可存放在128KB大扇区中。表格中也给出了每个扇区的起始地址和结束地址,一次写入的数据最好放在同一扇区中。

主存储器区块是用于存放我们下载的单片机程序也叫用户程序,用户程序从0x08000000地址开始写入,根据用户程序自身的大小占用的Flash扇区数量也不同,假如用户程序只占用了扇区0~2,那么余下扇区3~11未使用,这些空白扇区就可存放用户临时数据。

为了防止用户程序与临时数据之间产生相互覆盖的问题,一般都会在两组数据之间空出几个扇区。如下图所示。

系统存储器是存放BootLoader程序的区域,使用Flymcu软件下载程序,就是切换到系统存储器BootLoader程序来完成的。

OTP是一次性可编程存储区块共有528个字节,向这个区块写入数据后并锁定字节操作,OTP区块中的数据将永久无法更改,OTP区块可用于产品ID码或其他一次性写入数据的场合。

选项字节是单片机的一些特殊功能设置字节,通过向选项字节写入指定数据来设置与Fash存储器有关的功能,选项字节的设置可以在Flymcu软件下载程序时一并完成。

RDP:读保护功能,WRP写保护功能,用户选项字节。

RDP占用一个字节,写入0XAA则设置为LEVELO最低保护级别,写入0xCC设置为LEVEL2最高保护级别,写入其他数值时设置为LEVEL1一般保护级别。

需要注意的是RDP一旦设置成level 2将无法再切换到其他级别处于锁死状态,使用时需特别小心,设置完成后单击ok,再次下载程序时选项字节将一同完成设置,不设置RDP字节时默认为level 1读保护状态。

WRP写保护功能是可对Flash存储中的12个扇区进行独立写保护,被开启写保护的扇区将无法写入数据。

用户选项字节是设置看门狗 省电模式和复位功能的。

3. 编程实例:

3.1 main.c文件开始部分

已知编写的用户程序小于16kb,只占用了扇区0的一部分。理论上用户临时数据可以存放在扇区1-11中的任何一个,为了方便后续加大用户程序,又因为扇区4擦除时间慢,选择从第三个扇区开始存放临时保存的数据。扇区3的地址范围是0x0800C000到0x0800FFFF,临时数据可存放在其中任意地址,第37行的地址定义中随便存放在0x0800C001地址里。

在主函数中定义一个通用变量a

第92行代码中先从Flash存储器相应地址中先读出LED开关状态,然后用开关状态值控制LED的状态。

添加按键触发Flash写入程序以上部分就实现了上电读取Flash存储器中的值并改变LED状态,在循环中检测按键状态写入Flash存储器的值。

3.2 Flash.c文件中的内容

这个函数主要是输入一个地址来判断这个地址在拿个扇区里面,比如第11行,如果输入的地址小于扇区1的起使地址则说明该输入地址在扇区0。

4. 读取Flash容量信息

如果要将同一个应用程序下载到不同Flash大小的单片机,可以通过读Flash大小寄存器,芯片在出厂时会把Flash容量值写入此寄存器且不可修改。

作者:嘴角那抹倔强的微笑

物联沃分享整理
物联沃-IOTWORD物联网 » 洋桃电子STM32F407单片机入门教程笔记二:嵌入式Flash读写详解

发表评论