找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3337|回复: 7
打印 上一主题 下一主题
收起左侧

关于STC单片机掉电存储数据的问题,请求各位大佬们支招?

[复制链接]
跳转到指定楼层
楼主
ID:792404 发表于 2022-6-4 15:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近在用STC8G单片机测试掉电存储的实验,就是用秒表计数,通电后,秒表开始计数,断电后保存断电之前的秒数,下次通电要读取断电前的秒数继续计数。我用的方法是每记一个数,就写入EEPROM,但是这种方法不理想,很容易干扰数码管显示,小一点的数还可以用,大一点的数就不能用了,比如几百、几千的数。请求各位大佬们支招,有没有更好的方法?                                                                                 
#include"STC8G.H"#include"EEPROM.h"
#include"intrins.h"
#define uint unsigned int
#define uchar unsigned char

sbit sin=P3^5;
sbit sck=P3^6;
sbit rck=P3^7;

sbit duan1=P1^4;
sbit duan2=P1^5;
sbit duan3=P1^6;
sbit duan4=P1^7;


uchar code ledduan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
                                  0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x7f};
uint x,num;
uchar mb[2];
void delay(uint i)
{
   while(i--);
}

void hc595secondbyte(uchar dat)
{
   uchar a;
   sck=0;
   rck=0;
   for(a=0;a<8;a++)
   {
      sin=dat>>7;
          dat<<=1;
          sck=1;
          _nop_();
          _nop_();  
          sck=0;
   }
   rck=1;
   _nop_();
   _nop_();
   rck=0;
}

void display()
{
   uchar i;
   for(i=0;i<2;i++)
   {
         switch(i)
         {
              case(0):duan1=0;duan2=1;duan3=1;duan4=1;break;
              case(1):duan1=1;duan2=0;duan3=1;duan4=1;break;
         }
         hc595secondbyte(ledduan[mb[i]]);
         delay(500);
         hc595secondbyte(0xff);
   }
}

void datpros()
{
                mb[1]=num/10;
                mb[0]=num%10;                 
}


void main()
{   
        num=IapRead(1);

        P1M0=0X00;
        P1M1=0X00;
        P3M0=0X00;
        P3M1=0X00;
        P5M0=0X00;
        P5M1=0X00;

        TMOD=0X00;
        TL0=0X66;
        TH0=0Xfc;
        ET0=1;
        TR0=1;
        EA=1;

        while(1)
        {
            datpros();
            display();
        }                       
}

void T0_time() interrupt 1
{
   x++;       
   if(x==1000)
   {
          x=0;
          num++;
          IapErase(1);
          IapProgram(1,num);          
          if(num==60)
          num=0;
   }
}




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:213173 发表于 2022-6-5 08:31 | 只看该作者
STC8G在11.0592MHz擦写一个扇区耗时大于50ms,远大于你的中断周期。不但干扰数码管,也影响计时精度。
STC内置EEPROM是有寿命限制的,手册标明擦写次数可达 10 万次以上。如果每秒记录一次,可能持续两天就报废了。通常做法是利用芯片的外部中断、低压检测、比较器、ADC等功能实时检测电源电压。一旦检测到掉电,利用备用电池或滤波电容贮存的电能,立即把需要保存的数据写入EEPROM,供下次上电时读取使用。
回复

使用道具 举报

