打印

STM32 FLASH模拟EEPROM 使用和优化

[复制链接]
20301|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
banhushui|  楼主 | 2010-5-31 22:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 banhushui 于 2010-6-1 09:32 编辑

感兴趣去21IC博客下载详细说明和优化后的例子
http://blog.21ic.com/user1/5817/archives/2010/69182.html
来自 2楼
banhushui|  楼主 | 2010-6-1 09:50 | 只看该作者
本帖最后由 banhushui 于 2010-6-1 09:51 编辑

STM32 FLASH模拟EEPROM优化
官方例程中读写数据每次要查询读写位置,写数据是从页首地址开始查询,读地址是从页末地址查询。
假如只有1个数据,读数据时效率是很低的,要查到最后才能找到有效数据,
如果页快满了写数据效率也很低,读效率反而好一点了。
实际程序中记录下一个可以写数据的位置将提高数据的读写效率,这样的话:写数据就是立即写不用查询,读数据不从页末地址查询,而是从最后1个写入数据处查询,这样特别在页数据少时效率提高不少。优化过的例子代码只需要增加很少部分就能实现。
增加关键代码
uint32_t CurWrAddress;

//初始化写地址,减少每次读写时查询时间
uint16_t InitCurrWrAddress(void)
{
  FLASH_Status FlashStatus = FLASH_COMPLETE;
  uint16_t ValidPage = PAGE0;
  //uint32_t Address;
  uint32_t PageEndAddress;
  
  /* Get valid Page for write operation */
  ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE);

  /* Check if there is no valid page */
  if (ValidPage == NO_VALID_PAGE)
  {
    CurWrAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
    return  NO_VALID_PAGE;
  }
  
  /* Get the valid Page start Address */
  //Address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
  CurWrAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));

  /* Get the valid Page end Address */
  PageEndAddress = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE));

  /* Check each active page address starting from begining */
  while (CurWrAddress < PageEndAddress)
  {
    /* Verify if Address and Address+2 contents are 0xFFFFFFFF */
    if ((*(__IO uint32_t*)CurWrAddress) == 0xFFFFFFFF)
    {
      
      /* Set variable virtual address */
      FlashStatus = FLASH_COMPLETE;
      /* Return program operation status */
      return FlashStatus;
    }
    else
    {
      /* Next address location */
      CurWrAddress = CurWrAddress + 4;
    }
  }

  /* Return PAGE_FULL in case the valid page is full */
  return PAGE_FULL;
}
详细请看修改后的例子,读写函数也做了相应更改

STM32 FLASH模拟EEPROM进一步优化
上面优化过的例子在写数据无须查询直接写入就可,但是读数据在页数据少是效率提升明显,在页数据多时效率不明显,特别是页数据快满时就跟原来一样的。
说明:不管是官方还是优化过的例子在页交换时这个模拟EEPROM程序都将耗费不少时间的
//================================
如果你对时间要求不高完全不用考虑下面的了。
下面就进一步提升它的效率,方法如下:

为每1个保存的变量定义1个映射地址,就是在写数据时将写数据的地址偏移保存起来。比如第1次的数据映射地址是0,第2次的数据映射地址是1,那么读数据时就可以立即计算出地址。此方法对于1K页大小的每个数据将增加1个8位映射地址,对于2K页大小的每个数据将增加1个16位映射地址.

这里只提供方法,当然方法不是唯一的,有兴趣的自己去玩。

使用特权

评论回复
板凳
banhushui|  楼主 | 2010-6-1 09:32 | 只看该作者
本帖最后由 banhushui 于 2010-6-1 09:40 编辑

错误的例子:
/* 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);//不换页读出数据是对的,换页后读出数据错误
  }
}

使用特权

评论回复
地板
yybj| | 2010-6-1 17:00 | 只看该作者
看起来很不错

使用特权

评论回复
5
香水城| | 2010-6-1 20:37 | 只看该作者
给条裤子,鼓励积极思考。

使用特权

评论回复
6
banhushui|  楼主 | 2010-6-3 12:03 | 只看该作者
夏天热啊,应该给条裙子;P

使用特权

评论回复
7
香水城| | 2010-6-3 12:06 | 只看该作者
夏天热啊,应该给条裙子;P
banhushui 发表于 2010-6-3 12:03


仓库里只有裤子,要穿裙子,自己回去改一下了,改成短裤或裤头也不错,:lol

使用特权

评论回复
8
astudent| | 2010-7-12 22:06 | 只看该作者
cool

使用特权

评论回复
9
zc3909| | 2010-7-13 17:11 | 只看该作者
不错

使用特权

评论回复
10
电子乌托邦| | 2010-7-15 18:25 | 只看该作者
oo

使用特权

评论回复
11
午夜霓虹| | 2010-7-16 08:48 | 只看该作者
没看出什么特别的地方,我水平问题。

使用特权

评论回复
12
xsq5360| | 2011-8-25 22:01 | 只看该作者
酷帖必须顶

使用特权

评论回复
13
火箭球迷| | 2011-8-26 15:54 | 只看该作者
不错,学习就是要多思考

使用特权

评论回复
14
Ryanhsiung| | 2011-8-26 16:18 | 只看该作者
不错,学习

使用特权

评论回复
15
aleda303| | 2011-9-28 16:49 | 只看该作者
加个电池, 将计数指针保存到BKP里面, 主要数据放到flash里, 到时候就可以直接访问不需再去查询了

使用特权

评论回复
16
无风之树| | 2011-10-21 16:55 | 只看该作者
本来还以为公司已经有的那些程序是公司的人写的,原来都是从网上弄下来的,学习

使用特权

评论回复
17
skyline19872007| | 2011-11-4 23:29 | 只看该作者
谢谢楼主啊~~~~~~~~~~~~~

使用特权

评论回复
18
lianaiyy| | 2012-4-20 16:35 | 只看该作者
谢谢分享!!!

使用特权

评论回复
19
dfsa| | 2012-4-20 19:21 | 只看该作者
分析的不错,还是很有启发的

使用特权

评论回复
20
pkat| | 2012-4-20 19:29 | 只看该作者
不错,LZ很有想法

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

33

主题

157

帖子

14

粉丝