Flash均衡保存算法


Flash均衡保存算法

在实际应用中,用户经常需要在程序运行过程中保存或读取一些数据,这些数据在工作中经常会变化,而且掉电后也不能丢失,所以需要及时地进行存储,存储这些数据常用的存储器是EEPROM。单片机虽然本身不带EEPROM,但是它支持自编程技术,可以利用内部FLASH来模拟EEPROM,这样不仅简化了设计,而且降低了成本。

FLASH的擦写次数是有限的,一般是10W次, FLASH单个存储单元bit只能从1变为0,而不能从0变成1。想要变成1,只能page擦除,这里的page表示一个擦除单位,擦除过程就是把page所有的位都写1,这种硬件特性决定需要一种比较高效的写flash算法。总不能一次更改数值时擦除整一大片FLASH。

改进的保存方法:
        处理方法是将1024字节按16字节大小分成64等份,按后面格式存储参数
        地址 0x10*n +0x00 +0x01  +0x02 ... +0x0E +0x0F
        内容                 flag   data1  data2 ... data15  check_sum
         check_sum=(flag+data1+data2+...+data15)&0xFF
        flag为0xA5表示当前16个字节为正在使用的记录,为其它值表示当前16字节已经丢弃

这种保存方法是使用空间来换取擦写次数。

具体代码实现

定义FLASH页大小,储存数据大小

#define FLASH_PAGE      1024      

#define FLASH_DATAPACK  16  

定义一个储存结构体     

typedef struct {

             u32 Addr;            //地址为flash一页的首地址

             u8  Read;            //读地址的计数

             u8  Write;            //写地址的计数

             u8  ReadBuff[FLASH_DATAPACK];   //读取缓存区

             u8  WriteBuff[FLASH_DATAPACK];   //写入缓存区

}EEPROMTypeDef;

 

//FLASH写函数

void FlashWrite(EEPROMTypeDef *Flash_16)

{

       u8 Flag;

       while_1:

       //获取标志位

 

       Flag = *(vu8*)(Flash_16->Addr + (Flash_16->Write) * FLASH_DATAPACK);

       if(Flash_16->Write < 64 && Flag == 0xff)     //如果地址在一页内且内容空白

       {

      HT_Flash_ByteWrite(Flash_16->WriteBuff, Flash_16->Addr   + (Flash_16->Write++) * FLASH_DATAPACK, FLASH_DATAPACK);

       }

       else if(Flash_16->Write < 63 && Flag != 0xff) //如果地址在一页内却有数据存储

       {

                     Flash_16->Write++;

                     goto while_1;

       }     

       else if(Flash_16->Write >= 64 )//如果地址不在一页内

       {

                     Flash_16->Write = 63;

       }

}

 

//FLASH读函数

void FlashRead(EEPROMTypeDef *Flash_16)

{

       u8 Flag;

       while_1:

   //获取标志位

 

       Flag = *(vu8*)(Flash_16->Addr + (Flash_16->Read) * FLASH_DATAPACK); 

       if(Flash_16->Read < 64 && Flag == 0xA5)  //如果地址在一页之内且数据有效

       {

      HT_Flash_ByteRead(Flash_16->ReadBuff, Flash_16->Addr + (Flash_16->Read) * FLASH_DATAPACK, FLASH_DATAPACK);  

      HT_Flash_ByteWrite(00, Flash_16->Addr + (Flash_16->Read++) * FLASH_DATAPACK, 1);  //标记数据无效

       }

       else if(Flash_16->Read < 64 && Flag != 0xA5)  //如果地址在一页之内但数据无效

     {    

    if(Flag != 0xff)

              {                   

                     Flash_16->Read++;

                     goto while_1;

              }

       }     

       else if(Flash_16->Read >= 64)  //如果地址不在一页之内

       {

              Flash_16->Read = 0;

              Flash_16->Write = 0;

              HT_Flash_PageErase(Flash_16->Addr); //页擦除

       }

}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM