STM32 FLASH模拟 EEPROM

发布者:数字翻飞最新更新时间:2018-08-19 来源: eefocus关键字:STM32  FLASH  模拟  EEPROM 手机看文章 扫描二维码
随时随地手机看文章

原始文件ST 官方有例子和文档:AN2594
http://www.st.com/mcu/familiesdocs-110.html
看到不少网上使用官方例子程序不成功的问题,我估计大概是没详细阅读官方文档的原因吧,也许很多人没理
解官方例子的原理。那么下面就详细说明一下原理再说如何优化。
原理如下:


首先使用2 页FLASH 空间,如果0 页空间写满数据,那么把0 页空间里面的【有效数据】复制到1 页,如果1
页数据满那么把1 页空间里面的【有效数据】复制到0 页,这样循环使用,当然如果你想增加使用寿命可以增
加多页循环,官方例子只是按2 页实现的例子。每页前面4 字节保留,其中前2 字节是该页状态标志
下面的图显示数据在FLASH 中的保存格式:

保存数据是16 位的,后面16 位是该数据的虚拟地址,注意:1 个数据有唯1 个虚拟地址,地址必须为:0~0xfffe
范围内(每页将按4 字节分块,1 块保存1 个16 位数据)。下面继续说明16 位虚拟地址的作用。


Figure 3 显示了数据更新的过程:
1. 写数据
假设保存的数据虚拟地址是0X7777,那么程序写数据是从当前有效页页首地址开始查询虚拟地址位置为

0XFFFF 的空间,如果是0XFFFF 那么该位置可以保存数据;如果不是,那么继续找下1 个位置,如果本

页无0XFFFF 的空间那么表示本页已满,那么将本页【有效数据】复制到另外1 页继续保存数据。
当两次保存同一虚拟地址的数据时如下图所示:从上到下,第2 个虚拟地址是0X7777 对应的数据1245 才

是有效的。清楚了这点,那么读数据要怎么处理基本就明白了。


2. 读数据
读数据时是从有效页的末尾地址开始检测是否是有效数据,如果是那么立即返回,程序是通过虚拟地址判断有
效数据的,第1 个匹配的虚拟地址的数据才是有效的
3. 页满时处理数据
说到这里,看到不少使用例子程序不成功的问题,那么就请注意下面了,他们的错误估计是下面的原因造成的。
当1 页写满时其实里面有很多无效数据,你只需要将【有效数据】复制到另外1 页就成。如何复制有效数据呢?
我想很多人估计忽略了 【#define NumbOfVar ((uint8_t)0x03) /* Variables' number */】,NumbOfVar 就是你程
序中实际要保存的数据量,这个必须与实际保持一致,不能多也不能少,这个如果不一致,那么在换页时将出
错,没换页之前倒是没问题的,原因在于:程序在换页时将根据NumbOfVar 的值复制有效数据的个数,如果比
实际少,那么换页时将丢失数据,如果比实际多那么将出现旧数据覆盖最新数据

