在我们应用开发时,经常会有一些程序运行参数需要保存,如一些修正系数。这些数据的特点是:数量少而且不需要经常修改,但又不能定义为常量,因为每台设备可能不一样而且在以后还有修改的可能。将这类数据存在指定的位置,需要修改时直接修改存储位置的数值,需要使用时则直接读取,会是一种方便的做法。考虑到这些数据量比较少,使用专门的存储单元既不经济,也没有必要,而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~255uint32_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 闪存编程参考手册》。

欢迎关注:

STM32F103使用内部Flash保存参数相关推荐

  1. STM32 烧录程序后无法在内部FLASH保存数据问题解决

    STM32 烧录程序后无法在内部FLASH保存数据问题解决 新接手一套代码,要求在Flash特定区域保存数据.硬件为STM32F030C6,有32k Flash. 原代码中已经将数据打包成一个结构体, ...

  2. STM32F103 读写内部FLASH—学习笔记(野火)

    STM32F103的Flash类型是NOR Flash 烧录过程:调试器→STM32的SRAM→运行→Flash 内部Flash比外部Flash更高效,原因是使用了内部总线,且工作频率是72MHz 2 ...

  3. STM32F103标准库开发:内部Flash的读写

    本文章技术信息均出自:STM32F103系列超详细参考手册-中文版 STM32F103标准库开发-目录 一.STM32存储器介绍 STM32存储器分为以下两种: 1. 随机存储器-RAM RAM是与C ...

  4. c语言 将结构体放在flash,stm32的内部flash读写操作(含结构体的保存)

    不同的stm32单片机的flash大小不同,这个需要查阅芯片手册或者查看STM32CubeMX软件. stm32的flash地址起始于0x0800 0000,结束地址是0x0800 0000加上芯片实 ...

  5. STM32F103C8T6的内部Flash以及实例

    文章目录 〇.EEPROM与Flash(知识储备) 一.STM32F103内部 二.SD卡的读写 1. 说明 2.实验过程 3.从SD卡里读出数据 3.1 代码修改 3.2 结果显示 三.将内容写入f ...

  6. GD32F303固件库开发(17)----内部Flash读写

    概述 本例程主要讲解如何对芯片自带Flash进行读写,用芯片内部Flash可以对一些需要断电保存的数据进行保存,无需加外部得存储芯片,本例程采用的是GD32F303ZET6主控,512K大小的Flas ...

  7. 第50章 读写内部FLASH—零死角玩转STM32-F429系列

    第50章     读写内部FLASH 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...

  8. Flash保存GPS经纬度信息

    Flash保存GPS经纬度信息 文章目录 Flash保存GPS经纬度信息 flash简介 程序设计思路 技术要点 一.浮点数写入 FLASH 二.FLASH 写入及读取 三.将读取回来的值转化为浮点型 ...

  9. STM32读写内部flash

    概念:计算机中最小的信息单位是bit,也就是一个二进制位,8个bit组成一个Byte,也就是1个字节, 1个存储单元存放1个字节,每个存储单元对应一个32位(bit)地址,所以重要的话说三遍:对于32 ...

最新文章

  1. ISSCC 2021前瞻,智能传感器和IoT端是大势所趋 | AI日报
  2. Nodejs开发微信公众号中控服务
  3. 【经验】刚读硕士怎么感觉学机器学习和深度学习越学越不懂?
  4. boost::leaf::try_handle_some用法的测试程序
  5. Maven项目中获取classpath和资源文件的路径
  6. 为PHP5.4开启Zend OPCode缓存
  7. 仓库的种类和彼此关系
  8. 殷墟 太行山 红旗渠
  9. 一个优雅的报警处理系统范例
  10. 基于Hadoop 2.6.0运行数字排序的计算
  11. python假设有一段英文、其中有单独的字母_峰终定律是诺贝尔奖获得者丹尼尔卡尼曼提出的。他发现,我们对一件事的整体评价,是全过程中所有元素体验的平均分。...
  12. Dubbo与Zookeeper伪集群部署
  13. 20.QT-Qpixmap实现图片鼠标缩放,鼠标拖动示例(详解)
  14. unity性能优化初级入门篇
  15. readyread信号不触发_什么是示波器的触发,意外发现!
  16. 如何学好图像处理——从小白到大神?
  17. 工程计算和数据科学中常用的9种测量距离
  18. 什么是基于web开发,CSS的浮动属性,干货满满!
  19. 软件测试工作中遇到的痛点,RPA解决方案:几个典型行业痛点工作场景
  20. 跨域解决方式——JSONP,CORS

热门文章

  1. Java -- 异常的捕获及处理 -- 范例 -- throw与throws的应用
  2. 定义一个Matrix类,实现矩阵的加法和乘法
  3. 每天看一片代码系列(三):codepen上一个音乐播放器的实现
  4. VS2005 添加 Microsoft.Office.Tools.Word.dll 等引用
  5. C++学习——内联函数
  6. LeetCode LCP 06. 拿硬币
  7. 【剑指offer】面试题47:礼物的最大价值(Java)
  8. Leetcode--134. 加油站
  9. linux应用程序课程设计,linux操作系统与应用课程设计 .pdf
  10. linux连接外部库时候编译,交叉编译时如何使用外部库?