Chinaunix首页 | 论坛 | 博客

Lzy

  • 博客访问: 215998
  • 博文数量: 56
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 675
  • 用 户 组: 普通用户
  • 注册时间: 2014-02-27 15:50
文章分类

全部博文(56)

文章存档

2014年(56)

我的朋友

分类: 嵌入式

2014-05-02 11:49:38

 一、实现的功能 
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学习 
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. 信息块擦除 
   信息块的擦除主要是指对选择字节的擦除,选择字节组织如下: 
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操作失败。 


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》 

阅读(1211) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~