错误的例子:
/* Variables' number */
#define NumbOfVar ((uint8_t)0x05)
uint16_t VirtAddVarTab[NumbOfVar] = {0, 1, 2};
//NumbOfVar 定义的比用的多实际是{0, 1, 2, 0, 0},虚拟地址0 的数据换页后将出现旧数据覆盖最新数据
int main(void)
{
uint16_t temp;
for (VarValue = 0; VarValue < 100; VarValue++)
{
EE_WriteVariable(VirtAddVarTab[0], VarValue+10);
}
for (VarValue = 0; VarValue < 500; VarValue++)
{
EE_WriteVariable(VirtAddVarTab[1], VarValue);
temp=0;
EE_ReadVariable(0, &temp);//不换页读出数据是对的,换页后读出数据错误
}
}
//====================================================================================
/* Variables' number */
#define NumbOfVar ((uint8_t)0x03)
uint16_t VirtAddVarTab[NumbOfVar] = {0, 1, 2};
//NumbOfVar 定义为3,下面用到虚拟地址超过VirtAddVarTab 表里面的值
int main(void)
{
uint16_t temp;
for (VarValue = 0; VarValue < 100; VarValue++)
{
EE_WriteVariable(VirtAddVarTab[0], VarValue);
}
for (VarValue = 0; VarValue < 50; VarValue++)
{
EE_WriteVariable(3, VarValue+2);
}
for (VarValue = 0; VarValue < 200; VarValue++)
{
EE_WriteVariable(2, VarValue);
temp=0;
EE_ReadVariable(3, &temp);//不换页读出数据是对的,换页后读出数据错误
}
}
STM32 FLASH 模拟EEPROM 使用注意:
不少人问该程序的FLASH 保存数据多少和使用寿命
保存数据多少跟FLASH 页大小有关,如果页大小是1K 那么只能保存1024/4-1=256-1 个16 位数据,如果你保
存8 位数,你可以2 个8 位数据组合后保存或者直接保存,如果保存32 位数据那就拆成2 个16 位保存,当然
关于寿命
现在STM32 的FLASH 寿命是10000 次,
如果你保存255 个数据那么每次修改1 个数据FLASH 就要擦写1 次,如果你保存1 个数据,那么你修改255
次该页才擦1 次,继续用另外1 页,建议保存数据个数不要超过50%,当然如果你的数据基本都不修改你保存
255 个也是没有任何问题(你的数据都不修改根本不用关心寿命问题了:)。
STM32 FLASH 模拟EEPROM 优化
官方例程中读写数据每次要查询读写位置,写数据是从页首地址开始查询,读地址是从页末地址查询。
假如只有1 个数据,读数据时效率是很低的,要查到最后才能找到有效数据,
如果页快满了写数据效率也很低,读效率反而好一点了。
实际程序中记录下一个可以写数据的位置将提高数据的读写效率,这样的话:写数据就是立即写不用查询,读
数据不从页末地址查询,而是从最后1 个写入数据处查询,这样特别在页数据少时效率提高不少。优化过的例
子代码只需要增加很少部分就能实现。
增加关键代码
uint32_t CurWrAddress;
//初始化写地址,减少每次读写时查询时间
uint16_t InitCurrWrAddress(void)
详细请看修改后的例子,读写函数也做了相应更改
STM32 FLASH 模拟EEPROM 进一步优化
上面优化过的例子在写数据无须查询直接写入就可,但是读数据在页数据少是效率提升明显,在页数据多时效
率不明显,特别是页数据快满时就跟原来一样的。
说明:不管是官方还是优化过的例子在页交换时这个模拟EEPROM 程序都将耗费不少时间的
如果你对时间要求不高完全不用考虑下面的了。
下面就进一步提升它的效率,方法如下:
为每1 个保存的变量定义1 个映射地址,就是在写数据时将写数据的地址偏移保存起来。比如
第1 次的数据映射地址是0,第2 次的数据映射地址是1,那么读数据时就可以立即计算出地址。
此方法对于1K 页大小的每个数据将增加1 个8 位映射地址,对于2K 页大小的每个数据将增加
1 个16 位映射地址.
这里只提供方法,当然方法不是唯一的,有兴趣的自己去玩。

 

个人觉得,模拟固然是一根不错的方法,但风险也很大。如果模拟程序出错的话,数据很难恢

复,并且问题定位也不是很容易。用来保存关键数据的存储区的读写应该尽量使用简单的方案,

以确保数据的可靠性。


关键字:STM32  FLASH  模拟  EEPROM 引用地址:STM32 FLASH模拟 EEPROM

上一篇:STM32内部FLASH读写-通用
下一篇:STM32:Flash擦除与读写操作(HAL库)

推荐阅读最新更新时间:2024-03-16 16:11

