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