找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6119|回复: 6
收起左侧

单片机EEPROM的读写之间要不要延时一段时间

[复制链接]
ID:601478 发表于 2019-12-17 15:09 | 显示全部楼层 |阅读模式
最近写一个需要保存参数的程序,IC用STC15W408AS,10个扇区都用到了,实测时经常出现数据丢失的现象,请问有没有什么办法可以保证数据的准确性
void key_handle()
{
        uchar t,e1,e2,limit;
        e1 = dcx(0x0020);
        e2 = dcx(0x0220);
         while(1)
         {
                 if(KEY_1 == 0)
                 {
                         Delay(2);
                         if(KEY_1 == 0)
                         {
                                 while(KEY_1 == 0);
                                 if(limit<++e1) e1 = 0;
                         }                         
                 }
                 
                 if(KEY_2 == 0)
                 {
                         Delay(2);
                         if(KEY_2 == 0)
                         {
                                 while(KEY_2 == 0);
                                 if(limit<--e1) e1 = limit;
                         }
                 }
                 display1(e1);
         }


uchar dcx(uint addr)
{
  uchar dat;
        IAP_CONTR = ENABLE_IAP;
        IAP_CMD = CMD_READ;
        IAP_ADDRL = addr;
        IAP_ADDRH = addr >> 8;
        IAP_TRIG = 0x5a;
        IAP_TRIG = 0xa5;
        _nop_();
        _nop_();
        dat = IAP_DATA;
        Q0();
       
        return dat;
}

void cc(uint addr)
{
  IAP_CONTR = ENABLE_IAP;
        IAP_CMD = CMD_ERASE;
        IAP_ADDRL = addr;
        IAP_ADDRH = addr>>8;
        IAP_TRIG = 0x5a;
        IAP_TRIG = 0xa5;
        _nop_();
        _nop_();
        Q0();
}

void xcx(uint addr,uchar dat)
{
  IAP_CONTR = ENABLE_IAP;
        IAP_CMD = CMD_PROGRAM;
        IAP_ADDRL = addr;
        IAP_ADDRH = addr>>8;
        IAP_DATA = dat;
        IAP_TRIG = 0x5a;
        IAP_TRIG = 0xa5;
        _nop_();
        _nop_();
        Q0();
}

void Q0()
{
  IAP_CONTR = 0;
        IAP_CMD = 0;
        IAP_TRIG = 0;
        IAP_ADDRH = 0x80;
        IAP_ADDRL = 0;
}


大概就是按键设置参数然后保存这样,连续对多个参数进行调整后保存会出现数据丢失或者数据错误 的情况,网上说在每次写入后都校验一次,不过在实际使用中不同参数的读写保存之间的操作间隔非常小,11.059的晶振不知道能不能在这样极短的间隔内跑完这一系列的语句,不知道大佬们有没有什么好的EEPROM读写过程可以分享分享,虚心请教,谢谢
回复

使用道具 举报

ID:584814 发表于 2019-12-17 16:38 | 显示全部楼层
根据手册来,除非手册印错了
回复

使用道具 举报

ID:25310 发表于 2019-12-17 17:23 | 显示全部楼层
你这个程序不完整看不了,按我的经验不会出现数据丢失问题。
回复

使用道具 举报

ID:213173 发表于 2019-12-17 17:26 | 显示全部楼层
因为EEPROM有擦写寿命的,所以不太适合用于频繁适时擦写。通常是把需要保存的数据放在缓存中,掉电时才写入EEPROM保存,再次上电时读取保存的数据。
STC单片机写EEPROM是按扇区为单位,每个扇区512字节,写之前要将整个扇区擦除,写一个字节也得如此。
为了保证写入的数据准确无误可以每写完一个地址的数据,立即读取该地址的数据,并与写数据比较判断是否正确。如正确续写下一个地址的数据,直至全部数据写完。如果中途发现错误可以将整个扇区擦除从头开始重写。STC官方示例: 无标题.jpg


回复

使用道具 举报

ID:601478 发表于 2019-12-18 09:27 | 显示全部楼层
pcbboy 发表于 2019-12-17 17:23
你这个程序不完整看不了,按我的经验不会出现数据丢失问题。

我补充一下吧,就是多了个保存数据和菜单循环共用的按键,按下执行把改变后得值存回原地址,这样而已
补充:把这个if判断放到while(1)里
if(KEY_SET == 0)
           {
                   Delay(2);
                   if(KEY_SET == 0)
                   {
                     while(KEY_SET == 0);
                     if(19<++q) q = 0;
                     cc(0x0020 & 0x0220);
                     if(IAP_CONTR == 0) xcx(0x0020,e1);
                     if(IAP_CONTR == 0) xcx(0x0220,e2);
                     return;
                   }
           }
回复

使用道具 举报

ID:601478 发表于 2019-12-18 09:34 | 显示全部楼层
测试的时候需要模拟一般使用情况时使用者对参数进行修改的场景,所以我就想把它做到某些情况下面对快速的读写操作仍然可以保证数据的准确性
回复

使用道具 举报

ID:342911 发表于 2019-12-19 19:17 | 显示全部楼层
前一阵在坛子里逛看见前辈讨论这个,24C02一页的大小是8,所以写入的时候每到8的倍数的时候要等5ms换页 写的时候要注意下,读的时候可以一次性读,换page写的时候要等5ms
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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