• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > EDA/PCB > 設計應用 > avr eeprom保護方法.

    avr eeprom保護方法.

    作者: 時間:2024-05-10 來源:EDA365 收藏

    在項目中復制出來的程序,使用時可能有些地方需要修改。
    編譯環境:WinAVR-20060421+AVRStudio4.12.498ServicePack4
    基本思路:每份寫到EEPRM的數據,都做三個備份,每個備份的數據都做CRC16校驗,只要系統運行中出錯,錯誤地修改了數據,
    那么根據校驗字節就知道哪個備份的數據被修改了,然后用正確的備份覆蓋出錯的備份,達到數據恢復的目的。
    Save.h文件:
    #defineEepromPageSize 64 //頁容量定義
    #defineEepromPage0Addr 0x0000 //各個頁的其始地址定義
    #defineEepromPage1Addr (EepromPage0Addr+EepromPageSize)
    #defineEepromPage2Addr (EepromPage1Addr+EepromPageSize)
    #defineEepromPage3Addr (EepromPage2Addr+EepromPageSize)
    #defineEepromPage4Addr (EepromPage3Addr+EepromPageSize)
    #defineEepromPage5Addr (EepromPage4Addr+EepromPageSize)
    #defineEepromPage6Addr (EepromPage5Addr+EepromPageSize)
    #defineEepromPage7Addr (EepromPage6Addr+EepromPageSize)
    #defineVALID 0x01
    #defineINVALID 0x00
    Save.c文件:
    unsignedcharEepromReadByte(unsignedchar*address)
    {
    unsignedchardata;
    data=0;
    eeprom_busy_wait();
    data=eeprom_read_byte(address);
    returndata;
    }
    uint16_tEepromReadWord(uint16_t*address)
    {
    uint16_tdata;
    data=0;
    eeprom_busy_wait();
    data=eeprom_read_word(address);
    returndata;
    }
    voidEepromWriteByte(unsignedchar*address,unsignedchardata)
    {
    eeprom_busy_wait();
    eeprom_write_byte(address,data);
    }
    voidEepromWriteWord(unsignedint*address,unsignedintdata)
    {
    eeprom_busy_wait();
    eeprom_write_word(address,data);
    }
    voidEepromWriteBlock(unsignedchar*buff,unsignedchar*address,unsignedcharn)
    {
    unsignedchari;
    for(i=0;i<n;i++)
    {
    EepromWriteByte((unsignedchar*)(address+i),*buff);
    buff++;
    }
    }
    unsignedcharEepromCheck(unsignedchar*pdata,unsignedcharpacksize)
    {
    unsignedchari,j;
    unsignedintcrc,ref_crc;
    crc=0;
    ref_crc=0;
    for(i=0;i<(packsize-2);i++)
    {
    crc=crc^((uint16_t)EepromReadByte(pdata)<<8);
    for(j=0;j<8;j++)
    {
    if(crc&0x8000)
    {
    crc=(crc<<1)^0x1021;
    }
    else
    {
    crc=crc<<1;
    }
    }
    pdata++;
    }
    ref_crc=(uint16_t)EepromReadByte(pdata);
    ref_crc=ref_crc<<8;
    pdata++;
    ref_crc|=(uint16_t)EepromReadByte(pdata);
    if(crc==ref_crc)
    {
    returnVALID;
    }
    else
    {
    returnINVALID;
    }
    }
    unsignedcharCheckWriteCRC(unsignedchar*pdata,unsignedcharpacksize)
    {
    unsignedchari,j;
    unsignedintcrc;
    crc=0;
    for(i=0;i<(packsize-2);i++)
    {
    crc=crc^((uint16_t)EepromReadByte(pdata)<<8);
    for(j=0;j<8;j++)
    {
    if(crc&0x8000)
    {
    crc=(crc<<1)^0x1021;
    }
    else
    {
    crc=crc<<1;
    }
    }
    pdata++;
    }
    EepromWriteByte(pdata,(uint8_t)(crc>>8));
    pdata++;
    EepromWriteByte(pdata,(uint8_t)crc);
    pdata++;
    if(EepromCheck((pdata-packsize),packsize))
    {
    returnVALID;
    }
    else
    {
    returnINVALID;
    }
    }
    uint8_tCheckAllPage(void)
    {
    if((EepromCheck((unsignedchar*)EepromPage1Add,EepromPageSize)==VALID)
    &&(EepromCheck((unsignedchar*)EepromPage2Add,EepromPageSize)==VALID)
    &&(EepromCheck((unsignedchar*)EepromPage3Add,EepromPageSize)==VALID))
    {
    returnVALID;
    }
    returnINVALID;
    }
    uint8_tDataRecover(void)
    {
    unsignedchari;
    unsignedchartemp;
    unsignedcharpage;
    unsignedintinvalidpage[3];
    unsignedintvalidpage;
    invalidpage[0]=0;
    invalidpage[1]=0;
    invalidpage[2]=0;
    validpage=0;
    temp=0;
    page=0;
    if(EepromCheck((uint8_t*)EepromPage1Add,EepromPageSize)==VALID)
    {
    validpage=EepromPage1Add;
    }
    else
    {
    invalidpage[page]=EepromPage1Add;
    page++;
    }
    if(EepromCheck((uint8_t*)EepromPage2Add,EepromPageSize)==VALID)
    {
    validpage=EepromPage2Add;
    }
    else
    {
    invalidpage[page]=EepromPage2Add;
    page++;
    }
    if(EepromCheck((uint8_t*)EepromPage3Add,EepromPageSize)==VALID)
    {
    validpage=EepromPage3Add;
    }
    else
    {
    invalidpage[page]=EepromPage3Add;
    page++;
    }
    if(page==3) //三個備份都被破壞了
    {
    returnINVALID; //數據完全無效了
    }
    while((page--)>0) //數據恢復
    {
    for(i=0;i<EepromPageSize;i++)
    {
    temp=EepromReadByte((uint8_t*)(validpage+i));
    EepromWriteByte((uint8_t*)(invalidpage[page]+i),temp);
    }
    }
    if(CheckAllPage()==VALID)
    {
    returnVALID;
    }
    returnINVALID;
    }
    使用方法(三個備份):
    1、定義一個數組:EEPROMData[EepromPageSize-2],數組定義為EepromPageSize-2是為了給每個備份留2個字節的校驗
    2、要保存數據時,先把數據放到數組中,然后調用EepromWriteBlock()函數,把這個數組的數據寫進EEPROM,三個備份要寫三次。
    3、寫完了之后,調用CheckWriteCRC()函數,該函數會計算出當前備份的CRC16檢驗數據并寫到EEPROM備份的尾部,有多少個備份就要調用多少次。
    4、至此,數據的備份工作已經完成。
    5、校驗數據(一般在復位后運行),執行CheckAllPage()函數,若通過了,則EEPROM數據沒有問題,否則要運行DataRecover()函數,對損壞的備份進行修復

    本文引用地址:http://www.czjhyjcfj.com/article/202405/458561.htm


    關鍵詞: EEPROM avr

    評論


    相關推薦

    技術專區

    關閉
    主站蜘蛛池模板: 枣强县| 阳东县| 大姚县| 瑞昌市| 宁津县| 金寨县| 新平| 普定县| 永靖县| 夏津县| 恭城| 游戏| 平泉县| 安义县| 神木县| 襄汾县| 新宁县| 沁水县| 双辽市| 靖宇县| 克东县| 招远市| 绵竹市| 建湖县| 阿图什市| 周至县| 白河县| 新巴尔虎右旗| 瑞丽市| 启东市| 乐至县| 镇赉县| 辽中县| 太白县| 宕昌县| 准格尔旗| 中西区| 富川| 柞水县| 贵州省| 巴楚县|