【STM32+cubemx】0015 HAL库开发:内部flash读写
本节我们来学习stm32内部flash的读写。在某些应用中,我们需要保存少量掉电仍然不丢失的数据,而在电路板上额外增加一块eeprom或者flash又太浪费硬件资源,这时我们就可以把这些数据保存在stm32内部的flash里。
1)stm32内部flash简介
我们先来了解一下stm32内部的存储结构,如下图所示:
stm32的复位地址是从0x0000 0000开始。
flash地址起始于0x0800 0000,结束地址是0x0800 0000加上芯片实际的flash大小,不同的芯片flash大小不同;程序存储在这个区域,stm32芯片会自动将0x0800 0000与0x0000 0000映射,所以,软件编译生成的目标文件烧写到这个区域,复位之后就可以执行。
RAM起始地址是0x2000 0000,结束地址是0x2000 0000加上芯片的RAM大小,不同的芯片RAM也不同。
如keil中生成的配置,stm32芯片的flash(ROM)是从0x08000000开始的,RAM是从0x20000000开始的,选择不用芯片时,大小是不同的:
Stm32芯片烧写时,就是将软件编译生成的目标代码,烧写到0x08000000地址起始的flash中,如果目标代码小于芯片flash的容量,则最后一段flash就是空闲的。这一段空闲区域就可以用来存储用户的数据,实现掉电不丢失。
2)stm32内部flash的使用
我们仍然以串口的工程为基础,低功耗模式本身不需要特殊设置,生成HAL库工程文件时都会自带,直接使用串口工程即可。
先定义几个宏,用于指定分配给用户读写flash的区域:
主要是定义用户flash的起始地址、结束地址、可用页数(这里使用的芯片是stm32f103c8t6,内部flash总共64k,每页为1k,把最末尾的2页分配给用户使用)。
编写代码,先看读取flash的代码:
这个函数实现从用户flash起始地址读取num个32bit的数,放在DATA_32区域中;读取flash的过程,本质上是把要读取的flash地址转换为指针,然后获取该指针指向的数据。
再来看写入flash的函数,实现把DATA_32区域中的num个32bit的数据写入到用户存储区。
这个函数主要分两部分,擦除和写入;在擦除和写入前,为了保护flash不被误操作,还需要解锁flash;在擦除和写入后,需要重新给flash上锁:
函数内部的调用解锁、擦除、写入、上锁各个函数都是HAL库提供的,使用很方便。
主函数中,我们添加测试代码,循环擦除、写入、再读取打印,每次写入的数据都是上次读出的数据加1:
运行结果如下图:
可以看到,读出的数据是正确的。
3)stm32内部flash读写的注意事项
使用内部flash需要注意几点:
a)0x08000000起始的一段已被程序占用,用户区域最好从flash区的末尾使用,不能与已使用的部分冲突;由于程序也烧写在flash区,用户在擦写flash时,如果操作不当会损坏固化的程序;所以用户程序要谨慎处理;
b)Flash需要先擦除,再写入;可以一次擦除,分若干次向不同的地址写入;
c)Flash擦除的最小单位是页,也就是每次一擦除,都会把擦除地址所在页的整页数据擦掉;
注意不同系列的stm32芯片,内部的flash分页大小也不同:
小容量产品:主存储块1-32KB,每页1KB
中容量产品:主存储块64-128KB,每页1KB
大容量产品:主存储块256KB以上,每页2KB
互联型产品:主存储块256KB以上,每页2KB
d)Flash擦除和写入的速度慢,有的需要几十ms,一般要留足时间,并且尽量不要被打断;
e)Flash有擦写次数限制,手册中给的数据是1W次;读取次数不限。
欢迎关注我的公众号,可留言“资料”获取相关资料和软件: