STM32F103使用内部Flash保存参数

来源:互联网 发布:2016网络伤感歌曲大全 编辑:程序博客网 时间:2024/06/07 22:57

在我们应用开发时,经常会有一些程序运行参数需要保存,如一些修正系数。这些数据的特点是:数量少而且不需要经常修改,但又不能定义为常量,因为每台设备可能不一样而且在以后还有修改的可能。将这类数据存在指定的位置,需要修改时直接修改存储位置的数值,需要使用时则直接读取,会是一种方便的做法。考虑到这些数据量比较少,使用专门的存储单元既不经济,也没有必要,而STM32F103内部的Flash容量较大,而且ST的库函数中还提供了基本的Flash操作函数,实现起来也比较方便。

      以大容量产品STM32F103VE为例,其Flash容量达到512K,可以将其中一部分用作数据存储。如下是大容量的Flash组织模式:

      根据上面的Flash组织模式,我们可以根据自己的使用方便来作相应的定义。因为大容量每个扇区定义为2K,而小容量和中容量都定义为1K,所以我们做如下宏定义:

按 Ctrl+C 复制代码
#define FLASH_SIZE 512          //所选MCU的FLASH容量大小(单位为K)


#if FLASH_SIZE<256
  #define SECTOR_SIZE           1024    //字节
#else 
  #define SECTOR_SIZE           2048    //字节
#endif
按 Ctrl+C 复制代码

      虽然ST的库函数比较全面,但都是基本操作,为了使用方面,根据我们自己的需要对其进行再次封装。

      对于读操作相对比较简单,内置闪存模块可以在通用地址空间直接寻址,就像读取变量一样。

按 Ctrl+C 复制代码
//从指定地址开始读取多个数据
void FLASH_ReadMoreData(uint32_t startAddress,uint16_t *readData,uint16_t countToRead)
{
  uint16_t dataIndex;
  for(dataIndex=0;dataIndex<countToRead;dataIndex++)
  {
    readData[dataIndex]=FLASH_ReadHalfWord(startAddress+dataIndex*2);
  }
}


//读取指定地址的半字(16位数据)
uint16_t FLASH_ReadHalfWord(uint32_t address)
{
  return *(__IO uint16_t*)address; 
}


//读取指定地址的全字(32位数据)
uint32_t FLASH_ReadWord(uint32_t address)
{
  uint32_t temp1,temp2;
  temp1=*(__IO uint16_t*)address; 
  temp2=*(__IO uint16_t*)(address+2); 
  return (temp2<<16)+temp1;
}
按 Ctrl+C 复制代码

      对于写操作相对来说要复杂得多,写操作包括对用户数据的写入和擦除。为了防止误操作还有写保护锁。但这些基本的操作ST的库函数已经为我们写好了,我们只需要调用即可。

      STM32复位后,FPEC模块是被保护的,只有在写保护被解除后,我们才能操作相关寄存器。STM32闪存的编程每次必须写入16位,任何不是半字的操作都会造成错误。如下图是Flash写的过程:

      STM32FLASH在编程的时候,也必须要求其写入地址的FLASH 是被擦除了的(也就是其值必须是0XFFFF),否则无法写入。Flash的擦除要求必须整页擦除,所以也必须整页写入,否则可能会丢失数据。如下图是Flash页擦除过程:

       如下为Flash全擦除过程,

      根据以上图示我们便写数据写入函数如下:

按 Ctrl+C 复制代码
//从指定地址开始写入多个数据
void FLASH_WriteMoreData(uint32_t startAddress,uint16_t *writeData,uint16_t countToWrite)
{
  if(startAddress<FLASH_BASE||((startAddress+countToWrite*2)>=(FLASH_BASE+1024*FLASH_SIZE)))
  {
    return;//非法地址
  }
  FLASH_Unlock();         //解锁写保护
  uint32_t offsetAddress=startAddress-FLASH_BASE;               //计算去掉0X08000000后的实际偏移地址
  uint32_t sectorPosition=offsetAddress/SECTOR_SIZE;            //计算扇区地址,对于STM32F103VET6为0~255
  
  uint32_t sectorStartAddress=sectorPosition*SECTOR_SIZE+FLASH_BASE;    //对应扇区的首地址


  FLASH_ErasePage(sectorStartAddress);//擦除这个扇区
  
  uint16_t dataIndex;
  for(dataIndex=0;dataIndex<countToWrite;dataIndex++)
  {
    FLASH_ProgramHalfWord(startAddress+dataIndex*2,writeData[dataIndex]);
  }
  
按 Ctrl+C 复制代码

      在擦除之前应该将页面上的数据读取出来与要写入的数据合并,待擦除后再写入,但这样数据量很大(大容量是2K一个扇区),所以考虑到是少量数据存储,所以每次都将全部数据同时写入,简化操作,也减少数据处理量。经测试以上程序写入和读出数据均正确,可以实现内部Flash的读写操作。需要更深入了解可以参考《STM32F10xxx 闪存编程参考手册》。

 

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 理想歌曲 理想的 新理想 理想的性质 理想型 理想的路上 我的理想作文 理想名言警句 理想作文600字 关于理想名言警句 我的理想演讲稿 理想开启美好人生 韩娱之国民理想型 理想开启美好人生演讲稿 孩子考试不理想家长简短评语 理想作文400字 我的职业理想 理想的名言警句 理想是石敲出星星之火 人生理想是什么 关于我的理想的作文 我的理想是什么 有关理想的名言警句 55188理想论坛 理想作文800字 关于我的梦想的作文 梦想的名言警句 理财资讯 闲钱理财 达飞理财 理财推荐 欧元理财 新手如何理财 什么有理数 什么叫有理数 有理数除法 有理数除法法则 有理数加减乘除混合运算 有理数加减法计算题 有理数分类 有理数混合运算100题