简介


闪存分配
基本结构

闪存存储器接口 ,也叫闪存编程和擦除控制器,即FPEC ,它相当于闪存的管理者,可以对闪存中的程序存储器和选项字节进行擦除和编程,注意不包括系统存储器,因为里面存放的是官方编写的启动程序bootloader,不能更改。
修改选项字节,就可以对程序存储器的读写保护进行配置。
FLASH解锁

FLASH中的内容是不能随意修改的,是默认锁住的,防止误操作。如果要对其进行写入,就要先解锁:向闪存存储器中的键寄存器KEYR先写入键值KEY1,再写入键值KEY2,这样才能解锁,如果操作不对会导致FPEC,CR寄存器锁死,直到复位。
写入完成以后也需要对FLASH进行加锁,设置CR寄存器的LOCK位锁住FPEC和CR寄存器。
指针访问

如果要使用指针读取指定地址下的存储器内容,可以如图操作。比如读取地址为0x0800 0000的存储器,它位于闪存中,写下地址后,进行强制类型转换为指针,想读取16位整型数据就转化为uint16_t *,想读取32位浮点数据就转换为float32_t *,这样指针就已经指向了这个地址,最后再来一个 * 就可以将指针指向的地址里内容取出来了。
__IO是宏定义,即volatile ,C语言的关键字,写在变量前面作用是防止变量被编译器优化,强制编译器每次都从内存中读取这个变量,而不是从寄存器读取。编译器优化就是编译器把写的代码转换为机器指令的时候,会自作主张改写代码逻辑,同时保证它以为的最终结果不变以提高程序运行效率。往往会将经常使用的变量存入寄存器中方便取值,而不去内存取值,这样速度更快,单线程中没问题,但如果变量值被硬件、中断函数等修改了,这种情况下寄存器里的值是不会变的,CPU读取的还是寄存器中未改变的值,程序就会出问题。
如果要使用指针写存储器内容,也是写下地址后进行强制类型转换,使指针指向地址,再一个 * 取出地址内容,最后将要写入的值赋给它就行了。但注意,闪存本来是只读的,如果要写入就需要较高的权限,需要先解锁,并搭配上后续操作才能写入。
写入操作流程

对闪存进行编程操作,先判断CR寄存器的LOCK位是否为1,即是否锁住,=1锁住就先解锁,=0没锁就配置CR寄存器的PG位=1,表示要进行写入操作,然后在指定地址写入半字的数据,即两个字节,注意一次只能写入半字,16位数据,写入后芯片直接开始工作了,接着就判断忙状态,忙状态结束就表示写入成功。
在写入之前必须先进行擦除,否则芯片不会写入,除非要写入的是0x0000。
页擦除流程

进行闪存的页擦除,同样先判断上锁没有,然后配置CR寄存器的PER=1,表示要页擦除,再在地址寄存器AR选择要擦除的页,最后置CR寄存器的STRT=1让芯片开始工作,再判断忙状态,忙状态结束即擦除成功。
全擦除流程

判断解锁,然后置CR寄存器的MER=1表示要全擦除,再置CR寄存器STRT=1让芯片开始,最后等待忙状态结束。
选项字节及操作流程

当写入RDP数据时要同时在nRDP写入数据反码,这样写入数据才算有效,其他位也一样。

在解除FLASH的锁之后,内部选项字节还有一个锁,必须解除才能编程/擦除选项字节,解锁步骤也是向CR寄存器的OPTWRE位先后写入KEY1,KEY2键值。

电子签名
