原创 STM32教程系列之FLASH学习

2010-12-13 20:33 7637 2 8 分类: MCU/ 嵌入式

一、实现的功能


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. 信息块擦除


   信息块的擦除主要是指对选择字节的擦除,选择字节组织如下:


cb7097d9-9055-405f-a876-f6dbdbb3569b.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”


 

PARTNER CONTENT

文章评论6条评论)

登录后参与讨论

用户1290934 2015-4-29 17:08

学习了。很好。

用户1610878 2012-8-3 17:15

谢谢分享

用户1571705 2012-5-3 11:16

不错,下载看看吧

用户1633950 2012-4-19 14:41

不错,下载保存,正学习中

用户1562320 2011-12-9 17:18

里面的文件解压怎么出错啊?

用户404982 2011-11-13 16:27

i love it for free.
相关推荐阅读
用户1505072 2010-12-19 20:51
STM32教程之电源管理学习(带源码和流程图)
一、实现的功能1.实现STM32进入停止模式,并利用外部中断线唤醒来推出停止模式。2.实现外部按键和RTC报警两个外部中断来唤醒进入停止模式的STM32。二、实验操作及现象1.双击PWR.eww打开工...
我要评论
6
2
关闭 站长推荐上一条 /3 下一条