板凳
ID:213173 发表于 2022-6-5 09:26 | 只看该作者
  1. #include"STC8G.H"
  2. #include"EEPROM.h"
  3. #include"intrins.h"
  4. #define uint unsigned int
  5. #define uchar unsigned char

  6. sbit sin=P3^5;
  7. sbit sck=P3^6;
  8. sbit rck=P3^7;

  9. sbit duan1=P1^4;
  10. sbit duan2=P1^5;
  11. sbit duan3=P1^6;
  12. sbit duan4=P1^7;


  13. uchar code ledduan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
  14.                       0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x7f};
  15. uint x,num;
  16. uchar mb[4];

  17. void Delay1ms()                //@11.0592MHz
  18. {
  19.         unsigned char i, j;

  20.         i = 15;
  21.         j = 90;
  22.         do
  23.         {
  24.                 while (--j);
  25.         } while (--i);
  26. }


  27. void hc595secondbyte(uchar dat)
  28. {
  29.         uchar a;
  30.         sck=0;
  31.         rck=0;
  32.         for(a=0;a<8;a++)
  33.         {
  34.                 sin=dat>>7;
  35.                 dat<<=1;
  36.                 sck=1;
  37.                 _nop_();
  38.                 _nop_();  
  39.                 sck=0;
  40.         }
  41.         rck=1;
  42.         _nop_();
  43.         _nop_();
  44.         rck=0;
  45. }

  46. void display()
  47. {
  48.         static uchar i=0;
  49.         mb[0]=ledduan[num/1000%10];
  50.         mb[1]=ledduan[num/100%10];
  51.         mb[2]=ledduan[num/10%10];
  52.         mb[3]=ledduan[num%10];
  53.         P1&=0x0f;        //消隐
  54.         P1|=0x10<<i;//位码
  55.         hc595secondbyte(mb[i]);//段码
  56.         i=++i%4;
  57.         Delay1ms();
  58. }
  59. /*
  60. void datpros()
  61. {
  62.         mb[1]=num/10;
  63.         mb[0]=num%10;
  64. }*/

  65. void main()
  66. {   
  67.         P1M0=0X00;
  68.         P1M1=0X00;
  69.         P3M0=0X00;
  70.         P3M1=0X00;
  71.         P5M0=0X00;
  72.         P5M1=0X00;
  73.         //1毫秒@11.0592MHz
  74.         AUXR |= 0x80;        //定时器时钟1T模式
  75.         TMOD &= 0xF0;        //设置定时器自动重装模式
  76.         TL0 = 0xCD;                //设置定时初始值
  77.         TH0 = 0xD4;                //设置定时初始值
  78.         TR0 = 1;                //定时器0开始计时
  79.         EA=1;                        //使能总中断
  80.         ET0=1;                        //使能T0中断
  81.     EX0 = 1;        //使能INT0中断
  82.     IT0 = 1;        //使能INT0下降沿中断

  83.         num=IapRead(0);//读高8位
  84.         num<<=8;
  85.         num|=IapRead(1);//读低8位
  86.         if(num==0xffff)//检测是否初次上电
  87.                 num=0;

  88.         while(1)
  89.         {
  90. //                datpros();
  91.                 display();
  92.         }                        
  93. }

  94. void T0_time() interrupt 1
  95. {
  96.         x++;        
  97.         if(x==1000)
  98.         {
  99.                 x=0;
  100.                 num++;     
  101.                 if(num>9999)
  102.                         num=0;
  103.         }
  104. }
  105. //检测外部掉电
  106. void INT0_Isr() interrupt 0
  107. {
  108.         IapErase(0);//擦除扇区(扇区首地址0x0000)
  109.         IapProgram(0,num>>8);//写高8位数据
  110.         IapProgram(1,num);        //写低8位数据
  111. }
复制代码
回复

使用道具 举报

地板
ID:792404 发表于 2022-6-5 11:58 | 只看该作者
wulin 发表于 2022-6-5 08:31
STC8G在11.0592MHz擦写一个扇区耗时大于50ms,远大于你的中断周期。不但干扰数码管,也影响计时精度。
STC ...

感谢指导,没有仔细阅读手册,忽略了EEPROM擦写次数的问题,难怪连续几天就报废了一个单片机,感谢,感谢!
回复

使用道具 举报

5#
ID:792404 发表于 2022-6-5 12:02 | 只看该作者

感谢指点!已经用ADC功能检测低压的方法实验了,目前很稳定,正在测试中。再次感谢老师的指导。
回复

使用道具 举报

6#
ID:624769 发表于 2022-6-5 14:21 | 只看该作者
如果只是为了,掉电后的数据不丢失,反复擦写 STC 的 Eeprom 是不合适的。

建议,使用STC的掉电中断来对Eeprom进行掉电前的写入,只要单片机有 22~47uf的低频滤波,储电足够保存数据了。不需要增加额外硬件,只要多开一个中断即可。

详情可参考此帖:
http://www.51hei.com/bbs/dpj-213012-1.html
回复

使用道具 举报

7#
ID:792404 发表于 2022-6-5 15:51 | 只看该作者
188610329 发表于 2022-6-5 14:21
如果只是为了,掉电后的数据不丢失,反复擦写 STC 的 Eeprom 是不合适的。

建议,使用STC的掉电中断来对 ...

感谢老师指导,已验证此方法也挺好用的,感谢感谢!
回复

使用道具 举报

8#
ID:64283 发表于 2022-6-5 22:29 | 只看该作者
你没有处理好超过256之后的数,大于256后,你就要用到16位来做记忆,如果有更大的数,你就需要用更多的位来保存记忆值,你先处理好,超过256的数
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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