欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 291|回復: 5
收起左側

求一個STC15斷電記憶的EEPROM代碼

[復制鏈接]
ID:33548 發表于 2025-6-2 21:02 | 顯示全部樓層 |閱讀模式
謝謝大家
回復

使用道具 舉報

ID:390416 發表于 2025-6-2 23:31 | 顯示全部樓層
#include "all.h"                                                                 //從工程目錄下》c_and_h文件夾查找all文件
volatile u8 code EEPROM_Flash[512] _at_ 0x4000;        //指定EEPROM的存儲空間地址                       

//************************************************************************************  
// EEPROM IAP 擦除整個扇區
//************************************************************************************  
void EEPROM_Wipe512_Drive(u8 AddrH)
{
        IAP_ADDRH=AddrH;
        IAP_CMD=0x03;
        IAP_CONTR|=0x82;
        //IAP_TPS=30;                                                                        //為了兼容STC8H系列而出現,STC15W視頻教程沒有這行,STC8A8K也沒有這一行
        IAP_TRIG=0x5a;
        IAP_TRIG=0xa5;
}

//************************************************************************************  
// EEPROM IAP 向某個地址 保存數據
//************************************************************************************  
void EEPROM_Write_Byte_Drive(u8 AddrH,u8 AddrL,u8 Dat)
{
        IAP_ADDRH=AddrH;
        IAP_ADDRL=AddrL;
        IAP_DATA=Dat;
        IAP_CMD=0x02;
        IAP_CONTR|=0x82;
        //IAP_TPS=30;                                                                        //為了兼容STC8H系列而出現,STC15W視頻教程沒有這行,STC8A8K也沒有這一行
        IAP_TRIG=0x5a;
        IAP_TRIG=0xa5;
}

//************************************************************************************  
// EEPROM IAP 從某個地址復制數據
//************************************************************************************  
u8 EEPROM_Read_Byte_Drive(u8 AddrH,u8 AddrL)
{
        u8 Dat;
        IAP_ADDRH=AddrH;
        IAP_ADDRL=AddrL;
        IAP_CMD=0x01;
        IAP_CONTR|=0x82;
        //IAP_TPS=30;                                                                        //為了兼容STC8H系列而出現,STC15W視頻教程沒有這行,STC8A8K也沒有這一行
        IAP_TRIG=0x5a;
        IAP_TRIG=0xa5;
        Dat=IAP_DATA;
        return Dat;
}

回復

使用道具 舉報

ID:390416 發表于 2025-6-2 23:31 | 顯示全部樓層
kkk=EEPROM_Read_Byte_Drive(0,0);                                                        //EEPROM讀出上次記憶的數據
        kkk++;
        EEPROM_Wipe512_Drive(0);                                                                        //擦除整個扇區
        EEPROM_Write_Byte_Drive(0,0,kkk);
回復

使用道具 舉報

