#include <reg52.h>
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned int uint;
/*寄存器*/
sfr IAP_DATA = 0xE2;//数据寄存器
sfr IAP_ADDRH = 0xE3;//地址寄存器高8位
sfr IAP_ADDRL = 0xE4;//地址寄存器低8位
sfr IAP_CMD = 0xE5;//命令寄存器
sfr IAP_TRIG = 0xE6;//命令触发寄存器
sfr IAP_CONTR = 0xE7;//命令寄存器
/*IAP_CMD寄存器命令*/
#define CMD_STAND 0x00;//待机
#define CMD_READ 0x01;//读
#define CMD_WRITE 0x02;//写
#define CMD_ERASE 0x03;//擦除
/*IAP_CONTR寄存器命令*/
//IAP_CONTR最高位为1时允许读写和擦除
//#define IAP_ENABLE 0x80 //系统晶振<40MHz
#define IAP_ENABLE 0x81 //系统晶振<20MHz
//#define IAP_ENABLE x82 //系统晶振<10MHz
//#define IAP_ENABLE 0x83 //系统晶振<5MHz
//定义EEPROM扇区
#define IAP_ADDR1 0x2000;
sbit LED0=P2^0;//定义led IO口
sbit LED1=P2^1;
sbit K0=P1^4;//定义按键 IO口
sbit K1=P1^5;
void IapClose();//关闭IAP
void IapClear(uint addr);//清空一个扇区
uchar IapRead(uint addr);//读EEPROM中的数据
void IapWrite(uint addr,uchar dat);//向EEPROM写数据
void main()
{
uchar edata;
edata=IapRead(0x2018); //读取地址中的数据
if(edata==0x01)
{
LED0=0;
LED1=1;
}
else if(edata==0x02)
{
LED0=1;
LED1=0;
}
while(1)
{
if(!K0)
{
while(!K0);
LED0=0;
LED1=1;
IapClear(0x2000); //清空该扇区的数据
IapWrite(0x2018,0x01); //向地址中写入数据0x01
}
if(!K1)
{
while(!K1);
LED0=1;
LED1=0;
IapClear(0x2000);
IapWrite(0x2018,0x02);
}
}
}
/*************************************************
函数:IapClose
功能:关闭IAP
出口:void
入口:void
*************************************************/
void IapClose()
{
IAP_CONTR = 0x00;
IAP_CMD = 0x00;
IAP_TRIG = 0x00;
IAP_ADDRH = 0x80;
IAP_ADDRL = 0x00;
}
/*************************************************
函数:IapClear
功能:清空一个扇区
出口:void
入口:扇区开始地址
*************************************************/
void IapClear(uint addr)
{
IAP_CONTR=IAP_ENABLE; //IAP_ENABLE=0x81,允许读写擦除操作
IAP_CMD=CMD_ERASE; //CMD_ERASE==0x03,擦除指令
IAP_ADDRL=addr; //addr为16个字节的地址,将地址的低8位写入IAP_ADDRL寄存器
IAP_ADDRH=addr>>8; //地址的高8为写入IAP_ADDRH寄存器
IAP_TRIG=0x46; //每次操作都要向寄存器IAP_TRIG现写入0x46,在写入0xB9才会生效
IAP_TRIG=0xB9;
_nop_ ();
IapClose();
}
/*************************************************
函数:IapRead
功能:读数据
出口:uchar
入口:addr
*************************************************/
uchar IapRead(uint addr)
{
uchar dat;
IAP_CONTR=IAP_ENABLE;
IAP_CMD=CMD_READ;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG=0x46;
IAP_TRIG=0xB9;
_nop_ ();
dat=IAP_DATA;
IapClose();
return dat;
}
/*************************************************
函数:IapWrite
功能:写数据
出口:void
入口:addr,dat
*************************************************/
void IapWrite(uint addr,uchar dat)
{
IAP_CONTR=IAP_ENABLE;
IAP_CMD=CMD_WRITE;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_DATA=dat;
IAP_TRIG=0x46;
IAP_TRIG=0xB9;
_nop_ ();
IapClose();
}
/*
STC89C52RC内部EEPROM详细地址表:
第一扇区 | 第二扇区 | 第三扇区 | 第四扇区
起始地址 结束地址 | 起始地址 结束地址 | 起始地址 结束地址 | 起始地址 结束地址
2000h 21FFh | 2200h 23FFh | 2400h 25FFh | 2600h 27FFH
第五扇区 | 第六扇区 | 第七扇区 | 第八扇区
起始地址 结束地址 | 起始地址 结束地址 | 起始地址 结束地址 | 起始地址 结束地址
2800h 29FFh | 2A00h 2BFFh | 2C00h 2DFFh | 2E00h 2FFFh
*/
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned int uint;
/*寄存器*/
sfr IAP_DATA = 0xE2;//数据寄存器
sfr IAP_ADDRH = 0xE3;//地址寄存器高8位
sfr IAP_ADDRL = 0xE4;//地址寄存器低8位
sfr IAP_CMD = 0xE5;//命令寄存器
sfr IAP_TRIG = 0xE6;//命令触发寄存器
sfr IAP_CONTR = 0xE7;//命令寄存器
/*IAP_CMD寄存器命令*/
#define CMD_STAND 0x00;//待机
#define CMD_READ 0x01;//读
#define CMD_WRITE 0x02;//写
#define CMD_ERASE 0x03;//擦除
/*IAP_CONTR寄存器命令*/
//IAP_CONTR最高位为1时允许读写和擦除
//#define IAP_ENABLE 0x80 //系统晶振<40MHz
#define IAP_ENABLE 0x81 //系统晶振<20MHz
//#define IAP_ENABLE x82 //系统晶振<10MHz
//#define IAP_ENABLE 0x83 //系统晶振<5MHz
//定义EEPROM扇区
#define IAP_ADDR1 0x2000;
sbit LED0=P2^0;//定义led IO口
sbit LED1=P2^1;
sbit K0=P1^4;//定义按键 IO口
sbit K1=P1^5;
void IapClose();//关闭IAP
void IapClear(uint addr);//清空一个扇区
uchar IapRead(uint addr);//读EEPROM中的数据
void IapWrite(uint addr,uchar dat);//向EEPROM写数据
void main()
{
uchar edata;
edata=IapRead(0x2018); //读取地址中的数据
if(edata==0x01)
{
LED0=0;
LED1=1;
}
else if(edata==0x02)
{
LED0=1;
LED1=0;
}
while(1)
{
if(!K0)
{
while(!K0);
LED0=0;
LED1=1;
IapClear(0x2000); //清空该扇区的数据
IapWrite(0x2018,0x01); //向地址中写入数据0x01
}
if(!K1)
{
while(!K1);
LED0=1;
LED1=0;
IapClear(0x2000);
IapWrite(0x2018,0x02);
}
}
}
/*************************************************
函数:IapClose
功能:关闭IAP
出口:void
入口:void
*************************************************/
void IapClose()
{
IAP_CONTR = 0x00;
IAP_CMD = 0x00;
IAP_TRIG = 0x00;
IAP_ADDRH = 0x80;
IAP_ADDRL = 0x00;
}
/*************************************************
函数:IapClear
功能:清空一个扇区
出口:void
入口:扇区开始地址
*************************************************/
void IapClear(uint addr)
{
IAP_CONTR=IAP_ENABLE; //IAP_ENABLE=0x81,允许读写擦除操作
IAP_CMD=CMD_ERASE; //CMD_ERASE==0x03,擦除指令
IAP_ADDRL=addr; //addr为16个字节的地址,将地址的低8位写入IAP_ADDRL寄存器
IAP_ADDRH=addr>>8; //地址的高8为写入IAP_ADDRH寄存器
IAP_TRIG=0x46; //每次操作都要向寄存器IAP_TRIG现写入0x46,在写入0xB9才会生效
IAP_TRIG=0xB9;
_nop_ ();
IapClose();
}
/*************************************************
函数:IapRead
功能:读数据
出口:uchar
入口:addr
*************************************************/
uchar IapRead(uint addr)
{
uchar dat;
IAP_CONTR=IAP_ENABLE;
IAP_CMD=CMD_READ;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG=0x46;
IAP_TRIG=0xB9;
_nop_ ();
dat=IAP_DATA;
IapClose();
return dat;
}
/*************************************************
函数:IapWrite
功能:写数据
出口:void
入口:addr,dat
*************************************************/
void IapWrite(uint addr,uchar dat)
{
IAP_CONTR=IAP_ENABLE;
IAP_CMD=CMD_WRITE;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_DATA=dat;
IAP_TRIG=0x46;
IAP_TRIG=0xB9;
_nop_ ();
IapClose();
}
/*
STC89C52RC内部EEPROM详细地址表:
第一扇区 | 第二扇区 | 第三扇区 | 第四扇区
起始地址 结束地址 | 起始地址 结束地址 | 起始地址 结束地址 | 起始地址 结束地址
2000h 21FFh | 2200h 23FFh | 2400h 25FFh | 2600h 27FFH
第五扇区 | 第六扇区 | 第七扇区 | 第八扇区
起始地址 结束地址 | 起始地址 结束地址 | 起始地址 结束地址 | 起始地址 结束地址
2800h 29FFh | 2A00h 2BFFh | 2C00h 2DFFh | 2E00h 2FFFh
*/