文章目录
- 前言
- 首先来回顾一下存储器映像
- FLASH简介
- 闪存模块组织
- Flash基本结构(关系)图
- Flash解锁
- 使用指针访问存储器
- FLASH操作
- Flash全擦除
- Flash页擦除
- Flash写入
- 选项字节
- 选项字节操作
- 选项字节擦除
- 选项字节写入
- 器件电子签名
- 注意
- 闪存控制寄存器一览
前言
本文主要解释的为STM32的内部闪存(非易失性存储器)
首先来回顾一下存储器映像
本文就是对于ROM类型的说明,包括Flash、系统存储器(原厂写入,一般不修改)、选项字节等
FLASH简介
- STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分,通过闪存存储器接口(外设)可以对程序存储器和选项字节进行擦除和编程读写
- FLASH的用途:
利用程序存储器的剩余空间来保存掉电不丢失的用户数据 通过在程序中编程(IAP),实现程序的自我更新 - 在线编程(In-Circuit Programming –
ICP)用于更新程序存储器的全部内容,它通过JTAG、SWD协议或系统加载程序(Bootloader)下载程序 - 在程序中编程(In-Application Programming – IAP)可以使用微控制器支持的任一种通信接口下载程序(不研究)
闪存模块组织
注意各块的首地址规律,以便方便的找到首地址进行写入和区分块,对页的操作一般都以某页页首地址开始,写操作不能跨页,读操作可以跨页
Flash基本结构(关系)图
Flash解锁
对于这些需要保存在flash的重要数据,需要有安全的保护措施,STM32Flash也设置了特殊的安全设置:
FPEC共有三个键值:
- RDPRT键 = 0x000000A5
- KEY1 = 0x45670123
- KEY2 = 0xCDEF89AB
解锁:
- 复位后,FPEC被保护,不能写入FLASH_CR
- 在FLASH_KEYR先写入KEY1,再写入KEY2,解锁
- 错误的操作序列会在下次复位前锁死FPEC和FLASH_CR
加锁:
- 设置FLASH_CR中的LOCK位锁住FPEC和FLASH_CR
使用指针访问存储器
因为STM32的内部存储器都是挂载到总线上的,可以直接使用指针读取到
- 使用指针读指定地址下的存储器:
uint16_t Data = *((__IO uint16_t *)(0x08000000)); - 使用指针写指定地址下的存储器(需要先解锁):
*((__IO uint16_t *)(0x08000000)) = 0x1234; - 其中: #define __IO volatile
用于防止编译器优化,例如编译器会把它认为无用的内容给优化掉(如空循环等),那加上这个宏定义就可以避免内容被优化掉,keil默认是低级优化,一般没有影响,若提高了优化等级就需要注意加上这个宏定义。还有例如需要多次使用某变量,编译器会把变量先存在高速缓存中,执行结束后再存回内存,若代码为多线程,中途使用中断修改了此变量,而高速缓存中此变量并没有改变,会导致错误,此时加上这个宏定义,表示此变量为易变变量,要直接去内存找,就可以避免这种错误
FLASH操作
Flash全擦除
Flash页擦除
Flash写入
再写入前会先检查此地址是否擦除,未擦除则不写入
每次只能写入半字(16位)数据
写入使用指针写入即可
选项字节
以上带n的是不带n的反码,由电路自动配置
- RDP:写入RDPRT键(0x000000A5)后解除读保护
- USER:配置硬件看门狗和进入停机/待机模式是否产生复位
- Data0/1:用户可自定义使用
- WRP0/1/2/3:配置写保护,每一个位对应保护4个存储页(中容量),给0实施写保护
选项字节操作
选项字节擦除
- 检查FLASH_SR的BSY位,以确认没有其他正在进行的闪存操作,事前等待
- 解锁FLASH_CR的OPTWRE位,解锁选项字节,与flash锁类似,对FPEC解锁后,必须分别写入KEY1和KEY2(和flash的密钥相同)到FLASH_OPTKEYR寄存器
- 设置FLASH_CR的OPTER位为1,即将擦除选项字节
- 设置FLASH_CR的STRT位为1,开始擦除
- 等待BSY位变为0,等待执行结束
- 读出被擦除的选择字节并做验证
选项字节写入
- 检查FLASH_SR的BSY位,以确认没有其他正在进行的编程操作,事前等待
- 解锁FLASH_CR的OPTWRE位,解锁选项字节
- 设置FLASH_CR的OPTPG位为1,准备写入
- 写入要编程的半字到指定的地址
- 等待BSY位变为0,等待写入完成
- 读出写入的地址并验证数据
器件电子签名
电子签名存放在闪存存储器模块的系统存储区域,包含的芯片识别信息在出厂时编写,不可更改,使用指针读指定地址下的存储器可获取电子签名
闪存容量寄存器:
基地址:0x1FFF F7E0
大小:16位
产品唯一身份标识寄存器:
基地址: 0x1FFF F7E8
大小:96位
注意
FLASH的注意事项基本一致:
- 写入操作前,必须先进行写使能
- 每个数据位只能由1改写为0,不能由0改写为1
- 写入数据前必须先擦除,擦除后,所有数据位变为1
- 擦除必须按最小擦除单元进行 连续写入多字节时,最多写入一页的数据,超过页尾位置的数据,会回到页首覆盖写入
- 写入操作结束后,芯片进入忙状态,不响应新的读写操作
在编程过程中,(BSY位为’1’),任何读写闪存的操作都会使CPU暂停,直到此次闪存编程结束,可能会导致中断响应不及时