您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 51单片机读写内部EEPROM详解
..此文档共包含三个程序。第一个程序最简单易懂,看懂了基本就会读写51单片机内部EEPROM了。第二个程序和第一个读写EEPROM原理差不多,包含有LCD1602操作方法,有写字符串的方法。第三个程序在原有基础上增加了外部中断功能,细心的人会发现,操作内部EEPROM过程会将总中断关闭,实际上程序要用到中断时只需在原有的EEPROM操作后加上开总中断即可。验证第二、第三个程序时需按程序内主程序中的操作说明进行烧录单片机,以验证是否成功操作单片机内部EEPROM。程序1:/***************************************************************作品:EEPROM实验,开机还原关电前LED的亮灭状况单片机:STC89C52RC晶振:12M编译环境:KeiluVision4V9.00***************************************************************///#includeSTC89C52RC.H#includereg52.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedint/****************特殊功能寄存器声明****************/sfrISP_DATA=0xe2;sfrISP_ADDRH=0xe3;sfrISP_ADDRL=0xe4;sfrISP_CMD=0xe5;sfrISP_TRIG=0xe6;sfrISP_CONTR=0xe7;sbitLED1=P2^0;sbitLED2=P2^1;sbitK1=P3^2;//按钮1sbitK2=P3^3;//按钮2..voidcc(uintaddr);voidxcx(uintaddr,uchardat);uchardcx(uintaddr);voidQ0();/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈函数:主程序┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*//*voidmain(void){ucharV;V=dcx(0x2002);//开机读取EEPROM区2002h数据,还原关电前LED的亮灭状况if(V==2){LED1=0;LED2=1;}elseif(V==6){LED1=0;LED2=0;}while(1){if(!K1){while(!K1);LED1=0;LED2=1;cc(0x2000);//擦除第1个扇区(2000h~21FFh)xcx(0x2002,2);//对EEPROM区2002h写入2}if(!K2){while(!K2);LED1=0;LED2=0;cc(0x2000);//擦除第1个扇区(2000h~21FFh)xcx(0x2002,6);//对EEPROM区2002h写入6}}}*//*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈函数:擦除某一扇区(每个扇区512字节)入口:addr=某一扇区首地址┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/voidcc(uintaddr)..{//打开IAP功能(ISP_CONTR.7)=1:允许编程改变Flash,设置Flash操作等待时间//0x83(晶振5M)0x82(晶振10M)0x81(晶振20M)0x80(晶振40M)ISP_CONTR=0x81;ISP_CMD=0x03;//用户可以对DataFlash/EEPROM区进行扇区擦除ISP_ADDRL=addr;//ISP/IAP操作时的地址寄存器低八位,ISP_ADDRH=addr8;//ISP/IAP操作时的地址寄存器高八位。EA=0;ISP_TRIG=0x46;//在ISPEN(ISP_CONTR.7)=1时,对ISP_TRIG先写入46h,ISP_TRIG=0xB9;//再写入B9h,ISP/IAP命令才会生效。_nop_();Q0();//关闭ISP/IAP}/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈函数:写一字节入口:addr=扇区单元地址,dat=待写入数据┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/voidxcx(uintaddr,uchardat){ISP_CONTR=0x81;ISP_CMD=0x02;//用户可以对DataFlash/EEPROM区进行字节编程ISP_ADDRL=addr;ISP_ADDRH=addr8;ISP_DATA=dat;//数据进ISP_DATAEA=0;ISP_TRIG=0x46;ISP_TRIG=0xB9;_nop_();Q0();//关闭ISP/IAP}/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈函数:读一字节入口:addr=扇区单元地址出口:dat=读出的数据┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/uchardcx(uintaddr){uchardat;ISP_CONTR=0x81;ISP_CMD=0x01;//用户可以对DataFlash/EEPROM区进行字节读ISP_ADDRL=addr;ISP_ADDRH=addr8;..EA=0;ISP_TRIG=0x46;ISP_TRIG=0xB9;_nop_();dat=ISP_DATA;//取出数据Q0();//关闭ISP/IAPreturndat;}/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈函数:关闭ISP/IAP操作┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/voidQ0(){ISP_CONTR=0;//关闭IAP功能ISP_CMD=0;//待机模式,无ISP操作ISP_TRIG=0;//关闭IAP功能,清与ISP有关的特殊功能寄存器}/*STC89C52RC内部EEPROM详细地址表:第一扇区第二扇区第三扇区第四扇区起始地址结束地址起始地址结束地址起始地址结束地址起始地址结束地址2000h21FFh2200h23FFh2400h25FFh2600h27FFH第五扇区第六扇区第七扇区第八扇区起始地址结束地址起始地址结束地址起始地址结束地址起始地址结束地址2800h29FFh2A00h2BFFh2C00h2DFFh2E00h2FFFh*/..程序2:/***************************************************************作品:EEPROM实验,开机还原关电前LED的亮灭状况单片机:STC89C52RC晶振:12M编译环境:KeiluVision4V9.00***************************************************************///#includeSTC89C52RC.H#includereg52.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedint/****************特殊功能寄存器声明****************/sfrISP_DATA=0xe2;sfrISP_ADDRH=0xe3;sfrISP_ADDRL=0xe4;sfrISP_CMD=0xe5;sfrISP_TRIG=0xe6;sfrISP_CONTR=0xe7;sbitLED1=P2^0;sbitLED2=P2^1;sbitK1=P3^2;//按钮1sbitK2=P3^3;//按钮2voidcc(uintaddr);voidxcx(uintaddr,uchardat);uchardcx(uintaddr);voidQ0();#ifndefuchar#defineucharunsignedchar#endif#ifndefuint#defineuintunsignedint#endif../**********************************PIN口定义**********************************/#defineLCD1602_DATAPINSP0sbitLCD1602_E=P2^7;sbitLCD1602_RW=P2^5;sbitLCD1602_RS=P2^6;/**********************************函数声明**********************************//*在51单片机12MHZ时钟下的延时函数*/voidLcd1602_Delay1ms(uintc);//误差0us/*LCD1602写入8位命令子函数*/voidLcdWriteCom(ucharcom);/*LCD1602写入8位数据子函数*/voidLcdWriteData(uchardat);/*LCD1602初始化子程序*/voidLcdInit();/*LCD1602写入字符串*/voidLCDWrite_String(ucharx,uchary,ucharz,uchar*s);/*设置LCD1602写入字符串的位置*/voidLCD_set_xy(ucharx,uchary,ucharz);ucharON_Hour=0x07;//初始开灯时间07:001ucharWarning_TempH=32;//高温报警温度5/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈函数:主程序┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*//*voidmain(void){ucharV;V=dcx(0x2002);//开机读取EEPROM区2002h数据,还原关电前LED的亮灭状况if(V==2){LED1=0;LED2=1;}elseif(V==6){LED1=0;LED2=0;}..while(1){if(!K1){while(!K1);LED1=0;LED2=1;cc(0x2000);//擦除第1个扇区(2000h~21FFh)xcx(0x2002,2);//对EEPROM区2002h写入2}if(!K2){while(!K2);LED1=0;LED2=0;cc(0x2000);//擦除第1个扇区(2000h~21FFh)xcx(0x2002,6);//对EEPROM区2002h写入6}}}*/voidmain(void){LcdInit();//不注销下面三句,烧录一次//注销小面三句,再烧录一次//若两次烧录后现象一致,则操作内部EEPROM成功/////////////////////////////////////////////////////////////////cc(0x2000);//擦除第1个扇区(2000h~21FFh)xcx(0x2000,ON_Hour);//对EEPROM区2002h写入2xcx(0x2001,Warning_TempH);//对EEPROM区2002h写入2/////////////////////////////////////////////////////////////////ON_Hour=dcx(0x2000);Warning_TempH=dcx(0x2001);if((ON_Hour==0x07)||(Warning_TempH==32)){LcdWriteCom(0x80);LCDWrite_String(0,1,7,SUCCESS);}..elseLCDWrite_String(0,1,5,ERROR);while(1);}/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈函数:擦除某一扇区(每个扇区512字节)入口:addr=某一扇区首地址┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/voidcc(uintaddr){//打开IAP功能(ISP_CONTR.
本文标题:51单片机读写内部EEPROM详解
链接地址:https://www.777doc.com/doc-6922724 .html