治标治本,彻底解决AVR单片机EEPROM数据丢失问题 |
您所在的位置:网站首页 › eeprom区 › 治标治本,彻底解决AVR单片机EEPROM数据丢失问题 |
在项目中复制出来的程序,使用时可能有些地方需要修改。 编译环境:WinAVR-20060421 + AVR Studio 4.12.498 Service Pack 4 基本思路:每份写到EEPRM的数据,都做三个备份,每个备份的数据都做CRC16校验,只要系统运行中出错,错误地修改了EEPROM数据, 那么根据校验字节就知道哪个备份的数据被修改了,然后用正确的备份覆盖出错的备份,达到数据恢复的目的。 EEPROMSave.h 文件: /* EEPROM管理定义 */ #define EepromPageSize 64 //页容量定义 #define EepromPage0Addr 0x0000 //各个页的其始地址定义 #define EepromPage1Addr (EepromPage0Addr + EepromPageSize) #define EepromPage2Addr (EepromPage1Addr + EepromPageSize) #define EepromPage3Addr (EepromPage2Addr + EepromPageSize) #define EepromPage4Addr (EepromPage3Addr + EepromPageSize) #define EepromPage5Addr (EepromPage4Addr + EepromPageSize) #define EepromPage6Addr (EepromPage5Addr + EepromPageSize) #define EepromPage7Addr (EepromPage6Addr + EepromPageSize) /* 最后两个字节为CRC16校验码,其余为数据 | 0 | 1 | 2 | |.......................| 61 | 62 | 63 | Data Data...................Data.....CRCH CRCL */ #define VALID 0x01 #define INVALID 0x00 /*-----------------------------------------------------------------------------------------*/
EEPROMSave.c 文件: /******************************************************************* *函数名称:EepromReadByte() *函数功能:写一个Byte的数据进EEPROM *输入参数:address:地址 *返回参数:从指定地址读出来的数据 *编写作者:my_avr *编写时间:2007年8月13日 *相关说明: ********************************************************************/ unsigned char EepromReadByte(unsigned char *address) { unsigned char data; data = 0; eeprom_busy_wait(); data = eeprom_read_byte(address); return data; } /******************************************************************* *函数名称:EepromReadWord(); *函数功能:写一个Word的数据进EEPROM *输入参数:address:地址 *返回参数:从指定地址读出来的数据 *编写作者:my_avr *编写时间:2007年8月13日 *相关说明: ********************************************************************/ uint16_t EepromReadWord(uint16_t *address) { uint16_t data; data = 0; eeprom_busy_wait(); data = eeprom_read_word(address); return data; } /******************************************************************* *函数名称:EepromWriteByte() *函数功能:写一个Byte的数据进EEPROM *输入参数:address:地址;data:数据 *返回参数:无 *编写作者:my_avr *编写时间:2007年8月13日 *相关说明: ********************************************************************/ void EepromWriteByte(unsigned char *address,unsigned char data) { eeprom_busy_wait(); eeprom_write_byte(address,data); } /******************************************************************* *函数名称:EepromWriteWord() *函数功能:写一个Word的数据进EEPROM *输入参数:address:地址;data:数据 *返回参数: *编写作者:my_avr *编写时间:2007年8月13日 *相关说明: ********************************************************************/ void EepromWriteWord(unsigned int *address,unsigned int data) { eeprom_busy_wait(); eeprom_write_word(address,data); } /******************************************************************* *函数名称:EepromWriteBlock() *函数功能:将缓冲区中的n个数据写进EEPROM *输入参数:address:地址;data:数据 *返回参数: *编写作者:my_avr *编写时间:2007年8月13日 *相关说明: ********************************************************************/ void EepromWriteBlock(unsigned char *buff,unsigned char *address,unsigned char n) { unsigned char i; for (i = 0; i < n; i++) { EepromWriteByte((unsigned char *)(address + i),*buff); buff++; } } /****************************************************************** *函数名称:unsigned char EepromCheck(unsigned char *pdata,unsigned char packsize) *函数功能:检查EEPROM的数据是否有效,采用CRC16校验技术。 一次校验默认最后两个字节为校验码, 需要注意,packsize包括数据长度和校验码字节 *输入参数:pdata:数组指针;packsize:数据长度 *返回参数:数据是否有效,有效:VALID,无效:INVALID *编写作者:my_avr *编写时间:2007年8月21日 *相关说明: ********************************************************************/ unsigned char EepromCheck(unsigned char *pdata,unsigned char packsize) { unsigned char i,j; unsigned int crc,ref_crc; crc = 0; ref_crc = 0; for (i = 0; i < (packsize - 2); i ++) { crc = crc ^ ((uint16_t) EepromReadByte(pdata) |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |