AVR内部EEPROM数据丢失问题的原因与解决方案
1.Mega168EEPROM512字节,把EEPROM分为两个区,每个区256个字节,然后以8个字节为一个段,那么每个区就有32段。
数据区:0x000-0x0FF
0段:0x000-0x007
1段:0x008-0x00F
……
31段:0x0F8-0x0FF
备份区:0x100-0x1FF
每个段8个字节,其中前6个字节为有效数据,后2个字节为CRC16校验,数据格式下图所示:
2.EEPROM读写操作
EEPROM的操作以段为单位,
段写入函数:写数据到数据区时,先计算数据CRC16校验,然后同时把数据写入到数据区和备份区;
段读取函数:读取数据时,同时读取数据区以及备份区,如果数据区校验有误,备份区数据校验正确,就用备份区数据恢复数据区数据;
如果备份区数据有误,数据区数据正确,那么数据写入备份区重新备份;如果数据区备份区数据都有误,那么返回读取失败。
3.数据区与备份区的对应关系
数据读写操作以段进行,内部的数据区与备份区怎么映射呢?为了防治数据与备份同时被意外修改,那么数据与备份地址空间相隔不能太
近,并且数据与备份的地址,应该尽量不同。假设数据地址为Data_Addr,备份地址为Bakup_Addr,我使用下面的函数映射地址:
Bakup_Addr=(Data_Addr+0x100)^0x03F
加0x100是把地址定义到备份区,与0x03F异或,是把低6bits取反,这样处理,数据与备份的地址空间较远,并且地址有7bits的不同。
例如,第3段的地址:0x018-0x01F,
对应的备份区为:0x127-0x120
如下图所示:
4.读写函数加入写保护判断,在读写EEPROM前关闭写保护,读写完毕后,立即开启写保护,这样可以有效防止程序跑飞造成的EEPROM意外修改
。
5.第0块建议禁止使用。
评论