標(biāo)題: 關(guān)于STC單片機(jī)掉電存儲數(shù)據(jù)的問題,請求各位大佬們支招? [打印本頁]

作者: YUANYUXING    時間: 2022-6-4 15:23
標(biāo)題: 關(guān)于STC單片機(jī)掉電存儲數(shù)據(jù)的問題,請求各位大佬們支招?
最近在用STC8G單片機(jī)測試掉電存儲的實(shí)驗,就是用秒表計數(shù),通電后,秒表開始計數(shù),斷電后保存斷電之前的秒數(shù),下次通電要讀取斷電前的秒數(shù)繼續(xù)計數(shù)。我用的方法是每記一個數(shù),就寫入EEPROM,但是這種方法不理想,很容易干擾數(shù)碼管顯示,小一點(diǎn)的數(shù)還可以用,大一點(diǎn)的數(shù)就不能用了,比如幾百、幾千的數(shù)。請求各位大佬們支招,有沒有更好的方法?                                                                                 
#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;
   }
}





作者: wulin    時間: 2022-6-5 08:31
STC8G在11.0592MHz擦寫一個扇區(qū)耗時大于50ms,遠(yuǎn)大于你的中斷周期。不但干擾數(shù)碼管,也影響計時精度。
STC內(nèi)置EEPROM是有壽命限制的,手冊標(biāo)明擦寫次數(shù)可達(dá) 10 萬次以上。如果每秒記錄一次,可能持續(xù)兩天就報廢了。通常做法是利用芯片的外部中斷、低壓檢測、比較器、ADC等功能實(shí)時檢測電源電壓。一旦檢測到掉電,利用備用電池或濾波電容貯存的電能,立即把需要保存的數(shù)據(jù)寫入EEPROM,供下次上電時讀取使用。
作者: wulin    時間: 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;        //設(shè)置定時器自動重裝模式
  76.         TL0 = 0xCD;                //設(shè)置定時初始值
  77.         TH0 = 0xD4;                //設(shè)置定時初始值
  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);//擦除扇區(qū)(扇區(qū)首地址0x0000)
  109.         IapProgram(0,num>>8);//寫高8位數(shù)據(jù)
  110.         IapProgram(1,num);        //寫低8位數(shù)據(jù)
  111. }
復(fù)制代碼

作者: YUANYUXING    時間: 2022-6-5 11:58
wulin 發(fā)表于 2022-6-5 08:31
STC8G在11.0592MHz擦寫一個扇區(qū)耗時大于50ms,遠(yuǎn)大于你的中斷周期。不但干擾數(shù)碼管,也影響計時精度。
STC ...

感謝指導(dǎo),沒有仔細(xì)閱讀手冊,忽略了EEPROM擦寫次數(shù)的問題,難怪連續(xù)幾天就報廢了一個單片機(jī),感謝,感謝!
作者: YUANYUXING    時間: 2022-6-5 12:02
wulin 發(fā)表于 2022-6-5 09:26

感謝指點(diǎn)!已經(jīng)用ADC功能檢測低壓的方法實(shí)驗了,目前很穩(wěn)定,正在測試中。再次感謝老師的指導(dǎo)。
作者: 188610329    時間: 2022-6-5 14:21
如果只是為了,掉電后的數(shù)據(jù)不丟失,反復(fù)擦寫 STC 的 Eeprom 是不合適的。

建議,使用STC的掉電中斷來對Eeprom進(jìn)行掉電前的寫入,只要單片機(jī)有 22~47uf的低頻濾波,儲電足夠保存數(shù)據(jù)了。不需要增加額外硬件,只要多開一個中斷即可。

詳情可參考此帖:
http://www.torrancerestoration.com/bbs/dpj-213012-1.html
作者: YUANYUXING    時間: 2022-6-5 15:51
188610329 發(fā)表于 2022-6-5 14:21
如果只是為了,掉電后的數(shù)據(jù)不丟失,反復(fù)擦寫 STC 的 Eeprom 是不合適的。

建議,使用STC的掉電中斷來對 ...

感謝老師指導(dǎo),已驗證此方法也挺好用的,感謝感謝!
作者: ephzq    時間: 2022-6-5 22:29
你沒有處理好超過256之后的數(shù),大于256后,你就要用到16位來做記憶,如果有更大的數(shù),你就需要用更多的位來保存記憶值,你先處理好,超過256的數(shù)




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1