MM32 FLASH操作

judy的头像
judy 发布于:周四, 11/23/2017 - 16:37 ,关键词:

在我们应用开发时,经常会有一些程序运行参数需要保存,如一些修正系数或一些自定义数据。这些数据的特点是:数量少而且不需要经常修改,但又不能定义为常量,因为每台设备可能不一样而且在以后还有修改的可能。将这类数据存在指定的位置,需要修改时直接修改存储位置的数值,需要使用时则直接读取,会是一种方便的做法。考虑到这些数据量比较少,使用专门的存储单元既不经济,也没有必要,而MM32L0系列产品内部的Flash容量较大,且擦写次数以万为单位,使用部分的Flash空间存储用户数据实现起来既方便又实惠。

MM32L0系列产品嵌入式闪存特性:

• 高达 128K 字节闪存存储器
• 存储器结构:
- 主闪存模块:最大 32K 字(32K×32 位)
- 信息模块: 系统存储器:高达 1K 字节(1K x 8 位)
选项字节:高达 2 x 8 字节
保密空间:高达 3K 字节(3K x 8 位)
保护字节:高达 512 字节(512 x 8 位)
闪存接口的特性为:
• 带预取缓冲器的读接口(每字为 2 × 64 位 )
• 选择字节加载器
• 闪存编程/擦除操作
• 访问/写保护
• 低功耗模式

MM32 FLASH操作

闪存空间由 64 位宽的存储单元组成,既可以存代码又可以存数据。主闪存块按 128 页(每页 1K 字节)或 32 扇区(每扇区 4K 字节)分块,以扇区为单位设置写保护。

主存储器的起始地址就是0x0800 0000,结束地址是0x0801 FFFF,共128K字节, B0、B1都接GND的时候,就是从0x08000000开始运行代码的。

选项字节的地址空间是0x1FFF F800 - 0x1FFF F80F,选项字节为16个字节(有效数据为低 8 位,而高 8 位为低 8 位的反码)。用于配置读写保护、软件/硬件看门狗以及器件处于待机或停止模式下的复位。

1、 读保护

在产品发布时,如果想对MCU的程序做一些保护性措施,防止他人通过仿真器把Flash中的程序读取回来,得到bin文件或hex文件,然后去模仿产品。所以我们需要对程序进行保护,一种比较简单可靠的方法就是把Flash设置成读保护。

读保护后,只允许从用户代码中对主闪存存储器的读操作(以非调试方式从主闪存存储器启动),调试模式下(Sram boot 和 debug 模式)禁止对 flash 进行操作, flash 本身的程序禁止写低 4KB 空间。第 0 ~ 3 页被自动加上了写保护,其它部分的存储器可以通过在主闪存存储器中执行的代码进行编程(实现 IAP 或数据存储等功能),但不允许在调试模式下或在从内部 SRAM 启动后执行写或擦除操作(整片擦除除外)。

读保护操作方法:

FLASH_Unlock();//解锁
FLASH_ReadOutProtection(ENABLE);//读保护使能
FLASH_Lock();//上锁
注意:如果在设置了读保护时,调试器仍然连接到 JTAG/SWD 接口,需要执行一次上电复位,而不是(没有调试器时的)系统复位。

解除读保护操作方法:

FLASH_Unlock();//解锁
FLASH_ReadOutProtection(DISABLE);//读保护失能
FLASH_Lock();//上锁
注意:当解除读保护后MM32会自动擦除整片的Flash。

2、 FLASH写和擦除操作

只要MCU的供电正常,就可以完成烧写和擦除功能操作,但是在写/擦除 Flash 的同时不可以对它取指和访问数据,因为在对 Flash进行写/擦除操作的同时,任何对 Flash 的访问都会令总线停顿。

对FLASH进行写和擦除操作的功能主要由下列7个寄存器完成:
• 关键字寄存器(FLASH_KEYR)
• 选项字节关键字寄存器(FLASH_OPRKEYR)
• Flash 控制寄存器(FLASH_CR)
• Flash 状态寄存器(FLASH_SR)
• Flash 地址寄存器(FLASH_AR)
• 选项字节寄存器(FLASH_OBR)
• 写保护寄存器(FLASH_WRPR)

MM32 FLASH操作

第一步:FLASH解锁,访问闪存控制寄存器(FLASH_CR)的锁状态, Flash 存储器默认是受保护状态的,这样可以防范意外的擦除动作。 FLASH_CR 寄存器不允许被改写,除非执行一串针对 FLASH_KEYR 寄存器的解锁操作才能开启对 FLASH_CR 的访问权限。当LOCK位为“1”时表示FPEC和FLASH_CR被锁住,不能对FLASH进行读写或者擦除操作。在检测到正确的解锁序列后,硬件会自动清除此位为“0”,该位为“0”时才能对FLASH进行正常的操作。

第二步:清除相关标志位,清EOP(操作结束位)、WRPRTERR(写保护错误)和PGERR(编程错误)位,EOP(操作结束位)在需对FLASH进行读写操作时,需等存储器的操作结束和该位当闪存操作完成,然后硬件设置该位为“1”,再写“1”清除该状态位。 WRPRTERR(写保护错误)在试图对写保护的闪存地址编程时,硬件设置为“1”,写“1”清除状态。PGERR(编程错误)在试图对内容不是0XFFFF的地址编程时,该位置为“1”。

