amoBBS 阿莫电子论坛

 找回密码
 注册
搜索
bottom↓
查看: 540|回复: 0

分享个STC15F系列单片机D_FLASH备份程序

[复制链接]
发表于 2015-12-11 21:30:47 | 显示全部楼层 |阅读模式
自己写的,程序采用双备份和CRC校验的方法来保证数据的正确性,一般的应用场合应该够用了,欢迎拍砖
全部程序在附件里
顺便请教下,芯片手册里说的可以用MOVC指令读D_FLASH,具体怎么实现的?对汇编不怎么熟
  1. #include "hwa_eeprom.h"
  2. #include "hwa_eeprom_cfg.h"
  3. #include "sys_eeprom.h"
  4. #include "string.h"


  5. static UINT16 hwa_eepromCheck( UINT8 *dat, UINT16 len)
  6. {
  7.     UINT16 crc = 0xFFFF;
  8.     UINT8 i;
  9.     while(len--)
  10.     {
  11.         crc = crc ^*dat++;
  12.         for ( i = 0; i < 8; i++)
  13.         {
  14.             if( ( crc & 0x0001) > 0)
  15.             {
  16.                 crc = crc >> 1;
  17.                 crc = crc ^ 0xa001;
  18.             }
  19.             else
  20.             {
  21.                 crc = crc >> 1;
  22.             }
  23.         }
  24.     }
  25.     return ( crc );
  26. }

  27. void hwa_eepromInit(void)
  28. {
  29. }

  30. BOOL hwa_eepromReadSector(UINT8 *dat, UINT8 sector)
  31. {
  32.         BOOL e2_error = FALSE, e2_bak_error = FALSE;
  33.         UINT16 e2_addr, e2_bak_addr;
  34.         UINT16 e2_check_sum, e2_bak_check_sum;
  35.         UINT16 Size, SectorSize;

  36.         if (sector >= c_u8_eepromSectorNum)
  37.         {
  38.                 return FALSE;
  39.         }
  40.         Size = c_s_eepromConfig[sector].UseSize;
  41.         SectorSize = Size + 2;

  42.         e2_addr = c_u16_eepromSectorAddr + c_u16_eepromSectorSize * sector;
  43.         e2_bak_addr = c_u16_eepromSectorBakAddr + c_u16_eepromSectorSize * sector;

  44.         sys_eepromRead(e2_addr, e2_data, SectorSize);
  45.         if (c_s_eepromConfig[sector].Encrypt)
  46.         {
  47.                 hwa_eepromDecrypt(e2_data, Size);
  48.         }
  49.         e2_check_sum = e2_data[Size] << 8 | e2_data[Size + 1];

  50.         sys_eepromRead(e2_bak_addr, e2_data_bak, SectorSize);
  51.         if (c_s_eepromConfig[sector].Encrypt)
  52.         {
  53.                 hwa_eepromDecrypt(e2_data_bak, Size);
  54.         }
  55.         e2_bak_check_sum = e2_data_bak[Size] << 8 | e2_data_bak[Size + 1];

  56.         if (e2_check_sum != hwa_eepromCheck(e2_data, Size))
  57.         {
  58.                 e2_error = TRUE;
  59.         }
  60.         if (e2_bak_check_sum != hwa_eepromCheck(e2_data_bak, Size))
  61.         {
  62.                 e2_bak_error = TRUE;
  63.         }

  64.         if (e2_error && e2_bak_error)    //~1~备份块和正常块都校验错误,返回错误
  65.         {
  66.                 return FALSE;
  67.         }
  68.         else if (e2_error)                                 //~2~正常块校验错误,恢复正常块
  69.         {
  70.                 memcpy(e2_data, e2_data_bak, SectorSize);
  71.                 sys_eepromEraseSector(e2_addr);
  72.                 sys_eepromWrite(e2_addr, e2_data, SectorSize);
  73.         }
  74.         else if (e2_bak_error ||                          //~3~备份块校验错误,恢复备份块
  75.                 (e2_error == FALSE                                //~4~正常块、备份块都检验正确,但数据不同,则以
  76.                 && e2_bak_error == FALSE                         //   最新写入的正常块覆盖备份块
  77.                 && e2_check_sum != e2_bak_check_sum)
  78.                 )
  79.         {
  80.                 memcpy(e2_data_bak, e2_data, SectorSize);
  81.                 sys_eepromEraseSector(e2_bak_addr);
  82.                 sys_eepromWrite(e2_bak_addr, e2_data_bak, SectorSize);
  83.         }
  84.         memcpy(dat, e2_data, Size);
  85.         return TRUE;
  86. }

  87. BOOL hwa_eepromWriteSector(UINT8 *dat, UINT8 sector)
  88. {
  89.         UINT16 e2_addr, e2_bak_addr;
  90.         UINT16 e2_check_sum;

  91.         UINT16 Size, SectorSize;

  92.         if (sector >= c_u8_eepromSectorNum)
  93.         {
  94.                 return FALSE;
  95.         }
  96.         Size = c_s_eepromConfig[sector].UseSize;
  97.         SectorSize = Size + 2;

  98.         e2_addr = c_u16_eepromSectorAddr + c_u16_eepromSectorSize * sector;
  99.         e2_bak_addr = c_u16_eepromSectorBakAddr + c_u16_eepromSectorSize * sector;
  100.         e2_check_sum = hwa_eepromCheck(dat, Size);

  101.         hwa_eepromReadSector(e2_data, sector);                                  //  写入之前,如果有错误块,先恢复

  102.         memcpy(e2_data, dat, Size);

  103.         if (c_s_eepromConfig[sector].Encrypt)
  104.         {
  105.                 hwa_eepromEncrypt(e2_data, Size);
  106.         }
  107.         e2_data[Size] = (UINT8)(e2_check_sum >> 8);
  108.         e2_data[Size + 1] = (UINT8)(e2_check_sum & 0xFF);
  109.         sys_eepromEraseSector(e2_addr);
  110.         sys_eepromWrite(e2_addr, e2_data, SectorSize);

  111.         //    memcpy(e2_data_bak, e2_data, SectorSize);
  112.         sys_eepromEraseSector(e2_bak_addr);
  113.         sys_eepromWrite(e2_bak_addr, e2_data, SectorSize);
  114.         return TRUE;
  115. }
复制代码

hwa_eeprom.zip

4.1 KB, 下载次数: 157

友情提示:标题不合格、重复发帖,将会被封锁ID。详情请参考:论坛通告:封锁ID、获得注册邀请码、恢复被封ID、投诉必读
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|阿莫电子论坛(原ourAVR/ourDEV) ( 公安备案:44190002001997(交互式论坛) 工信部备案:粤ICP备09047143号 )

GMT+8, 2019-6-19 18:37

阿莫电子论坛, 原"中国电子开发网"

© 2004-2018 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表