51内部eeprom读写,实现掉电存储
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
主函数:
#include
#include"EEPROM.h"
#include"smg.h"
void main()
{
num=byte_read(DEBUG_Data_Memory_Begin_Sector_addr);//字节读(程序开始时读取EEPROM中数据)
if(num>=60)num=0;//防止首次上电时读取出错??
while(1)
{
if(num<60)
{
display(num);
num++;delay(5);
delay1(DELAY_CONST);
sector_erase(DEBUG_Data_Memory_Begin_Sector_addr);//擦出扇区
byte_program (DEBUG_Data_Memory_Begin_Sector_addr,num);//字节编程}
if(num==60)num=0;
}
}
EEPROM.h:
/*STC89C51RC,STC89LE51RC 0x2000 共八个扇区
STC89C52RC,STC89LE52RC 0x2000 共八个扇区
STC89C54RD+,STC89LE54RD+ 0x8000 共五十八个扇区
STC89C55RD+,STC89LE55RD+ 0x8000 共五十八个扇区
STC89C58RD+,STC89LE58RD+ 0x8000 共五十八个扇区*/
#include
#include
//sfr定义特殊功能寄存器
sfr ISP_DATA =0xe2;//ISP/IAP 操作时的数据寄存器,从Flash 读出的数据放在此处,向Flash 写的数据也需放在此处
sfr ISP_ADDRH =0xe3;//ISP/IAP 操作时的地址寄存器高八位
sfr ISP_ADDRL =0xe4;//ISP/IAP 操作时的地址寄存器低八位
sfr ISP_CMD =0xe5;//ISP/IAP 操作时的命令模式寄存器,须命令触发寄存器触发方可生效
sfr ISP_TRIG =0xe6;//ISP/IAP 操作时的命令触发寄存器
sfr ISP_CONTR =0xe7;//ISP/IAP 控制寄存器
/* 定义命令*/
#define uchar unsigned char /*8bit无符号整型*/
#define uint unsigned int /*16bit无符号整型*/
#define READ_AP_and_Data_Memory_Command 0x01 /*字节读数据存储区*/
#define PROGRAM_AP_and_Data_Memory_Command 0x02 /*字节编程数据存储区*/
#define SECTOR_ERASE_AP_and_Data_Memory_Command 0x03 /*扇区擦除数据存储*/
#define DEBUG_Data_Memory_Begin_Sector_addr 0x2000//扇区地址
#define DELAY_CONST 60000//延时
#define WAIT_TIME 0x01
uchar num;
/* 打开ISP,IAP 功能*/
void ISP_IAP_enable(void)
{
EA=0;/* 关中断*/
ISP_CONTR=ISP_CONTR & 0x18; /* 0001,1000 */
ISP_CONTR=ISP_CONTR|WAIT_TIME;
ISP_CONTR=ISP_CONTR|0x80; /* 1000,0000 */
}
/* 关闭ISP,IAP 功能*/
void ISP_IAP_disable(void)
{
ISP_CONTR=ISP_CONTR&0x7f;/* 0111,1111 */
ISP_TRIG=0x00;
EA=1;/* 开中断*/
}
/* 字节读*/
uchar byte_read(uint byte_addr)
{
ISP_ADDRH = (uchar)(byte_addr >> 8);
ISP_ADDRL = (uchar)(byte_addr & 0x00ff);
ISP_CMD = ISP_CMD&0xf8;/* 1111,1000 */
ISP_CMD = ISP_CMD|READ_AP_and_Data_Memory_Command;/* 0000,0001 */
ISP_IAP_enable();
ISP_TRIG = 0x46;
ISP_TRIG = 0xb9;
_nop_();
ISP_IAP_disable();
return (ISP_DATA);
}
/* 扇区擦除*/
void sector_erase(uint sector_addr)
{
uint get_sector_addr=0;
get_sector_addr=(sector_addr & 0xfe00); /* 1111,1110,0000,0000; 取扇区地址*/ ISP_ADDRH = (uchar)(get_sector_addr >> 8);
ISP_ADDRL = 0x00;
ISP_CMD = ISP_CMD&0xf8;/* 1111,1000 */
ISP_CMD =
ISP_CMD|SECTOR_ERASE_AP_and_Data_Memory_Command;/* 0000,0011 */ ISP_IAP_enable();
ISP_TRIG = 0x46;/* 触发ISP_IAP命令*/
ISP_TRIG = 0xb9;/* 触发ISP_IAP命令*/
_nop_();
ISP_IAP_disable();
}
/* 字节编程*/
void byte_program(uint byte_addr, uchar original_data)
{
ISP_ADDRH = (uchar)(byte_addr >> 8);
ISP_ADDRL = (uchar)(byte_addr & 0x00ff);
ISP_CMD = ISP_CMD & 0xf8; /* 1111,1000 */
ISP_CMD = ISP_CMD |
PROGRAM_AP_and_Data_Memory_Command; /* 0000,0010 */
ISP_DATA = original_data;
ISP_IAP_enable();
ISP_TRIG = 0x46; /* 触发ISP_IAP命令*/
ISP_TRIG = 0xb9; /* 触发ISP_IAP命令*/
_nop_();
ISP_IAP_disable();
}
void delay1(uint counter)
{
uint temp=0;
for(temp=counter;temp>0;temp--)
{
_nop_();
_nop_();
_nop_();
}
}