色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > avr eeprom保護(hù)方法

          avr eeprom保護(hù)方法

          作者: 時間:2016-11-23 來源:網(wǎng)絡(luò) 收藏
          在項目中復(fù)制出來的程序,使用時可能有些地方需要修改。
          編譯環(huán)境:WinAVR-20060421+AVRStudio4.12.498ServicePack4


          基本思路:每份寫到EEPRM的數(shù)據(jù),都做三個備份,每個備份的數(shù)據(jù)都做CRC16校驗,只要系統(tǒng)運(yùn)行中出錯,錯誤地修改了EEPROM數(shù)據(jù),
          那么根據(jù)校驗字節(jié)就知道哪個備份的數(shù)據(jù)被修改了,然后用正確的備份覆蓋出錯的備份,達(dá)到數(shù)據(jù)恢復(fù)的目的。


          EEPROMSave.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



          EEPROMSave.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; //數(shù)據(jù)完全無效了
          }

          while((page--)>0) //數(shù)據(jù)恢復(fù)
          {
          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、定義一個數(shù)組:EEPROMData[EepromPageSize-2],數(shù)組定義為EepromPageSize-2是為了給每個備份留2個字節(jié)的校驗
          2、要保存數(shù)據(jù)時,先把數(shù)據(jù)放到數(shù)組中,然后調(diào)用EepromWriteBlock()函數(shù),把這個數(shù)組的數(shù)據(jù)寫進(jìn)EEPROM,三個備份要寫三次。
          3、寫完了之后,調(diào)用CheckWriteCRC()函數(shù),該函數(shù)會計算出當(dāng)前備份的CRC16檢驗數(shù)據(jù)并寫到EEPROM備份的尾部,有多少個備份就要調(diào)用多少次。
          4、至此,數(shù)據(jù)的備份工作已經(jīng)完成。

          5、校驗數(shù)據(jù)(一般在復(fù)位后運(yùn)行),執(zhí)行CheckAllPage()函數(shù),若通過了,則EEPROM數(shù)據(jù)沒有問題,否則要運(yùn)行DataRecover()函數(shù),對損壞的備份進(jìn)行修復(fù)






          ------------------修改原因:修改變量的定義形式


          關(guān)鍵詞: avreeprom保護(hù)方

          評論


          技術(shù)專區(qū)

          關(guān)閉