标题: 单片机EEPROM的读写之间要不要延时一段时间 [打印本页]

作者: PDDDF    时间: 2019-12-17 15:09
标题: 单片机EEPROM的读写之间要不要延时一段时间
最近写一个需要保存参数的程序,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读写过程可以分享分享,虚心请教,谢谢

作者: man1234567    时间: 2019-12-17 16:38
根据手册来,除非手册印错了
作者: pcbboy    时间: 2019-12-17 17:23
你这个程序不完整看不了,按我的经验不会出现数据丢失问题。
作者: wulin    时间: 2019-12-17 17:26
因为EEPROM有擦写寿命的,所以不太适合用于频繁适时擦写。通常是把需要保存的数据放在缓存中,掉电时才写入EEPROM保存,再次上电时读取保存的数据。
STC单片机写EEPROM是按扇区为单位,每个扇区512字节,写之前要将整个扇区擦除,写一个字节也得如此。
为了保证写入的数据准确无误可以每写完一个地址的数据,立即读取该地址的数据,并与写数据比较判断是否正确。如正确续写下一个地址的数据,直至全部数据写完。如果中途发现错误可以将整个扇区擦除从头开始重写。STC官方示例:



作者: PDDDF    时间: 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;
                   }
           }
作者: PDDDF    时间: 2019-12-18 09:34
测试的时候需要模拟一般使用情况时使用者对参数进行修改的场景,所以我就想把它做到某些情况下面对快速的读写操作仍然可以保证数据的准确性
作者: muzhi    时间: 2019-12-19 19:17
前一阵在坛子里逛看见前辈讨论这个,24C02一页的大小是8,所以写入的时候每到8的倍数的时候要等5ms换页 写的时候要注意下,读的时候可以一次性读,换page写的时候要等5ms




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1