ID:1133081 發表于 2025-6-3 07:06 | 顯示全部樓層
可以參考這個測試程序
  1. //測試條件:TX-1C實驗板,轉換板MCU型號IAP15W4K58S4,系統時鐘11.0592MHz
  2. //注意:測試本示例時,需在ISP下載時將低壓復位功能和低壓時禁止EEPROM操作關閉

  3. #include "STC15Fxxxx.H"
  4. #include <intrins.h>                                //庫頭文件
  5. #define uint unsigned int                         //宏定義數據類型uint
  6. #define uchar unsigned char                 //宏定義數據類型uchar
  7. //宏定義ISP的操作命令
  8. #define CMD_IDLE    0               //空閑模式
  9. #define CMD_READ    1               //IAP字節讀命令
  10. #define CMD_PROGRAM 2               //IAP字節編程命令
  11. #define CMD_ERASE   3               //IAP扇區擦除命令
  12. #define ENABLE_IAP  0x82            //CPU的等待時間
  13. #define IAP_ADDRESS 0x0800                        //測試地址
  14. sbit duan=P2^6;
  15. sbit wein=P2^7;

  16. //順序共陰極數碼管段碼表,段碼a-h順序接PX0-PX7
  17. uchar code table[]={//共陰數碼管段碼"0~f-."
  18.                 0x3f,0x06,0x5b,0x4f,
  19.                 0x66,0x6d,0x7d,0x07,
  20.                 0x7f,0x6f,0x77,0x7c,
  21.                 0x39,0x5e,0x79,0x71,0x40,0x80};
  22. uchar data dis_buf[8];                //緩存數組
  23. uint num,sec;
  24. uchar i;

  25. void Timer0Init();                                        //定時器初始化聲明
  26. void IapIdle();                                                //關閉IAP/EEPROM
  27. uchar IapReadByte(uint addr);                //讀取EEPROM數據
  28. void IapProgramByte(uint addr, uchar dat);//寫入EEPROM數據
  29. void IapEraseSector(uint addr);                //擦除EEPROM數據

  30. void main()                                                       
  31. {
  32.         P0M0 = 0x00;
  33.         P0M1 = 0x00;
  34.         P1M0 = 0x00;
  35.         P1M1 = 0x00;
  36.         P2M0 = 0x00;
  37.         P2M1 = 0x00;
  38.         P3M0 = 0x00;
  39.         P3M1 = 0x00;
  40.         P4M0 = 0x00;
  41.         P4M1 = 0x00;
  42.         P5M0 = 0x00;
  43.         P5M1 = 0x00;
  44.         P6M0 = 0x00;
  45.         P6M1 = 0x00;
  46.         P7M0 = 0x00;
  47.         P7M1 = 0x00;
  48.         sec=IapReadByte(IAP_ADDRESS)<<8|IapReadByte(IAP_ADDRESS+1);//讀取保存的數據 用時11.75us
  49.         if(sec==0xffff)//如果沒有保存數據
  50.                 sec=0;//變量為0
  51.         else IapEraseSector(IAP_ADDRESS);//擦除數據,為下次掉電保存數據做準備

  52.         PCON &= 0xDF;//清0掉電標志
  53.         ELVD = 1;//開低壓中斷
  54.         EA   = 1;//開總中斷

  55.         Timer0Init();//初始化定時器

  56.         while(1)
  57.         {
  58.                 if(TF0)//查詢T0中斷請求標志
  59.                 {               
  60.                         TF0=0;//T0中斷請求標志清0
  61.                         if(++num>=1000)//1秒
  62.                         {
  63.                                 num=0;                               
  64.                                 sec++;
  65.                         }
  66.                         dis_buf[0]=table[sec/10000%10];
  67.                         dis_buf[1]=table[sec/1000%10];
  68.                         dis_buf[2]=table[sec/100%10];
  69.                         dis_buf[3]=table[sec/10%10];
  70.                         dis_buf[4]=table[sec%10];

  71.                         P0=0x00;duan=1;duan=0;
  72.                         P0=~(0x01<<i);wein=1;wein=0;
  73.                         P0=dis_buf[i];duan=1;duan=0;
  74.                         i=++i%5;
  75.                 }
  76.         }
  77. }

  78. void Timer0Init(void)        //1毫秒@11.0592MHz
  79. {
  80.         AUXR |= 0x80;                //定時器時鐘1T模式
  81.         TMOD &= 0xF0;                //設置定時器模式
  82.         TL0 = 0xCD;                        //設置定時初始值
  83.         TH0 = 0xD4;                        //設置定時初始值
  84.         TF0 = 0;                        //清除TF0標志
  85.         TR0 = 1;                        //定時器0開始計時
  86. }


  87. /*----------------------------
  88.         關閉IAP功能
  89. ----------------------------*/
  90. void IapIdle()
  91. {
  92.     IAP_CONTR = 0;                  //關閉IAP功能
  93.     IAP_CMD = 0;                    //清除命令寄存器
  94.     IAP_TRIG = 0;                   //清除觸發寄存器
  95.     IAP_ADDRH = 0x80;               //將地址設置到非IAP區域
  96.     IAP_ADDRL = 0;
  97. }
  98. /*----------------------------
  99. 從ISP/IAP/EEPROM區域讀取一字節
  100. ----------------------------*/
  101. uchar IapReadByte(uint addr)
  102. {
  103.     uchar dat;                       //數據緩沖區

  104.     IAP_CONTR = ENABLE_IAP;         //使能IAP
  105.     IAP_CMD = CMD_READ;             //設置IAP命令
  106.     IAP_ADDRL = addr;               //設置IAP低地址
  107.     IAP_ADDRH = addr >> 8;          //設置IAP高地址
  108.     IAP_TRIG = 0x5a;                //寫觸發命令(0x5a)
  109.     IAP_TRIG = 0xa5;                //寫觸發命令(0xa5)
  110.     _nop_();                        //等待ISP/IAP/EEPROM操作完成
  111.     dat = IAP_DATA;                 //讀ISP/IAP/EEPROM數據
  112.     IapIdle();                      //關閉IAP功能
  113.     return dat;                     //返回
  114. }
  115. /*-------------------------------
  116. 寫一字節數據到ISP/IAP/EEPROM區域
  117. --------------------------------*/
  118. void IapProgramByte(uint addr, uchar dat)
  119. {
  120.     IAP_CONTR = ENABLE_IAP;         //使能IAP
  121.     IAP_CMD = CMD_PROGRAM;          //設置IAP命令
  122.     IAP_ADDRL = addr;               //設置IAP低地址
  123.     IAP_ADDRH = addr >> 8;          //設置IAP高地址
  124.     IAP_DATA = dat;                 //寫ISP/IAP/EEPROM數據
  125.     IAP_TRIG = 0x5a;                //寫觸發命令(0x5a)
  126.     IAP_TRIG = 0xa5;                //寫觸發命令(0xa5)
  127.     _nop_();                        //等待ISP/IAP/EEPROM操作完成
  128.     IapIdle();                      //關閉IAP功能
  129. }
  130. /*----------------------------
  131. ISP/IAP/EEPROM扇區擦除
  132. ----------------------------*/
  133. void IapEraseSector(uint addr)
  134. {
  135.     IAP_CONTR = ENABLE_IAP;         //使能IAP
  136.     IAP_CMD = CMD_ERASE;            //設置IAP命令
  137.     IAP_ADDRL = addr;               //設置IAP低地址
  138.     IAP_ADDRH = addr >> 8;          //設置IAP高地址
  139.     IAP_TRIG = 0x5a;                //寫觸發命令(0x5a)
  140.     IAP_TRIG = 0xa5;                //寫觸發命令(0xa5)
  141.     _nop_();                        //等待ISP/IAP/EEPROM操作完成
  142.     IapIdle();                      //關閉IAP功能
  143. }
  144. void PowerLost() interrupt 6                //剩余電量從中斷開始到完全斷電2.5ms
  145. {
  146.         EA = 0;                                                //關閉總中斷
  147.         P0M1 = 0xff;                                //所有端口高阻用時2.75us
  148.         P1M1 = 0xff;
  149.         P2M1 = 0xff;
  150.         P3M1 = 0xff;
  151.         P4M1 = 0xff;
  152.         P5M1 = 0xff;
  153.         P6M1 = 0xff;
  154.         P7M1 = 0xff;
  155.         IapProgramByte(IAP_ADDRESS,sec>>8);//寫數據高8位到EEPROM
  156.         IapProgramByte(IAP_ADDRESS+1,sec);//寫數據低8位到EEPROM  寫兩個字節用時215.25us

  157.         while((PCON & 0x20) != 0)         //復查低壓標志
  158.         {
  159.                 PCON &= 0xDF;                  //清除低壓標志
  160.                 _nop_();               
  161.                 _nop_();                            //坐等掉電
  162.         }
  163.         IAP_CONTR = 0x20;                 //發現是誤報,重啟單片機,恢復正常工作
  164. }


復制代碼
回復

使用道具 舉報

ID:1109793 發表于 2025-6-3 07:34 | 顯示全部樓層
斷電記憶關鍵在及時取得斷電信號以及在斷電后持續的供電直到保存的代碼完成。
回復

使用道具 舉報

ID:421260 發表于 2025-6-6 09:09 | 顯示全部樓層
STC單片機需要識別斷電信號,必須CMP引腳接供電分壓電源,分壓后電壓控制在2.7V左右,這樣供電電源斷電瞬間CMP引腳第一時間識別到低電壓才能觸發斷電中斷,然后保持EEROM代碼就放在中斷函數里。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表