你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

查看: 3846|回复: 0

stm32系列教程之FLASH学习

[复制链接]

2

主题

2

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
发表于 2010-12-12 19:18:54 | 显示全部楼层 |阅读模式
一、实现的功能
1.实现对STM32Fxxx的片内FLASH的擦除和烧写,并读出后进行检验。
2.用串口打印出检验FLASH内容是否正确的变量值。
二、实验操作及现象
1双击FLASH.eww打开工程文件,然后进行编译。
2.用Flash Loader将程序下载到ARM内,或者利用JLINK等仿真器进行仿真。
3.在程序运行前,用串口线将开发板的串口1PC机的串口1连接,并打开“串
口调试助手”,设置波特率为115200,将会看到每0.5秒显示一次“Flash Status=1”,
则说明FLASH操作成功,否则说明FLASH操作失败。
三、片内FLASH学习
大家可能会疑惑,既然我们可以利用工具将代码下载芯片内部,为什么还要讲解Flash编程呢?目的是让大家掌握后可以编写自己的BootLoader,例如用CAN总线接口来更新产品中的升级代码,不需要将产品拆卸即可完成。另外一个很重要的问题就是我们要保护好自己编写的代码,否则被破解后,就成别人的产品了。
1解除Flash  
复位后,闪存擦写控制器模块是被保护的,不能写入FLASH_CR寄存器,
通过写入两个关键字(KEY1KEY2)FLASH_KEYR寄存器打开闪存擦写控
制器,才可以进行其他闪存操作。其中KEY10x45670123KEY20xCDEF89AB
编程如下:
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)//如果SRBSY0
    {
      //如果擦除操作完成,禁止CRPER
      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)//如果SRBSY0
    {
      //如果擦除操作完成,禁止CRPER
      FLASH->CR &= CR_MER_Reset;
    }
  }    
4. 编程
   编程就是将数据写入指定的FLASH地址,STM32FLASH每次编程都是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;
    }
  }
7STM32的代码保护
       通过选择字节的设置,可以实现代码的读保护和写保护,在上面6中讲到的,RDPWRP分别是读保护和写保护,将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;
    }
  }    
8STM323种启动模式:
1种:上电前BOOT0脚为0BOOT1脚是0或者1,上电后直接进入FLASH执行应用程序。
2种:上电前BOOT0脚为1BOOT1脚为0,上电后进入芯片的自举程序(LOADER代码,厂家写好固化到芯片里的专门用于串口下载代码的程序),一般我们烧写程序的时候进入此模式。
3种:上电前BOOT0脚为1BOOT1脚为1,上电后进入芯片的SRAM,一般我们很少使用这个模式
四、程序流程分析
       程序流程见附件《STM32例程之FLASH流程图.pdf
五、代码例程(不包括库文件)
       程序的IAR例程工程见附件“FLASH.rar
  STM32例程之FLASH流程图.pdf (37.92 KB, 下载次数: 45)
回复

使用道具 举报

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版