51单片机之内部集成EEPROM

#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
*/

猜你喜欢

转载自blog.csdn.net/jx_lihuifu/article/details/80109288