第三步:擦除FLASH(先擦除后写入),MM32的Flash 存储器可以按页(1K字节)为单位擦除,也可以整片擦除。
页(1K字节)擦除步骤:
• 检查 FLASH_SR 中的 BSY 位,以确认上一操作已经结束,当 FLASH_SR 中得 BSY 位为 1 的时候,这些寄存器不能写
• 置 FLASH_CR 寄存器中得 PER 位为 1
• 写 FLASH_AR 寄存器以选择待擦除的页
• 置 FLASH_CR 寄存器中的 STRT 位为 1
• 等待 FLASH_SR 中的 BSY 归零
• 读取已擦除页以校验
库函数操作函数:
FLASH_ErasePage(Page_Address);//页擦除,Page_Address表示需要擦除的页地址

整片擦除步骤:
可以用整片擦除命令一次擦除整个 Flash 用户区,但信息块不会受这个命令影响,注意用户在使用整片擦除时执行该函数会将写入的应用程序也会擦除,具体步骤如下:
• 检查 FLASH_SR 中的 BSY 位,以确认上一操作已经结束,当 FLASH_SR 中得 BSY 位为 1 的时候,这些寄存器不能写
• 置 FLASH_CR 寄存器中的 MER 位为 1
• 置 FLASH_CR 寄存器中的 STRT 位为 1
• 等待 BSY 位归零
• 读取全部页并校验
库函数操作函数:
FLASH_EraseAllPages();//整片擦除

选项字节的擦除步骤:
选项字节的编程与常规用户地址不同,总共 4 个字节(2 个写保护, 1 个读保护, 1 个硬件配置)。
• 检查 FLASH_SR 寄存器中的 BSY 位,以确保上一操作结束,当 FLASH_SR 中得 BSY 位为 1 的时候,这些寄存器不能写
• 解锁 FLASH_CR 寄存器中的 OPTWRE 位
• 置 FLASH_CR 寄存器中的 OPTER 位为 1
• 置 FLASH_CR 寄存器中的 STRT 位为 1
• 等待 BSY 位归零
• 读取并校验
库函数操作函数:
status = FLASH_EraseOptionBytes();//Option空间擦除

第四步:清除相关标志位,清EOP(操作结束位),等待擦除操作结束。

第五步:写入FLASH,存储器按页(1K字节)为单位写入,FLASH的写入地址必须是偶数(FLASH机制决定的FLASH写入的时候只能是偶数地址写入,必须写入半字或字,也就是2个字节或是4字节的内容)。
主闪存编程步骤:
• 检查 FLASH_SR 中的 BSY 位,以确认上一操作已经结束
• 置 FLASH_CR 寄存器中的 PG 位
• 以半字为单位向目标地址写入数据
• 等待 FLASH_SR 寄存器中的 BSY 归零
• 读数据以校验
在指定地址编写一个字库函数操作:
FLASH_ProgramWord(Address, Data);// Address表示待编写的地址,Data表示带写入数据

在指定地址编写半字库函数操作:
ProgramHalfWord(Address, Data); // Address表示待编写的地址,Data表示带写入数据

在指定FLASH选项字节地址(0x1FFF F800 - 0x1FFF F80F)编写半字库函数操作:
ProgramOptionByteData(Address, Data); // Address表示待编写的地址,Data表示带写入数据

第六步:FLASH上锁,设置Flash存储器保护状态,这样可以防范意外的擦除动作。

读取FLASH数据
我们要从地址addr,读取一个字(字节为8位,半字为16位,字为32位),可以通过如下的语句读取:
data= (*(__IO uint32_t*) addr));
将addr强制转换为u32指针,然后取该指针所指向的地址的值,即得到了addr地址的值。

小结:

1、 为了准确读取 Flash 数据,必须根据 CPU 时钟 (HCLK) 频率和器件电源电压,在 Flash 存取控制寄存器 (FLASH_ACR) 中正确地设置等待周期数 (LATENCY),有很多用户在自己配置时钟时,配置等待周期数错误导致程序进入HardFault。

MM32 FLASH操作

2、有些用户在测试读保护功能后,发现无法Download程序,这个时候MCU是处在读保护状态,所以程序无法下载,所以有两个解决办法:(1)在设置读保护之前加一个延时函数为程序擦除预留时间,延时时间以秒为单位,在MCU复位后,使用仿真器迅速擦除MCU程序。(2)从内置 SRAM 解除读保护,选择BOOT0接GND,使MCU从SRAM启动,Download程序,对读保护进行解除,然后重新将BOOT0接高电平。

3、如选项字节块对应的地址值为非 0xFFFF, 需先执行擦除选项字节块的动作,执行擦除选项字节块的动作不会导致自动的整片擦除操作, 不会改变读保护状态。

4、MM32的Flash主闪存块按 128 页(每页 1K 字节)或 32 扇区(每扇区 4K 字节)分块,存储器可以按页(1K字节)为单位擦除,也可以整片擦除,存储器按页(1K字节)为单位写入。

5、如果在设置了读保护时,调试器仍然连接到 JTAG/SWD 接口,需要执行一次上电复位读保护功能才会起作用,而不是(没有调试器时的)系统复位。

转自: 灵动微电子

围观 901