搜索
bottom↓
回复: 50

给大家一个算法,用于AVR片内EEPROM比较可靠,俺的产品就是这样用的

[复制链接]

出0入0汤圆

发表于 2008-9-5 09:38:46 | 显示全部楼层 |阅读模式
/*储存字符数*/
void SaveCrcUchar(uint addr,uchar data)
{
    uchar crc ;
         
    crc=CrcUchar(data);
    SaveUchar(addr,data);
    SaveUchar(addr+1,crc);
    delay(10);
         
    SaveUchar(addr+2,data);
    SaveUchar(addr+3,crc);
    delay(10);
         
    SaveUchar(addr+4,data);
    SaveUchar(addr+5,crc);
}

/*读取字符数*/
uchar LoadCrcUchar(uint addr)
{
    uchar a ;
    uchar b ;
         
    a=ReadUchar(addr);
    b=ReadUchar(addr+1);
    if(CrcUchar(a)==b)return a ;
         
    a=ReadUchar(addr+2);
    b=ReadUchar(addr+3);
    if(CrcUchar(a)==b)return a ;
         
    a=ReadUchar(addr+4);
    b=ReadUchar(addr+5);
    if(CrcUchar(a)==b)return a ;
         
    CrcErr=1 ;
    return 99 ;
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2008-9-5 09:40:10 | 显示全部楼层
//延时
void delay(uint temp)
{
    while(--temp);
}

/*储存字符数*/
void SaveUchar(uint addr,uchar c)
{
    EEPROMwrite(addr,c);
}

/*读取字符数*/
uchar ReadUchar(uint addr)
{
    return EEPROMread(addr);
}

uchar CrcUchar(uchar l)
{
    return 0xab^l ;
}

出0入0汤圆

发表于 2008-9-5 09:50:51 | 显示全部楼层
不是外挂的一般不会写错吧。如果写错了,你得校验会不会写到别的地方去,影响其他地址的数据。

出0入0汤圆

 楼主| 发表于 2008-9-5 09:55:29 | 显示全部楼层
1、片内的EEPROM写有次数限制;
2、如果电压过低,会出现写错误,导致读出也错误;

利用该算法,可以确保读出的数据正常。

出0入0汤圆

发表于 2008-9-5 09:59:49 | 显示全部楼层
 mark 一下 不错值得借鉴 

出0入22汤圆

发表于 2008-9-5 10:05:49 | 显示全部楼层
谢谢。

出0入0汤圆

发表于 2008-9-5 10:05:58 | 显示全部楼层
重复写就可以保证是对的?

出0入0汤圆

 楼主| 发表于 2008-9-5 10:09:07 | 显示全部楼层
重复写3次,只要有1次写成功,就能保证读出数据正常

出0入42汤圆

发表于 2008-9-5 10:23:58 | 显示全部楼层
程序只做了备份,没有做数据恢复,期待楼主完善一下

出0入0汤圆

发表于 2008-9-5 10:27:29 | 显示全部楼层
是个好主意,但治标不治本呐.

出0入0汤圆

发表于 2008-9-5 10:27:55 | 显示全部楼层
3次备份,1次对就可以。好主意。
3次都坏的概率小。

出0入0汤圆

 楼主| 发表于 2008-9-5 10:32:11 | 显示全部楼层
采用该算法还有一个好处:
    产品烧写程序后希望某些变量有一个初始值(而这些变量断电后又要保存),那么可以这样处理:读取该变量在EEPROM中的数据,如发现读取校验错误(首次烧写程序后,第一次读取肯定校验错误),则对变量初始化一次,然后保存。这样的话,产品烧写程序后就有一个初始值了。
    eg:

//初始化数据
void ini_data(void)
{
            CrcErr=0;
               
        SetFlashTime=LoadCrcUchar(eeprom_SetFlashTime);
               
        if (CrcErr)//错误处理,出现校验错误时,采用以下值作为默认参数。
        {
            SetFlashTime=30;  //闪烁次数:
               SaveCrcUchar(eeprom_SetFlashTime,SetFlashTime);
        }
}

出0入0汤圆

发表于 2008-9-5 10:33:46 | 显示全部楼层
假如第一次写的数据出错或者被误修改,而CRC是正确的,读出来不一样是错误的么?
LZ把3次放在连续的空间里,一旦误操作可能3次保存的数据都坏掉了,仍然无法取得正确数据

想牢靠点,把三次数据分开保存,读取的时候3取2,如果加CRC的话,在读取数据出来后再次CEC校验一次,确保数据的正确性

出0入0汤圆

发表于 2008-9-5 10:36:23 | 显示全部楼层

出0入0汤圆

 楼主| 发表于 2008-9-5 10:40:04 | 显示全部楼层
bluerain 网络棋侠:假如第一次写的数据出错或者被误修改,而CRC是正确的,读出来不一样是错误的么?

回答:这种算法只能降低出错机率,不能完全避免,除非采用可靠性更高的校验。

另外,每一次读取数据的时候都会判断CrcErr值,如果CrcErr==1,采用默认值。

出0入46汤圆

发表于 2008-9-5 10:52:24 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-9-5 11:13:24 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-9-5 11:31:33 | 显示全部楼层
不错~记号

出0入42汤圆

发表于 2008-9-5 11:31:46 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-9-5 12:00:38 | 显示全部楼层
记号

出0入0汤圆

发表于 2008-9-5 12:22:05 | 显示全部楼层
飘过

出0入0汤圆

发表于 2008-9-5 12:28:31 | 显示全部楼层
学习...

出0入0汤圆

发表于 2008-9-5 12:30:34 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-9-5 12:41:44 | 显示全部楼层
dd

出0入0汤圆

发表于 2008-9-5 13:10:52 | 显示全部楼层
这样会很占空间的

出0入0汤圆

发表于 2009-4-24 17:05:43 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-4-24 19:52:12 | 显示全部楼层
没这样用过   想法不错

出0入0汤圆

发表于 2009-4-24 19:58:49 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-4-24 20:19:15 | 显示全部楼层
MARK!谢谢共享!

出0入0汤圆

发表于 2009-6-12 10:34:01 | 显示全部楼层
不错,学习了,LZ好人

出0入0汤圆

发表于 2009-6-12 10:43:55 | 显示全部楼层
哈哈,eeprom采用三取二,搞三个备份。

  (1)、我经常操作EEPROM,其中EEPROM中保存的参数经常有100个,三个备份,太占用RAM空间了。RAM需要600字节,保存有一个备份,用于比较。同时还需要200字节,保存100个参数,因此共计800字节。

  (2)、我经常两个串口同时使用,其中一个RS232,另外一个RS485,协议为MODBUS,又要占用500字节。

 

出0入0汤圆

发表于 2009-6-12 10:56:37 | 显示全部楼层
学习中。。。。

出0入0汤圆

发表于 2009-6-12 12:47:02 | 显示全部楼层
记号

出0入0汤圆

发表于 2009-6-12 17:43:39 | 显示全部楼层
MARK

出675入8汤圆

发表于 2009-6-12 19:37:46 | 显示全部楼层
mark

出0入4汤圆

发表于 2009-6-12 22:48:52 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-7-9 11:27:58 | 显示全部楼层

出0入0汤圆

发表于 2009-7-10 14:34:01 | 显示全部楼层
学习

出0入0汤圆

发表于 2009-12-25 09:09:13 | 显示全部楼层
回复【楼主位】jiangjx
-----------------------------------------------------------------------

记号!谢谢楼主!

出0入0汤圆

发表于 2009-12-25 09:47:21 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-12-25 09:50:16 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-12-25 12:32:16 | 显示全部楼层
学习

出0入0汤圆

发表于 2009-12-25 13:02:29 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-25 14:20:12 | 显示全部楼层
我采取的措施是,CRC-CCITT校验,为防止首次使用时EEPROM是全0时
校验也是0不能识别是否被初始化,外加一个固定为0x55的字节.写
入的时候先写入再读出比较是否一直,读取的时候校验CRC是否正确.

出0入0汤圆

发表于 2009-12-25 14:35:45 | 显示全部楼层
不错。
三个地址备份好。

出0入0汤圆

发表于 2009-12-25 18:40:30 | 显示全部楼层
学习学习,

出0入0汤圆

发表于 2009-12-25 20:15:04 | 显示全部楼层
学习

出0入0汤圆

发表于 2009-12-25 20:24:51 | 显示全部楼层
记号

出0入0汤圆

发表于 2009-12-25 20:27:49 | 显示全部楼层
mark

出0入0汤圆

发表于 2014-9-29 09:08:50 | 显示全部楼层
学习了,现在正需要

出0入0汤圆

发表于 2014-9-30 15:49:28 | 显示全部楼层
学习了   
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 09:15

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表