zoukankan      html  css  js  c++  java
  • STM32 FLASH 擦除(以及防止误擦除程序代码)、写入

    copy from:           http://www.51hei.com/mcu/2766.html

       

    编译环境:我用的是(Keil)MDK4.7.2   
    stm32库版本:我用的是3.5.0
    一、本文不对FLASH的基础知识做详细的介绍,不懂得地方请查阅有关资料。
      对STM32 内部FLASH进行编程操作,需要遵循以下流程:
      FLASH解锁
      清除相关标志位
      擦除FLASH(先擦除后写入的原因是为了工业上制作方便,即物理实现方便)
      写入FLASH
      锁定FLASH
    实例:
    #define FLASH_PAGE_SIZE    ((uint16_t)0x400) //如果一页为1K大小
    #define WRITE_START_ADDR   ((uint32_t)0x08008000)//写入的起始地址
    #define WRITE_END_ADDR      ((uint32_t)0x0800C000)//结束地址
    uint32_t EraseCounter = 0x00, Address = 0x00;//擦除计数,写入地址
    uint32_t Data = 0x3210ABCD;//要写入的数据
    uint32_t NbrOfPage = 0x00;//记录要擦除的页数
    volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;/*FLASH擦除完成标志*/
    void main()
    {
      /*解锁FLASH*/
     FLASH_Unlock();
      /*计算需要擦除FLASH页的个数 */
     NbrOfPage = (WRITE_END_ADDR - WRITE_START_ADDR) / FLASH_PAGE_SIZE;
      /* 清除所有挂起标志位 */
      FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);        
      /* 擦除FLASH 页*/
     for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
        {
          FLASHStatus = FLASH_ErasePage(WRITE_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter));
        }
      /* 写入FLASH  */
     Address = WRITE_START_ADDR;
     while((Address < WRITE_END_ADDR) && (FLASHStatus == FLASH_COMPLETE))
        {
          FLASHStatus = FLASH_ProgramWord(Address, Data);
          Address = Address + 4;
        }
    /* 锁定FLASH  */
     FLASH_Lock();
    }
    二、FLASH 擦除(以及防止误擦除程序代码)
    1、擦除函数
    FLASH_Status FLASH_ErasePage(u32 Page_Address)只要()里面的数是flash第xx页中对应的任何一个地址!就是擦除xx页全部内容!
     

    防止误擦除有用程序代码的方法
    方法一:首先要计算程序代码有多少,把FLASH存取地址设置在程序代码以外的地方,这样就不会破坏用户程序。原则上从0x0800 0000 + 0x1000 以后的FLASH空间都可以作为存储使用。如果代码量占了 0x3000, 那么存储在 0x0800 0000+ 0x4000 以后的空间就不会破坏程序了。

    方法二:先在程序中定义一个const 类型的常量数组,并指定其存储位置(方便找到写入、读取位置),这样编译器就会分配你指定的空间将常量数组存入FLASH中。当你做擦除。读写操作时,只要在这个常量数组所在的地址范围就好。

      const uint8_t table[10] __at(0x08010000) = {0x55} ;
      MDK3.03A开始就支持关键字 __at() 。
      需要加#include <absacc.h>

    方法三:在程序中定义一个const 类型的常量数组,无需指定其存储位置。只要定义一个32位的变量存储这个数组的FLASH区地址就行。

      uint32_t address;//STM32的地址是32位的
      const uint8_t imageBuffer[1024] = {0,1,2,3,4,5,6,7};
      address = (uint32_t) imageBuffer;/*用强制类型转换的方式,可以把FLASH中存储的imageBuffer[1024]的地址读到RAM中的变量address 里,方便找到写入、读取位置*/

    方法四:利用写保护的方式(没研究明白)

    三、FLASH写入
      FLASH的写入地址必须是偶数(FLASH机制决定的FLASH写入的时候只能是偶数地址写入,必须写入半字或字,也就是2个字节或是4字节的内容)
     

     

    四、FLASH 读取方法
      *(uint32_t *)0x8000000;//读一个字
      *(uint8_t *)0x8000000;//读一个字节;
      *(uint16_t *)0x8000000;//读半字;  
      举例:
      uint8_t data;
      data = *(uint8_t *)0x8000000;//就是读取FLASH中地址0x8000000处的数据
    五、几个有用的子函数
    /*
    功能:向指定地址写入数据
    参数说明:addr 写入的FLASH页的地址
              p    被写入变量的地址(数组中的必须是uint8_t类型,元素个数必须是偶数
              Byte_Num 被写入变量的字节数(必须是偶数
    */
      void FLASH_WriteByte(uint32_t addr , uint8_t *p , uint16_t Byte_Num)
      {
              uint32_t HalfWord;
              Byte_Num = Byte_Num/2;
              FLASH_Unlock();
              FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
              FLASH_ErasePage(addr);
              while(Byte_Num --)
              {
                      HalfWord=*(p++);
                      HalfWord|=*(p++)<<8;
                      FLASH_ProgramHalfWord(addr, HalfWord);
                      addr += 2;
              }
              FLASH_Lock();
      }
      例:
      uint8_t data[100];
      FLASH_WriteByte(0x8000000 , data , 100);/*数组data的数据被写入FLASH中*/
    /*
    功能:从指定地址读取数据
    参数说明:addr 从FLASH中读取的地址
              p    读取后要存入变量的地址(数组中的必须是uint8_t类型
              Byte_Num 要读出的字节数
    */
      void FLASH_ReadByte(uint32_t addr , uint8_t *p , uint16_t Byte_Num)
      {
        while(Byte_Num--)
        {
         *(p++)=*((uint8_t*)addr++);
        }
      }
      例:
      uint8_t data[101];
      FLASH_ReadByte(0x8000001 , data , 101);/*FLASH中的数据被读入数组data中*/

    Always Believe Something Beauitful Will Be Happen
  • 相关阅读:
    SCI写作经典替换词,瞬间高大上!(转)
    最佳化常用测试函数 Optimization Test functions
    算法复杂度速查表
    VS 代码行统计
    CPLEX IDE 菜单栏语言设置( 中文 英文 韩文 等多国语言 设置)
    如何从PDF文件中提取矢量图
    Matlab无法打开M文件的错误( Undefined function or method 'uiopen' for input arguments of type 'char)
    visual studio 资源视图 空白 解决方案
    MFC DialogBar 按钮灰色不响应
    嗨翻C语言笔记(二)
  • 原文地址:https://www.cnblogs.com/Oude/p/6064704.html
Copyright © 2011-2022 走看看