STM32学习之Flash(主存储块、系统存储器和选项字节)详解
(2015-11-23 16:31:47)FLASH分类
FLASH的页面
STM32产品的分类
小容量产品主存储块1-32KB,
中容量产品主存储块64-128KB,
大容量产品主存储块256KB以上,
互联型产品主存储块256KB以上,
STM32F101xx、STM32F102xx 、STM32F103xx产品,根据其主存储块容量,一定是小容量、中容量、大容量产品中的一种,STM32F105xx、STM32F107xx是互联型产品。
关于ISP与IAP
FPEC
FPEC键寄存器(FLASH_KEYR)写入键值解锁。
选项字节键寄存器(FLASH_OPTKEYR)写入键值解锁选项字节操作。
闪存控制寄存器(FLASH_CR)选择并启动闪存操作。
闪存状态寄存器(FLASH_SR)查询闪存操作状态。
闪存地址寄存器(FLASH_AR)存储闪存操作地址。
选项字节寄存器(FLASH_OBR)选项字节中主要数据的映象。
写保护寄存器(FLASH_WRPR)选项字节中写保护字节的映象。
键值
闪存锁
当LOCK位为1时,闪存锁有效,只有向FLASH_KEYR依次写入KEY1、KEY2后,LOCK位才会被硬件清零,从而解除闪存锁。当LOCK位为1时,对
FLASH_KEYR的任何错误写操作(第一次不是KEY1,或第二次不是KEY2),都将会导致闪存锁的彻底锁死,一旦闪存锁彻底锁死,在下一次复位前,都无法解锁,只有复位后,闪存锁才恢复为一般锁住状态。
复位后,LOCK位默认为1,闪存锁有效,此时,可以进行解锁。解锁后,可进行FLASH的擦除编程工作。任何时候,都可以通过对LOCK位置1来软件加锁,软件加锁与复位加锁是一样的,都可以解锁。
主存储块的擦除
页擦除
1.检查FLASH_SR寄存器的BSY位。以确认没有其他正在进行的闪存操作。必须等待BSY位为0,才能继续操作。
2.设置FLASH_CR寄存器的PER位为1。选择页擦除操作。
3.设置FLASH_AR寄存器为要擦除页所在地址,选择要擦除的页。FLASH_AR的值在哪一页范围内,就表示要擦除哪一页。
4.设置FLASH_CR寄存器的STRT位为1,启动擦除操作。
5.等待FLASH_SR寄存器的BSY位变为0,表示操作完成。
6.查询FLASH_SR寄存器的EOP位,EOP为1时,表示操作成功。
7.读出被擦除的页并做验证。擦完后所有数据位都为1。
整片擦除
1.检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的闪存操作。
2.设置FLASH_CR寄存器的MER位为1。选择整片擦除操作。
3.设置FLASH_CR寄存器的STRT位为1。启动整片擦除操作。
4.等待FLASH_SR寄存器的BSY位变为0,表示操作完成。
5.查询FLASH_SR寄存器的EOP位,EOP为1时,表示操作成功。
6.读出所有页并做验证。擦完后所有数据位都为1。
主存储块的编程
1.检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的编程操作。
2.设置FLASH_CR寄存器的PG位为1。选择编程操作。
3.在指定的地址写入要编程的半字。直接用指针写。
4.等待FLASH_SR寄存器的BSY位变为0,表示操作完成。
5.查询FLASH_SR寄存器的EOP位,EOP为1时,表示操作成功。
6.读出写入的地址并验证数据。
关于主存储块擦除编程操作的一些疑问
1. 为什么每次都要检查BSY位是否为0?
2. 如果没有擦除就进行编程,会出现什么结果?
3. 为什么操作后要读出数据并验证?
4. 等待BSY位为1的时间以多少为合适?
5. FLASH编程手册上说进行闪存操作(擦除或编程)时,必须打开内部的RC振荡器(HSI),是不是一定要用HIS进行闪存的擦除及编程操作?
选项字节
目前,所有的STM32101xx、STM32102xx、STM32103xx、STM32105xx、STM32107xx产品,选项字节都是16字节。但是这16字节,每两个字节组成一个正反对,即,字节1是字节0的反码,字节3是字节2的反码,...,字节15是字节14的反码,所以,芯片使用者只要设置8个字节就行了,另外8个字节系统自动填充为反码。因此,有时候,也说STM32的选项字节是8个字节,但是占了16字节的空间。选项字节的8字节正码概述如下:
RDP
USER
Data0
Data1
WRP0
WRP1
WRP2
WRP3
选项字节写使能
选项字节擦除
1.检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的闪存操作。
2.解锁FLASH_CR寄存器的OPTWRE位。即,打开写使能。
3.设置FLASH_CR寄存器的OPTER位为1。选择选项字节擦除操作。
4.设置FLASH_CR寄存器的STRT位为1。
5.等待FLASH_SR寄存器的BSY位变为0,表示操作完成。
6.查询FLASH_SR寄存器的EOP位,EOP为1时,表示操作成功。
7.读出选项字节并验证数据。
由于选项字节只有16字节,因此,擦除时是整个选项字节都被擦除了。
选项字节编程
1.检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的编程操作。
2.解锁FLASH_CR寄存器的OPTWRE位。即,打开写使能。
3.设置FLASH_CR寄存器的OPTPG位为1。选择编程操作。
4.写入要编程的半字到指定的地址。启动编程操作。
5.等待FLASH_SR寄存器的BSY位变为0,表示操作完成。
6.查询FLASH_SR寄存器的EOP位,EOP为1时,表示操作成功。
7.读出写入的选项字节并验证数据。 对选项字节编程时,FPEC使用半字中的低字节并自动地计算出高字节(高字节为低字节的反码),并开始编程操作,这将保证选项字节和它的反码始终是正确的。
主存储块的保护
写保护用于保护数据不被非法改写,增强程序的健壮性。
读保护
1.从主存储块启动的程序,可以对整个主存储块执行读操作,不允许对主存储块的前4KB进行擦除编程操作,可以对4KB之后的区域进行擦除编程操作。
2.从SRAM启动的程序,不能对主存储块进行读、页擦除、编程操作,但可以进行主存储块整片擦除操作。
3.使用调试接口不能访问主存储块。这些特性足以阻止主存储器数据的非法读出,又能保证程序的正常运行。
只有当RDP选项字节的值为RDPRT键值时,读保护才被关闭,否则,读保护就是启动的。因此,擦除选项字节的操作,将启动主存储块的读保护。如果要关闭读保护,必须将RDP选项字节编程为RDPRT键值。并且,如果编程选项字节,使RDP由非键值变为键值(即由保护变为非保护)时,STM32将会先擦除整个主存储块,再编程RDP。芯片出厂时,RDP会事先写入RDPRT键值,关闭写保护功能。
写保护
选项字节与它的寄存器映象
我们知道,FPEC有两个寄存器存储了选项字节的映象。那么,选项字节本体(在FLASH中)与映象(在寄存器中)究竟有什么区别呢?
选项字节的本体只是个FLASH,它的作用只是掉电存储选项字节内容而以,真正起作用的是寄存器中的映象。即,一个配置是否有效,不是看本体,而是看映象。而映象是在复位后,用本体的值加载的,此后,除非复位,映象将不再改变。所以,更改本体的数据后,不会立即生效,只有复位加载到映象中后,才会生效。 有一点要注意的是,当更改本体的值,使主存储块读保护变为不保护时,会先擦除整片主存储块,然后再改变本体。这是唯一一个改变本体会引发的动作。但即使这样,读保护依然要等到复位后,加载到映象后,才会解除。
关于FLASH编程手册中文版的几处错误(不一定是,但是与我的理解不符)
1.选项字节编程一节中:
对FPEC解锁后,必须分别写入KEY1和KEY2(见2.3.1节)到FLASH_OPTKEYR寄存器,再设置FLASH_CR寄存器的OPTWRE位为’1’,此时可以对选项字节进行编程
实际上,对FLASH_OPTKEYR写入KEY1和KEY2后,OPTWRE位会被硬件置1,而不是用软件写1。这一点在后面的寄存器描述中也可以得到验证。 2.对读保护的描述中:
对读保护的数值对无法理解。正确的应该是,RDP为RDPRT键值时,解除读保护,为其它值时,读保护生效。
看了半天,原来只要几句就可以解决,当然是不考虑其他功能,只是简单的读写操作。
其中写操作如下:
从上面可以看出基本顺序是:解锁-》清除标志位(可以不要)-》擦除-》写半字-》清楚标志位(也可以不要)-》上锁。其中FLASH_START_ADDR是宏定义的0x8000000+2048*255,0x8000000是Flash的起始地址,2048是因为我用的是大容量芯片,根据上一笔记Flash地址可以看出芯片每页容量2K,即2048字节,255表示芯片的最后一页,这个根据不同芯片而定。之所以从后面页写起可以防止储存数据破坏用户程序。addr*2是因为每个数据占用2字节(半字),虽然写入的是1字节数据,但是编程是2字节为单位,也就是说一个字节的数据也会占用两个字节地址。
读操作如下:
后一篇:子夜