AVR EEPROM 可靠性问题的研究总结,以及可靠使用的终极解决方案--提供Mega168源代码。
其实论坛上讨论 AVR 内部 EEPROM 可靠性,以及如何合理使用内部 EEPROM 的帖子已经很多了,写这个帖子之前,还特意搜索了一下,EEPROM相关的主题贴一共有6页之多,酷贴达5个之多,没有看完,只选择性的看了一些,然后主要把注意力放在了两个与可靠性相关的,“穿
着裤子”的贴上,又仔细的读了一遍,在这些的基础上,我做一个总结吧,希望能终结 内部 EEPROM 可靠性问题的讨论。当然该贴只是针对其
可靠性问题,掉电存 EEPROM 的问题,以及存 EEPROM 速度的问题,不在该文的讨论范围之列。
针对 AVR EEPROM 的可靠性问题,以前使用 Mega88 做过专门的测试,测试数据结果直接发_论坛上了,没有做文档,这个测试结果好像找
不到了,应该是回复在下面这两个帖子其中之一的后面,网站被黑,可能回复没有恢复全。这两个帖子也是我主要参考得两个帖子。
讨论:eeprom的可靠性研究myppfish
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=672954&bbs_page_no=1&search_mode=1&search_text=EEPROM&bbs_id=1000
原创]治标治本,彻底解决AVR单片机EEPROM数据丢失问题 my_avr
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=1440595&bbs_page_no=1&search_mode=1&search_text=EEPROM&bbs_id=1000
测试的结论是 AVR 内部 EEPROM 是可靠的,如果有问题,也是所有 EEPROM 的通病。当然由于测试手段有限,该结论可能存在片面性,如
果哪位愿意继续深入测试,并且否定了这个结论,还请不吝赐教,谢谢。AVR 内部 EEPROM 可靠归可靠,但是如果使用不当,确也很容易出错
,所以搞得少数人以为 AVR 内部 EEPROM 不稳定。
首先,总结一下引起 AVR 内部 EEPROM 数据丢失的原因:
1. 程序问题;
2. 程序跑飞;
3. EEPROM相关寄存器因强磁场、高压静电等外部干扰出错所产生的写入动作;
4. 系统有很大的感性负载,在断电的时候会产生一个反向高压,EEPROM有可能会自擦除。
……(还有什么原因,欢迎大家继续列举,以便完善及想办法解决)
针对问题1,程序问题不再该文讨论范围内。
针对问题2,程序跑飞,这个因该是引起 EEPROM 数据丢失的主要原因。但是引起程序跑飞的原因却是多方面的。
第一. 电压不正常,工作不稳定,程序跑飞。针对这个问题,可以开启内部BOD、或者外加复位芯片解决,在低功耗场合,外部复位是有必
要的,毕竟BOD功耗太高。
第二,晶体振荡受干扰,频率不稳定,程序跑飞。针对这个问题,建议晶体使用全幅振荡,并且走线的时候尽量短,并且使用地线隔离。
第三系统受外界环境干扰,修改了PC等寄存器,程序跑飞。针对这个干扰问题,这个引起程序跑飞的可能性应该不大,如果环境实在恶劣
,那么就应该想到做电磁屏蔽,ESD保护等,如果还不行,那么只能建议换换别的单片机试试看了。
针对问题3,我们只能优化电路设置,尽量避免,比如加屏蔽罩,加ESD保护,加TVS保护,电源加电容退耦等等。
针对问题4, 如果系统真的具有很大的感性负载,那么请注意加续流二极管、滤波电容等做保护,不要让这种反向高压产生,无论如何,这
种因为感性负载突然断电自激产生的高压,不仅仅会对EEPROM有影响,而是对整个系统都存在威胁。
好了,说了这么多,设计也都按照上面的做了,EEPROM 就可以100%没有问题了?不是的,经过上面硬件上的一些处理,虽然EEPROM数据丢
失的可能已经很小了,但是我们仍然不能保证EEPROM数据就不会丢失了。这时 EEPROM 数据的可靠性,那就得从软件上去考虑了,接着我们从
软件的方面继续讨论。
我的做法是,数据分块,分区,校验,备份。当然这里讲的处理方法,仅仅是提供一种想法,你可以做不同数据长度的分块,不同大小的
分区,采用不同的地址映射方法,以及采用更多次的数据备份。下面以 Mega168 为例继续讨论。
1. Mega168 EEPROM 512字节,把EEPROM分为两个区,每个区256个字节,然后以8个字节为一个段,那么每个区就有32段。
数据区:0x000 - 0x0FF
0段:0x000 - 0x007
1段:0x008 - 0x00F
……
31段:0x0F8 - 0x0FF
备份区:0x100-0x1FF
每个段8个字节,其中前6个字节为有效数据,后2个字节为CRC16校验,数据格式下图所示:
http://cache.amobbs.com/bbs_upload782111/files_14/ourdev_438344.JPG
(原文件名:数据分区.JPG)
2. EEPROM读写操作
EEPROM的操作以段为单位,
段写入函数:写数据到数据区时,先计算数据CRC16校验,然后同时把数据写入到数据区和备份区;
段读取函数:读取数据时,同时读取数据区以及备份区,如果数据区校验有误,备份区数据校验正确,就用备份区数据恢复数据区数据;
如果备份区数据有误,数据区数据正确,那么数据写入备份区重新备份;如果数据区备份区数据都有误,那么返回读取失败。
3. 数据区与备份区的对应关系
数据读写操作以段进行,内部的数据区与备份区怎么映射呢?为了防治数据与备份同时被意外修改,那么数据与备份地址空间相隔不能太
近,并且数据与备份的地址,应该尽量不同。假设数据地址为 Data_Addr,备份地址为 Bakup_Addr,我使用下面的函数映射地址:
Bakup_Addr = ( Data_Addr + 0x100 ) ^ 0x03F
加0x100是把地址定义到备份区, 与0x03F异或,是把低6bits取反,这样处理,数据与备份的地址空间较远,并且地址有7bits的不同。
例如,第 3 段 的地址: 0x018 - 0x01F,
对应的备份区为:0x127 - 0x120
如下图所示:
http://cache.amobbs.com/bbs_upload782111/files_14/ourdev_438343.JPG
(原文件名:地址映射.JPG)
4. 读写函数加入写保护判断,在读写EEPROM前关闭写保护,读写完毕后,立即开启写保护,这样可以有效防止程序跑飞造成的EEPROM意外修改
。
5. 第0块建议禁止使用。
以下是Mega168 的 EEPROM C语言库函数(汇编比较晦涩,就不上了),另外送上 CRC16 CRC32 校验的函数,以及 Mega168 UART0 通信函
数库,以便于测试。编译环境 Studio + WinAVR 。
点击此处下载 ourdev_438338.rar(文件大小:53K) (原文件名:EEPROM Test.rar)
程序仿真结果:
1. 利用 MKII 仿真,EEPROM 数据被擦除后,全为0xFF
http://cache.amobbs.com/bbs_upload782111/files_14/ourdev_438339.JPG
(原文件名:01 EEPROM 擦除.JPG)
2. 发送写第一块命令
http://cache.amobbs.com/bbs_upload782111/files_14/ourdev_438340.JPG
(原文件名:02 写01块.JPG)
3. Break暂停仿真,查看 EEPROM 数据:
http://cache.amobbs.com/bbs_upload782111/files_14/ourdev_438341.JPG
(原文件名:03 仿真结果.JPG)
4. 发送 C1 00 命令,读取的一块数据:
http://cache.amobbs.com/bbs_upload782111/files_14/ourdev_438342.JPG
(原文件名:04 读01块.JPG)
----------------------------------------------------------
修改原因:有点长,大家可能没有注意到混迹其中的源代码附件,修改了下标题,吸引眼球。 强贴沙发! 搞了一个晚上,自己坐个板凳,看碟去了…… 顶。 不知道拿AVR 的FLASH当EEPROM使用,会不会比直接用EEPROM更稳定??
(FLASH被改的可能性应该更小) 4楼在开玩笑么?只有BootLoader区可以修改Flash,并且都是整页地修改。用Flash当EEPROM,Freescale中是这样用的,但是AVR这样坐,感觉就是在玩火。 ATMEL有一篇AN介绍把FLASH当作EEPROM用的,个人认为太复杂了。 学习了 【6楼】 my_avr
ATMEL有一篇AN介绍把FLASH当作EEPROM用的,个人认为太复杂了。
在哪里?能否给个链接? 【8楼】 void_c void *c‘
有么有详细的代码,可以参考呀 【楼主位】 windy__xp
-------------------------------------
本以为楼主的摄影强,想不到技术也这么厉害!!! 段读取函数:读取数据时,同时读取数据区以及备份区,如果数据区校验有误,备份区数据校验正确,就用备份区数据恢复数据区数据;
如果备份区数据有误,数据区数据正确,那么数据写入备份区重新备份;如果数据区备份区数据都有误,那么返回读取失败。
--------------------------------------------------------------------------------------------------------------------
想问下楼主,读取数据时, 是先把数据区和备份区的数据作对比,还是把数据区的数据和数据区的CRC16校验作比较? 留给记号先 【6楼】 my_avr
积分:1210
派别:
等级:------
来自:武汉
ATMEL有一篇AN介绍把FLASH当作EEPROM用的,个人认为太复杂了。
---------------------------------------------------------------
看论坛中的帖子,有的总说Flash中的程序掉了,其实这个掉程序的原因与EEPROM丢数据的原因有相似的地方,就是程序跑飞到BL区,执行了SPM指令,修改了Flash数据。所以用Flash当EEPROM用,同样有丢数据的可能,另外,如果把写Flash的程序放在BL区,那么BootLoader功能实现就有些麻烦了。总之,个人不建议使用Flash当EEPROM用。
【10楼】 yangyongwen
积分:416
派别:
等级:------
来自:广东
本以为楼主的摄影强,想不到技术也这么厉害!!!
__________________________
摄影只是玩玩,不过专业技术还得继续学习——学无止境嘛。
【11楼】 yangyongwen
积分:416
派别:
等级:------
来自:广东
段读取函数:读取数据时,同时读取数据区以及备份区,如果数据区校验有误,备份区数据校验正确,就用备份区数据恢复数据区数据;
如果备份区数据有误,数据区数据正确,那么数据写入备份区重新备份;如果数据区备份区数据都有误,那么返回读取失败。
--------------------------------------------------------------------------------------------------------------------
想问下楼主,读取数据时, 是先把数据区和备份区的数据作对比,还是把数据区的数据和数据区的CRC16校验作比较?
-----------------------------------------------------------------------------------------
附件中的源代码,有详细注释,应该不难读懂。目前的做法是不比较数据区和经备份区的数据,而是直接CRC16校验,以此判断数据是否正确。 lz的串口调试助手不错,能否共享一下! mark
回头把毕业设计中的EEP给改高级点 【14楼】 1181zjf
积分:638
派别:
等级:------
来自:
lz的串口调试助手不错,能否共享一下!
---------------------------------------------------------
这个软件的确好用,但是有个BUG,就是开启过后,系统的复制、粘贴功能就不能用了。上两个常用的串口调试软件。
点击此处下载 ourdev_438503.rar(文件大小:234K) (原文件名:串口调试助手.rar) mark 支持一个 我采用EEPROM“中断”方式写EEPROM(没有采用查询方式),同时开启BOD,门限电压=4.3V,使用了2年多,从来没有遇到过问题。
1、读EEPROM只是在一上电还未开放全局中断时,一次性把EEPROM中的数据读到RAM中。
2、写EERPOM时,我测试过用上位机每隔20毫秒不停的写,也没有遇到问题。
3、不停的上电、断电,至少测试过1000次,也没有遇到EERPOM丢失问题。
所以,EEPROM中不必划分几个区(有的人搞了备份1,有的人还搞了备份2),我认为没有必要。 用Flash替代EEPROM记录数据可以参考AVR105: Power Efficient High Endurance Parameter Storage in Flash Memory。 ba_wang_mao
积分:839
我采用EEPROM“中断”方式写EEPROM(没有采用查询方式),同时开启BOD,门限电压=4.3V,使用了2年多,从来没有遇到过问题。
1、读EEPROM只是在一上电还未开放全局中断时,一次性把EEPROM中的数据读到RAM中。
2、写EERPOM时,我测试过用上位机每隔20毫秒不停的写,也没有遇到问题。
3、不停的上电、断电,至少测试过1000次,也没有遇到EERPOM丢失问题。
所以,EEPROM中不必划分几个区(有的人搞了备份1,有的人还搞了备份2),我认为没有必要。
------------------------------------------------------------------------
AVR EEPROM数据丢失的原因是多方面的,你的产品没有遇到问题,只能说是你的应用环境也许比较好。另外你所说的测试方法太简单,很多恶劣的环境没有模拟,所以结论下的有些武断。个人觉得目前虽然采用了保护措施,确还不敢说,一定可靠,数据一定不会丢。 幸好我目前还没有碰到很恶劣的环境~~ 我也来说说我怎么做的:
数据分主存和备份,两部分的数据完全相同,每部分的数据由有效数据,校验和及特征码(0xaa,0x55)组成。
读取数据的时候,先读主存,如果校验和和特征码都正确,则读取备份区,如果备份区的 校验和不正确,或者与主存区不一样,或者特征码不正确,就直接用主存区的数据恢复。如果主存区不正确,则读取备份区,检查校验和和特征码,若正确则恢复主存区,不正确就只能恢复到默认值了。
写数据的时候,先写主存区再写备份区,流程都是 :先写特征码为0x00,0x00,然后写有效数据和 校验码,最后写特征码为0xaa,0x55
特征码有什么作用?举个例子:不使用特征码时,某个时刻EEPROM中存储的数据为0x10,0x20,0x30,0x60,(第4个字节为校验和,下同),现在数据需要变更为0x20,0x10,0x50,0x80,如果刚写完主存区数据0x10掉电了,最后主存区的数据变成了0x20,0x10,0x30,0x60,而备份区的数据仍然是0x10,0x20,0x30,0x60,主存区的校验和仍然正确,而实际上数据是错误的,再次重新读取数据的时候,将得到错误的数据,并用错误的数据覆盖备份区。
使用特征码,每次写有效数据前,先把特征码写成0x00,0x00,数据写完后才写为0xaa,0x55,这样读取数据时一旦发现特征码不正确,说明数据没正常写入。只要硬件不发生故障,主存区和备份区至少有一个区的特征码是正确的。如果两个区的校验和特征码都正确,但校验和不一样,则说明主存区的数据是最近一次写入的,而备份区的数据是上次写入的,需要用主存区的数据覆盖。
另外,读取数据的时候发现不正确,可以重复读三遍,防止总线受干扰而读到错误的数据,误判断为EEPROM中存储的数据错误。
关键数据一定要有备份区,不然数据写入一半的时候掉电,就只能挂掉了。如果只是一些无关紧要的参数,恢复到默认值就行,但如果是IP地址这样的参数受到破坏,将没法上网了,只能人工去恢复。 mark mark mark mark mark 请问如果电路设计的感性负载大,那么要如何加续流二极管、滤波电容等做保护? 能否画个原理图告诉我要怎么接到atmega128芯片上?请高手指教!! mark 回复【13楼】windy__xp龙笑
【6楼】 my_avr
积分:1210
派别:
等级:------
来自:武汉
atmel有一篇an介绍把flash当作eeprom用的,个人认为太复杂了。
---------------------------------------------------------------
看论坛中的帖子,有的总说flash中的程序掉了,其实这个掉程序的原因与eeprom丢数据的原因有相似的地方,就是程序跑飞到bl区,执行了spm指令,修改了flash数据。所以用flash当eeprom用,同样有丢数据的可能,另外,如果把写flash的程序放在bl区,那么bootloader功能实现就有些麻烦了。总之,个人不建议使用flash当eeprom用。
【10楼】 yangyongwen
积分:416
派别:
等级:------
来自:广东
本以为楼主的摄影强,想不到技术也这么......
-----------------------------------------------------------------------
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3927784&bbs_page_no=1&search_mode=4&search_text=XA144F&bbs_id=9999
这篇帖子介绍的是对M48的操作方法,过程简单,当然这也让我想到了STC单片机的做法……
我用Atmega8515做实验不成功,把程序定位到Bootloader区域,使用熔丝设置都不成功。 不错, 如果eeprom够多的话,我都是每个数据备份个3遍以上,用的时候都读出来,比较是否相等,然后取相等次数最多的数据,再把不相等的重写一遍。 不错
111 频繁写 使用flash当eeprom用,死都不知道怎么死的。 很经典,很有用
这几天被avr的eeprom折腾了
明天试试这个方法 记号!经典有用! 很好的文章,MARK。。 我现在碰到个问题,老板破解了别人的程序,我在抄别人的板,然后写相同的功能.
现在在测试上电时发现我的程序多次上电后偶然EEPROM被,别人的程序不会.
测试方法是做一个测试架供电,上电后0-10秒钟内断电,下次断电时会延时多10ms再断电,如此整死它.上电后程序开始都会读EEPROM,而我用到的EEPROM是08H-120H 好帖,记号! 膜拜大神,墙贴 Mark
页:
[1]