STM32F103使用内部Flash保存参数



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

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

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

#define FLASH_SIZE 512          //所选MCU的FLASH容量大小(单位为K)

#if FLASH_SIZE<256
  #defineSECTOR_SIZE           1024    //字节
#else
  #defineSECTOR_SIZE           2048    //字节
#endif

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

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

//从指定地址开始读取多个数据
void FLASH_ReadMoreData(uint32_tstartAddress,uint16_t *readData,uint16_t countToRead)
{
  uint16_tdataIndex;
 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_ttemp1,temp2;
 temp1=*(__IO uint16_t*)address;
 temp2=*(__IO uint16_t*)(address+2);
  return(temp2<<16)+temp1;
}

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

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

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

如下为Flash全擦除过程,

 

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

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

 FLASH_ErasePage(sectorStartAddress);//擦除这个扇区
 
  uint16_tdataIndex;
 for(dataIndex=0;dataIndex<countToWrite;dataIndex++)
  {
   FLASH_ProgramHalfWord(startAddress+dataIndex*2,writeData[dataIndex]);
  }
 
 FLASH_Lock();//上锁写保护
}

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

欢迎关注:

  • 21
    点赞
  • 107
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
STM32F103系列的微控制器内部集成了Flash存储器,可以用来存储数据。可以使用IAP(在应用编程功能)来将未使用的片上Flash用作数据存储。在进行数据写入之前,建议将页面上的数据读取出来,并与要写入的数据合并,然后擦除该页面,最后再将合并后的数据写入。不过,如果数据量较小,也可以每次都将全部数据同时写入,以简化操作并减少数据处理量。对于更深入的了解,可以参考《STM32F10xxx 闪存编程参考手册》。对于大容量产品如STM32F103VE,其Flash容量可达到512K,可以将其中一部分用作数据存储。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [STM32F103 FLASH数据存储实验](https://blog.csdn.net/weixin_46567262/article/details/106572900)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [STM32F103使用内部Flash保存参数](https://blog.csdn.net/foxclever/article/details/52241744)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值