標(biāo)題:
求一個(gè)STC15斷電記憶的EEPROM代碼
[打印本頁]
作者:
cjtdz
時(shí)間:
2025-6-2 21:02
標(biāo)題:
求一個(gè)STC15斷電記憶的EEPROM代碼
謝謝大家
作者:
人人學(xué)會單片機(jī)
時(shí)間:
2025-6-2 23:31
#include "all.h" //從工程目錄下》c_and_h文件夾查找all文件
volatile u8 code EEPROM_Flash[512] _at_ 0x4000; //指定EEPROM的存儲空間地址
//************************************************************************************
// EEPROM IAP 擦除整個(gè)扇區(qū)
//************************************************************************************
void EEPROM_Wipe512_Drive(u8 AddrH)
{
IAP_ADDRH=AddrH;
IAP_CMD=0x03;
IAP_CONTR|=0x82;
//IAP_TPS=30; //為了兼容STC8H系列而出現(xiàn),STC15W視頻教程沒有這行,STC8A8K也沒有這一行
IAP_TRIG=0x5a;
IAP_TRIG=0xa5;
}
//************************************************************************************
// EEPROM IAP 向某個(gè)地址 保存數(shù)據(jù)
//************************************************************************************
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系列而出現(xiàn),STC15W視頻教程沒有這行,STC8A8K也沒有這一行
IAP_TRIG=0x5a;
IAP_TRIG=0xa5;
}
//************************************************************************************
// EEPROM IAP 從某個(gè)地址復(fù)制數(shù)據(jù)
//************************************************************************************
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系列而出現(xiàn),STC15W視頻教程沒有這行,STC8A8K也沒有這一行
IAP_TRIG=0x5a;
IAP_TRIG=0xa5;
Dat=IAP_DATA;
return Dat;
}
作者:
人人學(xué)會單片機(jī)
時(shí)間:
2025-6-2 23:31
kkk=EEPROM_Read_Byte_Drive(0,0); //EEPROM讀出上次記憶的數(shù)據(jù)
kkk++;
EEPROM_Wipe512_Drive(0); //擦除整個(gè)扇區(qū)
EEPROM_Write_Byte_Drive(0,0,kkk);
作者:
WL0123
時(shí)間:
2025-6-3 07:06
可以參考這個(gè)測試程序
//測試條件:TX-1C實(shí)驗(yàn)板,轉(zhuǎn)換板MCU型號IAP15W4K58S4,系統(tǒng)時(shí)鐘11.0592MHz
//注意:測試本示例時(shí),需在ISP下載時(shí)將低壓復(fù)位功能和低壓時(shí)禁止EEPROM操作關(guān)閉
#include "STC15Fxxxx.H"
#include <intrins.h> //庫頭文件
#define uint unsigned int //宏定義數(shù)據(jù)類型uint
#define uchar unsigned char //宏定義數(shù)據(jù)類型uchar
//宏定義ISP的操作命令
#define CMD_IDLE 0 //空閑模式
#define CMD_READ 1 //IAP字節(jié)讀命令
#define CMD_PROGRAM 2 //IAP字節(jié)編程命令
#define CMD_ERASE 3 //IAP扇區(qū)擦除命令
#define ENABLE_IAP 0x82 //CPU的等待時(shí)間
#define IAP_ADDRESS 0x0800 //測試地址
sbit duan=P2^6;
sbit wein=P2^7;
//順序共陰極數(shù)碼管段碼表,段碼a-h順序接PX0-PX7
uchar code table[]={//共陰數(shù)碼管段碼"0~f-."
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x40,0x80};
uchar data dis_buf[8]; //緩存數(shù)組
uint num,sec;
uchar i;
void Timer0Init(); //定時(shí)器初始化聲明
void IapIdle(); //關(guān)閉IAP/EEPROM
uchar IapReadByte(uint addr); //讀取EEPROM數(shù)據(jù)
void IapProgramByte(uint addr, uchar dat);//寫入EEPROM數(shù)據(jù)
void IapEraseSector(uint addr); //擦除EEPROM數(shù)據(jù)
void main()
{
P0M0 = 0x00;
P0M1 = 0x00;
P1M0 = 0x00;
P1M1 = 0x00;
P2M0 = 0x00;
P2M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
P6M0 = 0x00;
P6M1 = 0x00;
P7M0 = 0x00;
P7M1 = 0x00;
sec=IapReadByte(IAP_ADDRESS)<<8|IapReadByte(IAP_ADDRESS+1);//讀取保存的數(shù)據(jù) 用時(shí)11.75us
if(sec==0xffff)//如果沒有保存數(shù)據(jù)
sec=0;//變量為0
else IapEraseSector(IAP_ADDRESS);//擦除數(shù)據(jù),為下次掉電保存數(shù)據(jù)做準(zhǔn)備
PCON &= 0xDF;//清0掉電標(biāo)志
ELVD = 1;//開低壓中斷
EA = 1;//開總中斷
Timer0Init();//初始化定時(shí)器
while(1)
{
if(TF0)//查詢T0中斷請求標(biāo)志
{
TF0=0;//T0中斷請求標(biāo)志清0
if(++num>=1000)//1秒
{
num=0;
sec++;
}
dis_buf[0]=table[sec/10000%10];
dis_buf[1]=table[sec/1000%10];
dis_buf[2]=table[sec/100%10];
dis_buf[3]=table[sec/10%10];
dis_buf[4]=table[sec%10];
P0=0x00;duan=1;duan=0;
P0=~(0x01<<i);wein=1;wein=0;
P0=dis_buf[i];duan=1;duan=0;
i=++i%5;
}
}
}
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定時(shí)器時(shí)鐘1T模式
TMOD &= 0xF0; //設(shè)置定時(shí)器模式
TL0 = 0xCD; //設(shè)置定時(shí)初始值
TH0 = 0xD4; //設(shè)置定時(shí)初始值
TF0 = 0; //清除TF0標(biāo)志
TR0 = 1; //定時(shí)器0開始計(jì)時(shí)
}
/*----------------------------
關(guān)閉IAP功能
----------------------------*/
void IapIdle()
{
IAP_CONTR = 0; //關(guān)閉IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除觸發(fā)寄存器
IAP_ADDRH = 0x80; //將地址設(shè)置到非IAP區(qū)域
IAP_ADDRL = 0;
}
/*----------------------------
從ISP/IAP/EEPROM區(qū)域讀取一字節(jié)
----------------------------*/
uchar IapReadByte(uint addr)
{
uchar dat; //數(shù)據(jù)緩沖區(qū)
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_READ; //設(shè)置IAP命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
IAP_TRIG = 0x5a; //寫觸發(fā)命令(0x5a)
IAP_TRIG = 0xa5; //寫觸發(fā)命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
dat = IAP_DATA; //讀ISP/IAP/EEPROM數(shù)據(jù)
IapIdle(); //關(guān)閉IAP功能
return dat; //返回
}
/*-------------------------------
寫一字節(jié)數(shù)據(jù)到ISP/IAP/EEPROM區(qū)域
--------------------------------*/
void IapProgramByte(uint addr, uchar dat)
{
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_PROGRAM; //設(shè)置IAP命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
IAP_DATA = dat; //寫ISP/IAP/EEPROM數(shù)據(jù)
IAP_TRIG = 0x5a; //寫觸發(fā)命令(0x5a)
IAP_TRIG = 0xa5; //寫觸發(fā)命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle(); //關(guān)閉IAP功能
}
/*----------------------------
ISP/IAP/EEPROM扇區(qū)擦除
----------------------------*/
void IapEraseSector(uint addr)
{
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_ERASE; //設(shè)置IAP命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
IAP_TRIG = 0x5a; //寫觸發(fā)命令(0x5a)
IAP_TRIG = 0xa5; //寫觸發(fā)命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle(); //關(guān)閉IAP功能
}
void PowerLost() interrupt 6 //剩余電量從中斷開始到完全斷電2.5ms
{
EA = 0; //關(guān)閉總中斷
P0M1 = 0xff; //所有端口高阻用時(shí)2.75us
P1M1 = 0xff;
P2M1 = 0xff;
P3M1 = 0xff;
P4M1 = 0xff;
P5M1 = 0xff;
P6M1 = 0xff;
P7M1 = 0xff;
IapProgramByte(IAP_ADDRESS,sec>>8);//寫數(shù)據(jù)高8位到EEPROM
IapProgramByte(IAP_ADDRESS+1,sec);//寫數(shù)據(jù)低8位到EEPROM 寫兩個(gè)字節(jié)用時(shí)215.25us
while((PCON & 0x20) != 0) //復(fù)查低壓標(biāo)志
{
PCON &= 0xDF; //清除低壓標(biāo)志
_nop_();
_nop_(); //坐等掉電
}
IAP_CONTR = 0x20; //發(fā)現(xiàn)是誤報(bào),重啟單片機(jī),恢復(fù)正常工作
}
復(fù)制代碼
作者:
xiaobendan001
時(shí)間:
2025-6-3 07:34
斷電記憶關(guān)鍵在及時(shí)取得斷電信號以及在斷電后持續(xù)的供電直到保存的代碼完成。
作者:
szqinyi
時(shí)間:
2025-6-6 09:09
STC單片機(jī)需要識別斷電信號,必須CMP引腳接供電分壓電源,分壓后電壓控制在2.7V左右,這樣供電電源斷電瞬間CMP引腳第一時(shí)間識別到低電壓才能觸發(fā)斷電中斷,然后保持EEROM代碼就放在中斷函數(shù)里。
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1