STM32教程系列之FLASH
发布时间:2020-12-15 06:34:11 所属栏目:百科 来源:网络整理
导读:? 一、实现的功能 1.实现对STM32Fxxx的片内FLASH的擦除和烧写,并读出后进行检验。 2.用串口打印出检验FLASH内容是否正确的变量值。 二、实验操作及现象 1.双击FLASH.eww打开工程文件,然后进行编译。 2.用Flash?Loader将程序下载到ARM内,或者利用JLINK
?
一、实现的功能
1.实现对STM32Fxxx的片内FLASH的擦除和烧写,并读出后进行检验。 2.用串口打印出检验FLASH内容是否正确的变量值。 二、实验操作及现象 1.双击FLASH.eww打开工程文件,然后进行编译。 2.用Flash?Loader将程序下载到ARM内,或者利用JLINK等仿真器进行仿真。 3.在程序运行前,用串口线将开发板的串口1和PC机的串口1连接,并打开“串 口调试助手”,设置波特率为115200,将会看到每0.5秒显示一次“Flash?Status=1”, 则说明FLASH操作成功,否则说明FLASH操作失败。 三、片内FLASH学习 大家可能会疑惑,既然我们可以利用工具将代码下载芯片内部,为什么还要讲解Flash编程呢?目的是让大家掌握后可以编写自己的BootLoader,例如用CAN总线接口来更新产品中的升级代码,不需要将产品拆卸即可完成。另外一个很重要的问题就是我们要保护好自己编写的代码,否则被破_解后,就成别人的产品了。 1.解除Flash锁??? 复位后,闪存擦写控制器模块是被保护的,不能写入FLASH_CR寄存器, 通过写入两个关键字(KEY1,KEY2)到FLASH_KEYR寄存器打开闪存擦写控 制器,才可以进行其他闪存操作。其中KEY1为0x45670123,KEY2为0xCDEF89AB。 编程如下: FLASH->KEYR?=?FLASH_KEY1; ?? FLASH->KEYR?=?FLASH_KEY2; 2.页擦除 在FLASH操作中,每次擦除只能擦除一页,不能一个字节一个字节的擦除,其实所谓的擦出就是将指定的页全部填写成0XFF,下面是页擦除的过程: ???-检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的闪存操作; ???-用FLASH_AR寄存器选择要擦除的页; ???-设置FLASH_CR寄存器的PER位为1; ???-设置FLASH_CR寄存器的STRT位为1; ???-等待BSY位变为0; ???-读出被擦除的页并做验证。 编程如下: //等待前次操作完毕(检查FLASH_SR寄存器的BSY位) ??status?=?FLASH_WaitForLastOperation(EraseTimeout); ?? ??if(status?==?FLASH_COMPLETE)//如果FLASH处于可以操作状态,开始进行页擦除操作 ??{? ???? ????FLASH->CR|=?CR_PER_Set;//设置FLASH_CR寄存器的PER位为1 ????FLASH->AR?=?Page_Address;//用FLASH_AR寄存器选择要擦除的页 ????FLASH->CR|=?CR_STRT_Set;//设置FLASH_CR寄存器的STRT位为1 ???? ????//等待擦除操作完毕(等待BSY位变为0) ????status?=?FLASH_WaitForLastOperation(EraseTimeout); ????if(status?!=?FLASH_BUSY)//如果SR的BSY为0 ????{ ??????//如果擦除操作完成,禁止CR的PER位 ??????FLASH->CR?&=?CR_PER_Reset; ????} ??} 3.?全部擦除 全部擦除就是将全部FLASH都填写成0xFF,其过程如下: ???-检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的闪存操作; ???-设置FLASH_CR寄存器的MER位为1; ???-设置FLASH_CR寄存器的STRT位为1; ???-等待BSY位变为0; ???-读出所有页并做验证。 编程如下:? //等待前次操作完毕(检查FLASH_SR寄存器的BSY位) ??status?=?FLASH_WaitForLastOperation(EraseTimeout); ?? ??if(status?==?FLASH_COMPLETE)//如果FLASH出于可以操作状态,开始进行全部页擦除操作 ??{ ?????FLASH->CR?|=?CR_MER_Set;//设置FLASH_CR寄存器的MER位为1 ?????FLASH->CR?|=?CR_STRT_Set;//设置FLASH_CR寄存器的STRT位为1 ???? ????//等待全部页擦除操作完毕(等待BSY位变为0) ????status?=?FLASH_WaitForLastOperation(EraseTimeout); ????if(status?!=?FLASH_BUSY)//如果SR的BSY为0 ????{ ??????//如果擦除操作完成,禁止CR的PER位 ??????FLASH->CR?&=?CR_MER_Reset; ????} ??} ??? 4.?编程 ???编程就是将数据写入指定的FLASH地址,STM32的FLASH每次编程都是16位(在32位系统中,我们叫做半字),过程如下: -检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的编程操作; ???-设置FLASH_CR寄存器的PG位为1; ???-写入要编程的半字到指定的地址; ???-等待BSY位变为0; ???-读出写入的地址并验证数据。 编程如下: //检查参数是否正确 ??assert_param(IS_FLASH_ADDRESS(Address)); ??//等待前次操作完毕(检查FLASH_SR寄存器的BSY位) ??status?=?FLASH_WaitForLastOperation(ProgramTimeout); ?? ??if(status?==?FLASH_COMPLETE)//如果FLASH处于可以操作状态,开始进行编程操作 ??{ ???? ????FLASH->CR?|=?CR_PG_Set;//设置FLASH_CR寄存器的PG位为1 ?? ????*(vu16*)Address?=?Data;//写入要编程的半字到指定的地址 ????//等待半字编程操作完毕(等待BSY位变为0) ????status?=?FLASH_WaitForLastOperation(ProgramTimeout); ????if(status?!=?FLASH_BUSY) ????{ ??????//如果半字编程完毕,禁止PG位 ??????FLASH->CR?&=?CR_PG_Reset; ????} ??} 5.?信息块擦除 ???信息块的擦除主要是指对选择字节的擦除,选择字节组织如下: ? (原文件名:option.JPG)? RDP:读出保护选择字节 读出保护功能帮助用户保护存在闪存中的软件。该功能由设置信息块中的一个选择字节启用。写入正确的数值(RDPRT键=0x00A5)到这个选择字节后,闪存被开放允许读出访问。 USER:用户选择字节 这个字节用于配置下列功能: ??选择看门狗事件:硬件或软件 ??进入停机(STOP)模式时的复位事件 ??进入待机模式时的复位事件 Data:用户数据,可由用户自己分配 WRPx:闪存写保护选择字节 用户选择字节WRPx中的每个位用于保护主存储器中4页的内容,每页为1K字节。总共有4个用户选择字节用于保护所有128K主闪存。 其擦除的过程如下: -检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的闪存操作; ???-解除FLASH_CR寄存器的OPTWRE位; ???-设置FLASH_CR寄存器的OPTER位为1; ???-设置FLASH_CR寄存器的STRT位为1; ???-等待BSY位变为0; ???-读出小信息块并做验证。 编程过程如下: //等待前次操作完毕(检查FLASH_SR寄存器的BSY位) ??status?=?FLASH_WaitForLastOperation(EraseTimeout); ??if(status?==?FLASH_COMPLETE)//如果FLASH处于可以操作状态,开始进选择字节擦除操作 ??{ ????//解锁?CR寄存器中的OPTWRE位? ????FLASH->OPTKEYR?=?FLASH_KEY1;//输入选择字节键1 ????FLASH->OPTKEYR?=?FLASH_KEY2;//输入选择字节键2 ???? ????FLASH->CR?|=?CR_OPTER_Set;//设置FLASH_CR寄存器的OPTER位为1 ????FLASH->CR?|=?CR_STRT_Set;//设置FLASH_CR寄存器的STRT位为1 ????//等待选择字节擦除操作完毕(等待BSY位变为0) ????status?=?FLASH_WaitForLastOperation(EraseTimeout); ???? ????if(status?==?FLASH_COMPLETE)//如果选择字节擦除操作完毕 ????{ ??????//如果擦除操作完毕,禁止OPTER位 ??????FLASH->CR?&=?CR_OPTER_Reset; ??????? ??????//使能选择字节编程操作 ??????FLASH->CR?|=?CR_OPTPG_Set; ??????//使能读出访问 ??????OB->RDP=?RDP_Key;?//选择字节擦除同时需要开放代码读出 ??????//等待前次操作完毕 ??????status?=?FLASH_WaitForLastOperation(ProgramTimeout); ? ??????if(status?!=?FLASH_BUSY)//如果前次操作结束 ??????{ ????????//如果编程操作完毕,禁止OPTPG位 ????????FLASH->CR?&=?CR_OPTPG_Reset; ??????} ????} 6.?选择字节编程 ???选择字节的编程就是向上面讲到的选择字节里面写入指定的数据,其过程如下: -检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的编程操作; ???-解除FLASH_CR寄存器的OPTWRE位; ???-设置FLASH_CR寄存器的OPTPG位为1; ???-写入要编程的半字到指定的地址; ???-等待BSY位变为0; ???-读出写入的地址并验证数据。 编程过程如下: //等待前次操作完毕(检查FLASH_SR寄存器的BSY位) ??status?=?FLASH_WaitForLastOperation(ProgramTimeout); ??if(status?==?FLASH_COMPLETE)//如果FLASH处于可以操作状态,开始进行编程操作 ??{ ????//解锁?CR寄存器中的OPTWRE位 ????FLASH->OPTKEYR?=?FLASH_KEY1; ????FLASH->OPTKEYR?=?FLASH_KEY2; ??? ????FLASH->CR?|=?CR_OPTPG_Set;//设置FLASH_CR寄存器的OPTPG位为1 ????*(vu16*)Address?=?Data;//写入要编程的半字到指定的地址 ???? ????//等待半字编程操作完毕(等待BSY位变为0) ????status?=?FLASH_WaitForLastOperation(ProgramTimeout); ????if(status?!=?FLASH_BUSY) ????{ ??????//如果半字编程完毕,禁止OPTPG位 ??????FLASH->CR?&=?CR_OPTPG_Reset; ????} ??}? 7.STM32的代码保护 通过选择字节的设置,可以实现代码的读保护和写保护,在上面6中讲到的,RDP和WRP分别是读保护和写保护,将RDP设置指定的数值,可以实现代码的读保护,也就是不允许任何设备读取FLASH里面的应用代码,将WRP里设置指定的数值,可以实现代码的写保护,不允许任何设备改写FLASH里面的应用代码。其中设置读保护的代码如下: //等待前次操作完毕(检查FLASH_SR寄存器的BSY位) ??status?=?FLASH_WaitForLastOperation(EraseTimeout); ??if(status?==?FLASH_COMPLETE)//如果FLASH处于可以操作状态,开始进行指定操作 ??{ ????//解锁?CR寄存器中的OPTWRE位 ????FLASH->OPTKEYR?=?FLASH_KEY1; ????FLASH->OPTKEYR?=?FLASH_KEY2; ????//擦除整个选择字节区域 ????FLASH->CR?|=?CR_OPTER_Set; ????FLASH->CR?|=?CR_STRT_Set; ????//等待擦除操作完毕 ????status?=?FLASH_WaitForLastOperation(EraseTimeout); ????if(status?==?FLASH_COMPLETE)//如果擦除操作完毕 ????{ ??????//禁止OPTER位 ??????FLASH->CR?&=?CR_OPTER_Reset; ??????//使能选择字节编程操作 ??????FLASH->CR?|=?CR_OPTPG_Set;? ??????if(NewState?!=?DISABLE)//禁止读出操作 ??????{ ????????OB->RDP?=?0x00; ??????} ??????else//使能读出操作 ??????{ ????????OB->RDP?=?RDP_Key;?? ??????} ??????//等待写入完毕 ??????status?=?FLASH_WaitForLastOperation(EraseTimeout);? ???? ??????if(status?!=?FLASH_BUSY) ??????{ ????????//写入操作完毕,禁止OPTPG位 ????????FLASH->CR?&=?CR_OPTPG_Reset; ??????} } 写保护代码如下: //等待前次操作完毕(检查FLASH_SR寄存器的BSY位) ??status?=?FLASH_WaitForLastOperation(ProgramTimeout); ?? ??if(status?==?FLASH_COMPLETE)//如果FLASH处于可以操作状态,开始进行编程操作 ??{ ????//解锁?CR寄存器中的OPTWRE位 ????FLASH->OPTKEYR?=?FLASH_KEY1; ????FLASH->OPTKEYR?=?FLASH_KEY2; ????//设置FLASH_CR寄存器的OPTPG位为1 ????FLASH->CR?|=?CR_OPTPG_Set; ????if(WRP0_Data?!=?0xFF)//如果不是全部不写保护 ????{ ??????OB->WRP0?=?WRP0_Data;//写入WRP0 ?????? ??????//等待写入操作完毕 ??????status?=?FLASH_WaitForLastOperation(ProgramTimeout); ????} ????if((status?==?FLASH_COMPLETE)?&&?(WRP1_Data?!=?0xFF)) ????{ ??????OB->WRP1?=?WRP1_Data; ?????? ??????//等待写入操作完毕 ??????status?=?FLASH_WaitForLastOperation(ProgramTimeout); ????} ????if((status?==?FLASH_COMPLETE)?&&?(WRP2_Data?!=?0xFF)) ????{ ??????OB->WRP2?=?WRP2_Data; ?????? ??????//等待写入操作完毕 ??????status?=?FLASH_WaitForLastOperation(ProgramTimeout); ????} ???? ????if((status?==?FLASH_COMPLETE)&&?(WRP3_Data?!=?0xFF)) ????{ ??????OB->WRP3?=?WRP3_Data; ????? ??????//等待写入操作完毕 ??????status?=?FLASH_WaitForLastOperation(ProgramTimeout); ????} ?????????? ????if(status?!=?FLASH_BUSY) ????{ ??????//如果编程操作完毕,禁止OPTPG位 ??????FLASH->CR?&=?CR_OPTPG_Reset; ????} ??}???? 8.STM32有3种启动模式: 第1种:上电前BOOT0脚为0,BOOT1脚是0或者1,上电后直接进入FLASH执行应用程序。 第2种:上电前BOOT0脚为1,BOOT1脚为0,上电后进入芯片的自举程序(LOADER代码,厂家写好固化到芯片里的专门用于串口下载代码的程序),一般我们烧写程序的时候进入此模式。 第3种:上电前BOOT0脚为1,BOOT1脚为1,上电后进入芯片的SRAM,一般我们很少使用这个模式 四、程序流程分析 程序流程见附件《STM32例程之FLASH流程图.pdf》 五、代码例程(不包括库文件) 程序的IAR例程工程见附件“FLASH.rar” 点击此处下载? ourdev_604189GXBJQ5.pdf(文件大小:38K)? (原文件名:STM32例程之FLASH流程图.pdf)? 点击此处下载? ourdev_604190LP4GFP.rar(文件大小:223K)? (原文件名:FLASH.rar)? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |