您的位置 首页 基础

对STM32的flash进行操作的一些关键

说到STM32的flash,我们的第一反应是用来装程序的,实际上,STM32的片内FLASH不仅用来装程序,还用来装芯片配置、芯片ID、自举程序等等。当然, FLAS

提到STM32flash,咱们的榜首反应是用来装程序的,实践上,STM32的片内FLASH不只用来装程序,还用来装芯片装备、芯片ID、自举程序等等。当然, FLASH还能够用来装数据。

FLASH分类
依据用处,STM32片内的FLASH分红两部分:主存储块、信息块。 主存储块用于存储程序,咱们写的程序一般存储在这里。 信息块又分红两部分:体系存储器、选项字节。 体系存储器存储用于存放在体系存储器自举形式下的发动程序(BootLoader),当运用ISP方法加载程序时,便是由这个程序履行。这个区域由芯片厂写入BootLoader,然后锁死,用户是无法改动这个区域的。 选项字节存储芯片的装备信息及对主存储块的维护信息。
FLASH的页面
STM32的FLASH主存储块按页安排,有的产品每页1KB,有的产品每页2KB。页面典型的用处便是用于按页擦除FLASH。从这点来看,页面有点像通用FLASH的扇区。
STM32产品的分类
STM32依据FLASH主存储块容量、页面的不同,体系存储器的不同,分为小容量、中容量、大容量、互联型,共四类产品。
小容量产品主存储块1-32KB, 每页1KB。体系存储器2KB。
中容量产品主存储块64-128KB, 每页1KB。体系存储器2KB。
大容量产品主存储块256KB以上, 每页2KB。体系存储器2KB。
互联型产品主存储块256KB以上, 每页2KB。体系存储器18KB。
关于详细一个产品归于哪类,能够查数据手册,或依据以下简略的规矩进行差异:
STM32F101xx、STM32F102xx 、STM32F103xx产品,依据其主存储块容量,必定是小容量、中容量、大容量产品中的一种,STM32F105xx、STM32F107xx是互联型产品。
互联型产品与其它三类的不同之处便是BootLoader的不同,小中大容量产品的BootLoader只需2KB,只能经过USART1进行ISP,而互联型产品的BootLoader有18KB,能经过USAT1、4、CAN等多种方法进行ISP。小空量产品、中容量产品的BootLoader与大容量产品相同。

关于ISP与IAP
ISP(In System Programming)在体系编程,是指直接在方针电路板上对芯片进行编程,一般需求一个自举程序(BootLoader)来履行。ISP也有叫ICP(In Circuit Programming)、在电路编程、在线编程。 IAP(In Application Programming)在运用中编程,是指终究产品出厂后,由终究用户在运用中对用户程序部分进行编程,完结在线晋级。IAP要求将程序分红两部分:引导程序、用户程序。引导程序总是不变的。IAP也有叫在程序中编程。 ISP与IAP的差异在于,ISP一般是对芯片整片从头编程,用的是芯片厂的自举程序。而IAP仅仅更新程序的一部分,用的是电器厂开发的IAP引导程序。归纳来看,ISP遭到的约束更多,而IAP由所以自己开发的程序,替换程序的时分更简略操作。

FPEC
FPEC(FLASH Program/Erase controller 闪存编程/擦除操控器),STM32经过FPEC来擦除和编程FLASH。FPEC运用7个寄存器来操作闪存:

FPEC键寄存器(FLASH_KEYR) 写入键值解锁。
选项字节键寄存器(FLASH_OPTKEYR) 写入键值解锁选项字节操作。
闪存操控寄存器(FLASH_CR) 挑选并发动闪存操作。
闪存状况寄存器(FLASH_SR) 查询闪存操作状况。
闪存地址寄存器(FLASH_AR) 存储闪存操作地址。
选项字节寄存器(FLASH_OBR) 选项字节中首要数据的映象。
写维护寄存器(FLASH_WRPR) 选项字节中写维护字节的映象。

