avrEEPROM数据丢失问题原因与解决方案
avr EEPROMavr EEPROM 数据丢失问题数据丢失问题 原因与解决方原因与解决方 案案 总结一下引起 AVR 内部 EEPROM 数据丢失的原因: 1.程序问题; 2.程序跑飞; 3.EEPROM 相关寄存器因强磁场、高压静电等外部干 扰出错所产生的写入动作; 4.系统有很大的感性负载,在断电的时候会产生一 个反向高压,EEPROM 有可能会自擦除。 (还有什么原因,欢迎大家继续列 举,以便完善及想办法解决) 针对问题 1,程序问题不再该文讨论范围内。 针对问题 2,程序跑飞,这个因该是引起 EEPROM 数 据丢失的主要原因。但是引起程序跑飞的原因却是多方 面的。 第一.电压不正常,工作不稳定,程序跑飞。针对这 个问题,可以开启内部 BOD、或者外加复位芯片解决, 在低功耗场合,外部复位是有必 要的,毕竟 BOD 功耗太高。 第二,晶体振荡受干扰,频率不稳定,程序跑飞。 针对这个问题,建议晶体使用全幅振荡,并且走线的时 候尽量短,并且使用地线隔离。 第三系统受外界环境干扰,修改了 PC 等寄存器,程 序跑飞。针对这个干扰问题,这个引起程序跑飞的可能 性应该不大,如果环境实在恶劣 ,那么就应该想到做电磁屏蔽,ESD 保护等,如果还不 行,那么只能建议换换别的单片机试试看了。 针对问题 3,我们只能优化电路设置,尽量避免, 比如加屏蔽罩,加ESD保护,加TVS保护,电源加电容退 耦等等。 针对问题 4,如果系统真的具有很大的感性负载,那 么请注意加续流二极管、滤波电容等做保护,不要让这 种反向高压产生,无论如何,这 种因为感性负载突然断电自激产生的高压,不仅仅会对 EEPROM 有影响,而是对整个系统都存在威胁。 ================================================= ================================================= ============ 经过上面硬件上的一些处理,虽然 EEPROM 数据丢 失的可能已经很小了,但是我们仍然不能保证 EEPROM 数 据就不会丢失了。这时 EEPROM 数据的可*性,那就得从 软件上去考虑了,接着我们从 软件的方面继续讨论。 我的做法是,数据分块,分区,校验,备份。当然 这里讲的处理方法,仅仅是提供一种想法,你可以做不 同数据长度的分块,不同大小的 分区,采用不同的地址映射方法,以及采用更多次的数 据备份。下面以 Mega168 为例继续讨论。 1.Mega168EEPROM512 字节,把EEPROM 分为两个区,每个 区256个字节,然后以8个字节为一个段,那么每个区就 有 32 段。 数据区:0 x000-0 x0FF 0 段:0 x000-0 x007 1 段:0 x008-0 x00F 31 段:0 x0F8-0 x0FF 备份区:0 x100-0 x1FF 每个段 8 个字节,其中前 6 个字节为有效数据,后 个字节为 CRC16 校验,数据格式下图所示: 2 2.EEPROM 读写操作 EEPROM 的操作以段为单位, 段写入函数:写数据到数据区时,先计算数据 CRC16 校验,然后同时把数据写入到数据区和备份区; 段读取函数:读取数据时,同时读取数据区以及备 份区,如果数据区校验有误,备份区数据校验正确,就 用备份区数据恢复数据区数据; 如果备份区数据有误,数据区数据正确,那么数据 写入备份区重新备份;如果数据区备份区数据都有误, 那么返回读取失败。 3.数据区与备份区的对应关系 数据读写操作以段进行,内部的数据区与备份区怎 么映射呢?为了防治数据与备份同时被意外修改,那么 数据与备份地址空间相隔不能太 近,并且数据与备份的地址,应该尽量不同。假设数据 地址为 Data_Addr,备份地址为 Bakup_Addr,我使用下 面的函数映射地址: Bakup_Addr=(Data_Addr+0 x100)^0 x03F 加0 x100是把地址定义到备份区,与0 x03F异或,是 把低 6bits 取反,这样处理,数据与备份的地址空间较 远,并且地址有 7bits 的不同。 例如,第 3 段的地址:0 x018-0 x01F, 对应的备份区为:0 x127-0 x120 如下图所示: 4.读写函数加入写保护判断,在读写 EEPROM 前关闭 写保护,读写完毕后,立即开启写保护,这样可以有效 防止程序跑飞造成的 EEPROM 意外修改 。 5.第 0 块建议禁止使用。