经常有人在QQ群讨论有关E2PROM操作、保护、失效等一些问题,今天闲来没事,简单概括总结一下咯。(才疏学浅,路过的英雄记得补刀)
1)有关 芯片内部自带的E2PROM
有的资深的工程师可能不是很愿意用MCU自带的E2PROM,大概是这些家伙上过什么当、受过骗还是什么的。简单说一下优缺点吧:
(1)片内集成的感觉挺便宜的,和MCU一起卖的,对成本要求严格的,写次数很少的场合一般会考虑,至少能省个2、3毛钱吧;
(2)缺点的话,可能擦写次数、稳定性没有外挂的专用芯片厉害;
2)有关常用的外挂E2PROM
如果是学生或者刚从学生时代走来的人们,大概也就知道ATMEL 24C0X系列吧,就好像我毕业的时候以为世界只有51和AVR,开个玩笑!
工程师主要考察E2PROM的参数无非就是擦写次数、功耗、稳定性、价格,其中10万次擦写次数和 100万次擦写次数正在较量,至于从工程师的角度考虑 擦写次数自然是没有上限最好,太低的擦写次数会让程序员死很多脑细胞。
3)有关E2PROM的数据管理
(1)操作注意事项:分页操作需要有5ms延迟等待时间才可以(以类AT24C04的产品为例),也就是模块化程序设计中,在写数据之前、写数据完毕后、度数据之前、读数据之后都需要考虑加5ms的延时时间。本来IIC的读写速率就不是很高,外加这些延迟一定会势必影响系统设计的实时性,但也不得不从读写性能的角度出发。
(2)上拉电阻的选择:出于稳定性考虑,WP、SDA、SCL引脚都会设置上拉电阻,常用的电阻值为 4.7K 、10K电阻,个人比较推荐4.7K。
(3)硬件IIC与软件模拟IIC的比较:对MCU资源不是很敏感的应用,都会考虑软件模拟的方式,毕竟这个移植起来真的很方便,只有第一做软件部分的时序、保护性设计作为足够好,后面拿过来修改时钟就可以直接,确实方便。
(4)默认参数的写入:设置新E2PROM的时间戳标志,每次系统启动时检查这个时间戳和MCU自身存储的时间戳是否一致,不一致则初始化整个E2PROM为默认参数;当然软件程序的升级,这个时间戳表示也有必要做更改。
(5)数据容错和管理:
把数据以有意义的数据块作分类管理,在数据的块的头、位加固定标识和CS/CRC校验 模式,格式如
数据块开始字 | 数据长度 | 数据 | 校验 | 结束 |
0xA5 | Length | Byte0---ByteN | CS/CRC | 0x5A |
实际用于产品中,可以挑选这个格式内容里面的部分内容使用,比如去掉结束符等。
个人之所以建立写入开始字、结束字,原因是方便最好读出来的数据做数据格式检查,确认写入、读出的数据可靠性最高。
为增强实际的可靠性,在需要写入的时候,可以在写入后,再读出来进行数据的比对,确认写入是否正确;或者在需要读出的时候,读两次、或者多次,检查每次的数据是否一致。
对于出现异常的数据,最好有容错机制,可以回到默认状态值,不至于系统此时因为某个参数改变的崩溃。
(6)实际底层操作是否需要关闭主程序的中断:一般按照上述(5)操作,有多次冗余操作设计,可以不关闭主程序中断。而且,IIC为等待型操作,一般不会因为系统延迟导致时钟脉宽拉长,影响字节写入、读出。
(7)E2PROM擦写次数的延长: 如果现在手上的E2PROM的擦鞋次数是10万次,项目要求为100万次,且E2PROM内有很多空闲字节的没有使用。
可以这样操作,将数据整理好,以数据块的方式存储,一组数据分10个块地址存储,每次写完后转移到下一块写,即10次写操作中每个物理的数据存储地址只操作了1次。 注意此时的写块数据的指针不能单独存、操作,不然这个字节的操作频率高,也就受到10万次的限制,这个关键的链子在10万次的时候掉了,其他字节也就挂了。这个表征操作哪个块的指针或者说标示符,当然也需要是移动的,至于具体怎么实现,就是见仁见智的事了。
转自:http://blog.chinaunix.net/uid-20589269-id-1622153.html
最近用Mega16做一个步进电机的项目,以后把项目全部的内容贴上来跟大家分享呵呵,现在讨论一个防止EEPROM读写出错的小办法,我编写熔丝位是用AVRstudio里面的Jtag下载功能来烧熔丝位的,连上Jtag,AVRstudio的Jtag功能fuse选项里,把熔丝位中的Preserve EEPROM memory through the Chip Erase cycle钩上,Brown-out detection level at VCC=4.0V钩上,Brown-out detection enabled钩上,就可以解决读写EEPROM时出错的机会了。
如果再加上用直接地址访问法,而不用变量定义法,会更好的避免EEPROM读写问题,例如我就定义了
//定义eeprom变量的地址
#define eeprom_step_num 0xA0
#define eeprom_step_r_max 0xB0
#define eeprom_step_l_max 0xC0
然后程序就没有再跑飞了!^_^
在其它论坛上还有一些讨论EEPROM读写错误的贴,我节选了一些,留作参考:
EEPROM掉电丢数据这个特点可不是AVR独有的。很多年前在89C51+24C02的系统里面就遇到过,我不知道铁电有什么比24C02更牛的地方,居然能保证不丢数据。原因很简单,就是掉电过程中,电压降低到MCU无法正常工作的程度,程序跑飞了,单片机引脚状态完全不可控,某次掉电就可能发出错误的写24C02的指令。上电的时候因为RESET处于有效状态,MCU引脚状态完全确定(对于51来说就是全1),是不可能误操作24C02的。解决方案很简单,加一片MAX813L,当电压低于4.6V就锁定89C51,问题彻底解决。这么多年也没见24C02被误改写。
最早的一批AVR内置了EEPROM却没有BOD,所以EEPROM被误改写是家常便饭,ATMEL很快发现了这个问题,新推出的AVR全都含有BOD乐。AVR的情况比较复杂,振荡方式和复位方式都有多种,所以不仅掉电会改写EEPROM(原因同上),上电也会!RESET过程结束前,必须有若干XTAL,MCU内部寄存器(包括软件不可见的)才会清零,如果RESET结束了才来时钟,上电就是程序乱飞,同样有可能改写EEPROM。用RC振荡方式问题不大,有电就能振起来,用石英晶体就会出问题,我测过89C51的,上电后20ms才振起来,如果电源上有大的滤波电容,VCC的上升斜率变小,晶体起振时间会变得更长!有存储示波器的朋友可以自己测一下,对晶振的起振有个感性认识。
我遇到过的问题,m8里面有写eeprom的程序段,数据已经写入到eeprom了。
不停的开关电,eeprom里的值有可能随机改变,不见得是0x00,0xFF
原因是不是上电时,程序指针跑飞到写eeprom那段,导致往eeprom随机地址写了随机数。
后来,采用isp下载2次程序,最后版本的程序是删除了写eeprom程序段,保留读eeprom段。
这样的话,开关电很多次,里面的eeprom没见有改动。
如果系统实际运行时,需要对eeprom写操作,可考虑存多几次数据,用校验方法来处理数据改变。
偶的应用一般要用到EEPROM存储的数据比较少,一般采取反码冗余备份校验的方式,需要存储的数据按照原码和反码存两份,需要读取时分别读取原码和反码,进行校验,若校验不通过,则根据一定的算法恢复数据或者采取缺省值.
我遇到过的问题,m8里面有写eeprom的程序段,数据已经写入到eeprom了。
不停的开关电,eeprom里的值有可能随机改变,不见得是0x00,0xFF
我也是一样BOD使能 就OK了 不过我还是不放心,我用两份数据,最后加校验,启动的时候读eeprom数据 如果有异常 检测出错误数据组,然后用正确的恢复。如果两组数据均遭毒手,用flash里面的默认数据覆盖。
一般我在eeprom里间三分拷贝,位置隔的比较远
以下是马潮老师的解决办法:
作为一个正式的系统或产品,当系统基本功能调试完成后,一旦进行现场测试阶段,请注意马上改写熔丝位的配置,启用AVR的电源检测(BOD)功能。
对于5V系统,设置BOD电平为4.0V;对于3V系统,设置BOD电平为2.7V。然后允许BOD检测。
这样,一旦AVR的供电电压低于BOD电平,AVR进入RESET(不执行程序了)。而当电源恢复到BOD电平以上,AVR才正式开始从头执行程序。保证了系统的可靠性!
原因分析如下:
AVR是宽电压工作的芯片,当电压跌至2.5V,系统程序还能工作。这是有2个可怕的现象可能出现,
1。外围芯片工作已经混乱,AVR读到的东西不正确,造成程序的执行发生逻辑错误(不是AVR本身的原因)。
2。当电源低到临界点,如2.4V时,并且在此互上互下的,AVR本身的程序执行也不正常,取指令、读数据都可能发生错误,或程序乱飞、不稳定(AVR本身的原因,实际任何的单片机都是这样的),非常容易造成EEPROM、FALSH的破坏。有人问51怎么不会?实际上51也是这样,只是51内部没有直接写EEPROM、FLASH的指令,它的程序乱飞留不下痕迹。还有人有疑问:外挂EEPROM,掉电时怎么不会改写?实际是外挂EEPROM,当电压低于4V(2.7V)时,它已经不工作了,程序去改内容也改不了。而AVR内部的东西在临界电压时都能工作,但非常不稳定。
AVR的BOD功能必须要使用,我早期使用51时,凡是产品外部都要使用电源监测芯片,现在AVR自己本身就有该功能,一定要使用。
上一篇:I2C通信 读写数据过程
下一篇:EEPROM读写操作常见的陷阱
推荐阅读最新更新时间:2024-03-16 16:09