键值
为了增强安全性,进行某项操作时,需要向某个方位写入特定的数值,来验证是否为安全的操作,这些数值称为键值。STM32的FLASH共有三个键值:
RDPRT键 = 0x000000A5 用于免除读维护
KEY1 = 0x45670123 用于免除闪存锁
KEY2 = 0xCDEF89AB 用于免除闪存锁
闪存锁
在FLASH_CR中,有一个LOCK位,该位为1时,不能写FLASH_CR寄存器,然后也就不能擦除和编程FLASH,这称为闪存锁。
当LOCK位为1时,闪存锁有用,只需向FLASH_KEYR顺次写入KEY1、KEY2后,LOCK位才会被硬件清零,然后免除闪存锁。当LOCK位为1时,对
FLASH_KEYR的任何过错写操作(榜首次不是KEY1,或第2次不是KEY2),都将会导致闪存锁的完全锁死,一旦闪存锁完全锁死,鄙人一次复位前,都无法解锁,只需复位后,闪存锁才康复为一般锁住状况。
复位后,LOCK位默以为1,闪存锁有用,此刻,能够进行解锁。解锁后,可进行FLASH的擦除编程作业。任何时分,都能够经过对LOCK方位1来软件加锁,软件加锁与复位加锁是相同的,都能够解锁。
主存储块的擦除
主存储块能够按页擦除,也能够整片擦除。
页擦除
主存储块的任何一页都能够经过FPEC的页擦除功用擦除。 主张运用以下过程进行页擦除:
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。
主存储块的编程
对主存储块编程每次能够写入16位。当FLASH_CR寄存器的PG位为1时,在一个闪存地址写入一个半字(16位)将发动一次编程;写入任何非半字的数据,FPEC都会发生总线过错。在编程过程中(BSY位为1时),任何读写闪存的操作都会使CPU暂停,直到此次闪存编程完毕。 主张运用如下过程对主存储块进行编:
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?
因为BSY位为1时,不能对任何FPEC寄存器履行写操作,所以有必要要等BSY位为0时,才干履行闪存操作。
2. 假如没有擦除就进行编程,会呈现什么成果?
STM32在履行编程操作前,会先查看要编程的地址是否被擦除,假如没有,则不进行编程,并置FLASH_SR寄存器的PGERR位为1。仅有破例的是,当要编程的数据为0X0000时,即便未擦除,也会进行编程,因为0X0000即便擦除也能够正确编程。
3. 为什么操作后要读出数据并验证?
STM32在某些特殊情况下(例如FPEC被锁住),或许根本就没有履行所要的操作,仅经过寄存器无法判别操作是否成功。所以,稳妥起见,操作后都要读出一切数据查看。
4. 等候BSY位为1的时刻以多少为适宜?
请参阅STM32固件库中的数据。
5. FLASH编程手册上说进行闪存操作(擦除或编程)时,有必要翻开内部的RC振荡器(HSI),是不是必定要用HIS进行闪存的擦除及编程操作?
关于这点,我的了解是,进行闪存操作时,有必要要确保HIS没有被封闭,可是操作时的体系仍然能够是HSE时钟。STM32复位后,HIS默许是开的,只需你不为了低功耗去主动封闭它,则用什么时钟都能够进行闪存操作的。我所编的程序也验证了这一点。
选项字节
选项字节用于存储芯片运用者对芯片的装备信息。
现在,一切的STM32101xx、STM32102xx、STM32103xx、STM32105xx、STM32107xx产品,选项字节都是16字节。可是这16字节,每两个字节组成一个正对立,即,字节1是字节0的反码,字节3是字节2的反码,...,字节15是字节14的反码,所以,芯片运用者只需设置8个字节就行了,别的8个字节体系主动填充为反码。因而,有时分,也说STM32的选项字节是8个字节,可是占了16字节的空间。选项字节的8字节正码概述如下:
RDP 字节0。读维护字节,存储对主存储块的读维护设置。
USER 字节2。用户字节,装备看门狗、停机、待机。
Data0 字节4。数据字节0,由芯片运用者自在运用。
Data1 字节6。数据字节1,由芯片运用者自在运用。
WRP0 字节8。写维护字节0,存储对主存储块的写维护设置。
WRP1 字节10。写维护字节1,存储对主存储块的写维护设置。
WRP2 字节12。写维护字节2,存储对主存储块的写维护设置。
WRP3 字节14。写维护字节3,存储对主存储块的写维护设置。
选项字节写使能
在FLASH_CR中,有一个OPTWRE位,该位为0时,不答应进行选项字节操作(擦除、编程)。这称为选项字节写使能。只需该位为1时,才干进行选项字节操作。 该位不能软件置1,但能够软件清零。只需向FLASH_OPTKEYR顺次写入KEY1和KEY2后,硬件会主动对该方位1,此刻,才答应选项字节操作。这称为解锁(翻开)选项字节写使能。该位为1后,能够由软件清零,封闭写使能。复位后,该位为0。过错操作不会永久封闭写使能,只需写入正确的键序列,则又能够翻开写使能。写使能已翻开时,再次翻开,不会犯错,而且仍然是翻开的。 很明显,进行选项字节操作前,先要解开闪存锁,然后翻开选项字节写使能,之后,才干进行选项字节操作。
选项字节擦除
主张运用如下过程对选项字节进行擦除:
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键值,封闭写维护功用。
写维护
STM32主存储块能够分域进行写维护。假如企图对写维护的域进行擦除或编程操作,在闪存状况寄存器(FLASH_SR)中会回来一个写维护过错标志。STM32主存储块每个域4KB,WRP0-WRP3选项字节中的每一位对应一个域,位为0时,写维护有用。关于超越128KB的产品,WRP3.15维护了域31及之后的一切域。明显,擦除选项字节将导致免除主存储块的写维护。
选项字节与它的寄存器映象
咱们知道,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_Unlock(); //解锁FLASH编程擦除操控器
FLASH_ClearFlag(FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);//铲除标志位
/*********************************************************************************
// FLASH_FLAG_BSY FLASH忙标志位
// FLASH_FLAG_EOP FLASH操作完毕标志位
// FLASH_FLAG_PGERR FLASH编写过错标志位
// FLASH_FLAG_WRPRTERR FLASH页面写维护过错标净
**********************************************************************************/
FLASH_ErasePage(FLASH_START_ADDR); //擦除指定地址页
FLASH_ProgramHalfWord(FLASH_START_ADDR+(addr+i)*2,dat); //从指定页的addr地址开端写
FLASH_ClearFlag(FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);//铲除标志位
FLASH_Lock(); //确定FLASH编程擦除操控器
从上面能够看出根本次序是:解锁-》铲除标志位(能够不要)-》擦除-》写半字-》清楚标志位(也能够不要)-》上锁。其间FLASH_START_ADDR是宏界说的0x8000000+2048*255,0×8000000是Flash的开端地址,2048是因为我用的是大容量芯片,依据上一笔记Flash地址能够看出芯片每页容量2K,即2048字节,255表明芯片的最终一页,这个依据不同芯片而定。之所以从后边页写起能够避免贮存数据损坏用户程序。addr*2是因为每个数据占用2字节(半字),尽管写入的是1字节数据,可是编程是2字节为单位,也便是说一个字节的数据也会占用两个字节地址。
读操作如下:
u16 value;
value = *(u16*)(FLASH_START_ADDR+(addr*2));//从指定页的addr地址开端读
我在实践的项目中发现,在对flash进行写操作时要封闭一切中止,关于这一点是否是有必要的,我没有去进一步了解和验证。

  • STM32单片机中文官网
  • STM32单片机官方开发工具
  • STM32单片机参阅规划

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/jichu/156783.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部