MCU内嵌Flash内存成趋势 出货比重过半
因应MCU成长快速及程序数据储存需要,MCU内嵌Flash内存设计成为主流趋势,MCU大厂也纷纷以购并或结盟掌握内嵌Flash的相关IP与制程技术。本文将探讨内嵌Flash IP制程技术,为下一代Flash MCU带来的技术变革。 Flash MCU出货比重过半 掌握Flash成为MCU开发关键 因应MCU成长快速,所带动的程序代码与数据储存需要,MCU内嵌内存类型也从早期Maskrom、EPROM、EEPROM到Flash内存。据市调机构预估,内嵌Flash内存的MCU在2010年出货比重超过50%。也因此MCU大厂也急于掌握内嵌Flash内存相关IP与制程技术。像Microchip就购并闪存大厂SST。提供MCU内
[手机便携]
基于STM32单片机的雷管电子保险装置设计
雷管使用中如果引爆系统屏蔽不够完善,使雷管中流过泄漏电流和电容电流达到一定的数值和作用时间,电流转化成足够的热能达到雷管炸药点燃温度(约180℃)时即可引爆,电雷管耐静电压为(1~3)×104V,超过(1~3)×104V 的静电压,从而引爆电雷管,造成爆破材料发生意外爆炸事故。本课题是在参阅了国内外关于雷管安全保险发展技术资料的基础上进行的国内雷管防护措施开发和研制的一次有益的尝试和探索,简要介绍了STM32F103RBT6 的主要功能和性能,完成了系统整体设计。 1.STM32F103RBT6简介 STM32F103RBT6 是一种高性能32 位微控制器(MICrocontrollerUnit),是意法半导体公司
[单片机]
基于<font color='red'>STM32</font>单片机的雷管电子保险装置设计
STM32-FSMC-LCD详解
LCD有如下控制线: CS:Chip Select 片选,低电平有效 RS:Register Select 寄存器选择 WR:Write 写信号,低电平有效 RD:Read 读信号,低电平有效 RESET:重启信号,低电平有效 DB0-DB15:数据线 假如这些线,全部用普通IO口控制。根据LCD控制芯片手册(大部分控制芯片时序差不多): 如果情况如下: DB0-DB15的IO全部为1(表示数据0xff),也可以为其他任意值,这里以0xff为例。 CS为0(表示选上芯片,CS拉低时,芯片对传入的数据才会有效) RS为1(表示DB0-15上传递的是要被写到寄存器的值),如果为0,表示传递的是数据。 WR为0,RD为1(表示是写动作)
[单片机]
STM32时钟初始化函数SystemInit()详解
花了一天的时间,总算是了解了SystemInit()函数实现了哪些功能,初学STM32,,现记录如下(有理解错误的地方还请大侠指出): 使用的是3.5的库,用的是STM32F107VC,开发环境RVMDK4.23 我已经定义了STM32F10X_CL,SYSCLK_FREQ_72MHz 函数调用顺序: startup_stm32f10x_cl.s(启动文件) → SystemInit() → SetSysClock () → SetSysClockTo72() 初始化时钟用到的RCC寄存器复位值: RCC_CR = 0x0000 xx83; RCC_CFGR = 0x0000 0000;RCC_CIR = 0x0000 0000;
[单片机]
<font color='red'>STM32</font>时钟初始化函数SystemInit()详解
STM32 DMA 多通道
ADC_init.C #define ADC1_DR_Address ((uint32_t)0x4001244C) extern vu16 After_filter ; //用来存放求平均值之后的结果 extern vu16 ADCConvertedValue ; DMA_InitTypeDef DMA_InitStructure; //DMA总线枚举类型 ADC_InitTypeDef ADC_InitStructure; //ADC 枚举类型 /******************************************************************************* * 函数名称: GP
[单片机]
使用微控制器集成模拟比较器以提供电源保护并降低电路板空间
简介 现在,越来越多的设计师开始转向电子微控制器,以在电机控制和数字电源系统中控制功率级。 使用微控制器(例如德州仪器 (TI) 的 C2000™ Piccolo™ 微控制器)的集成模拟比较器功能可以保护系统电源,同时也可使设计师减少板级所需的外部模拟组件的数量。在此类电机控制和数字电源系统中,在微控制器自身发生执行错误的情况下防止发生过压或欠压时,设计师仍局限于模拟域。 通过使用 TI C2000 Piccolo 微控制器系列的集成模拟功能,可以围绕单个控制器来设计系统,而不需要外部支持电路。这主要涉及使用模拟比较器来监控功率级模拟域中的过压或欠压以及过流或欠流事件。 Piccolo 微处理器的优势 Piccolo 微控制
[传感器]
使用微控制器集成<font color='red'>模拟</font>比较器以提供电源保护并降低电路板空间
STM32开发板中如何点亮一个LCD
网络上配套STM32开发板有很多LCD例程,主要是TFT LCD跟OLED的。从这些例程,大家都能学会如何点亮一个LCD。但这代码都有下面问题: 分层不清晰,通俗讲就是模块化太差。 接口乱。只要接口不乱,分层就会好很多了。 可移植性差。 通用性差。 为什么这样说呢?如果你已经了解了LCD的操作,请思考如下情景: 1、代码空间不够,只能保留9341的驱动,其他LCD驱动全部删除。能一键(一个宏定义)删除吗?删除后要改多少地方才能编译通过? 2、有一个新产品,收银设备。系统有两个LCD,都是OLED,驱动IC相同,但是一个是128x64,另一个是128x32像素,一个叫做主显示,收银员用;一个叫顾显,顾客看金额。怎么办?这些例
[单片机]
瑞萨e2studio----串口获取数据通过SPI存储于W25Q128外部flash
1.概述 本篇文章主要介绍如何使用e2studio对瑞萨进行spi配置,同时移植stm32上的W25Q128到瑞萨上,同时通过对该FLASH进行读写操作,验证是否正确。 2.硬件准备 首先需要准备一个开发板,这里我准备的是芯片型号 R7FA2L1AB2DFL 的开发板。 3.新建工程 4.工程模板 5.保存工程路径 6.芯片配置 本文中使用R7FA2L1AB2DFL来进行演示。 7 7.工程模板选择 8.SPI配置 点击Stacks- New Stack- Driver- Connectivity- SPI Driver on r_spi。 9.S
[单片机]
瑞萨e2studio----串口获取数据通过SPI存储于W25Q128外部<font color='red'>flash</font>
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved