关键词不能为空

当前您在: 主页 > 英语 >

51单片机读写内部EEPROM详解

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-02-09 08:47
tags:

-

2021年2月9日发(作者:守护神)



此文档共包含三个程序。



第一个程序最简单易懂,看懂了基本就会读写



51


单片机内部


EEPROMT




第二个程序和第一个读写



EEP ROM


原理差不多,包含有


L CD1602


操作方



法,有写字符串的方法。



第三个程序 在原有基础上增加了外部中断功能,细心的人会发现,操作内




EEPROM


过程会将总中断关闭,实际上程序要用到中断时 只需在原有的



EEP


ROM


操作后加上开总中断即可。


< /p>


验证第二、第三个程序时需按程序内主程序中的操作说明进行烧录单片


机,以验证是否成功操作单片机内部



EEPROM




程序



1




/** ************************************************** ***********


作品:


EEP ROM


实验,开机还原关电前


LED


的亮灭状况

< p>


单片机:



STC89C52RC


晶振:



12M


编译环境:



Keil uVision4 V9.00


******** ************************************************** *****


//#include


#include


#include


#define uchar unsigned char


#define uint unsigned int


****************


特殊功能寄存器声明



****************


1 / 43




sfr ISP_DATA = 0xe2;


sfr ISP_ADDRH = 0xe3;


sfr ISP_ADDRL = 0xe4;


sfr ISP_CMD = 0xe5;


sfr ISP_TRIG = 0xe6;


sfr ISP_CONTR = 0xe7;


sbit LED1 = P 2



0;


sbit LED2 = P 2



1;


sbit K1= P 3



2;//


按钮



1


sbit K2= P3


八< /p>


3;//


按钮



2


voidcc(uint addr);


voidxcx(uint addr,uchar dat);


uchar dcx(uint addr);


voidQ0();


/*


/*


void main(void)


uchar V;



*/


2 / 43





V = dcx(0x2002);//


开机读取


EEPROM




2002h


数 据



还原关电前


LED


的亮




状况



if(V == 2){LED1=0;LED2=1;}


else if(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


*/


/*


3 / 43





函数:擦除某一扇区


(


每个扇区



512


字节


)


入口:



addr =


某一扇区首地址



*/


void cc(uint addr)


//


打开


IAP


功能


(

< p>
ISP_CONTR.7)=


允许编程改变


Fla sh


设置


Flash


操作等待时





// 0x83(


晶振



v5M)0x82(


晶振



v10M)0x81(


晶振



v20M)0x80(


晶振



<40M)


ISP_CONTR = 0x81;


ISP_CMD= 0x03;/


用户可以对

< br>




进行扇区擦除



ISP_ADDRL = addr;// IS P/IA


操作时的地址寄存器低八位,



ISP _ADDRH = addr>>8;// IS P/IA


操作时的地址寄存器高八位。



EA =0;


ISP_TRIG = 0x46;




ISPEN(ISP_ CONTR.7)






ISP_TRlGfe


写入



46h


,


ISP_TRIG = 0 xB9;


再写入


B9h,ISP/IAP


命令才会生效。



_nop_();


Q0();


}//


关闭



ISP/IAP


/*


函数:写一字节


4 / 43







入口:



addr =


扇区单元地址



, dat =


待写入数










void xcx(uint addr,uchar dat)







ISP_CONTR = 0x81;





ISP_CMD= 0x02;/


用户可以对

< br>




进行字节编程




ISP_ADDRL = addr;





ISP_ADDRH = addr>>8;





ISP_DATA



dat;/


数据进





ISP_DATA



EA = 0;





ISP_TRIG = 0x46;





ISP_TRIG = 0xB9;





_nop_();





Q0();//


关闭



ISP/IAP








/*




函数:读一字节






入口:



addr =


扇区单元地







出口:



dat=


读出的数










uchar dcx(uint addr)


5 / 43




*/


*/




uchar dat;


ISP_CONTR = 0x81;


ISP_CMD= 0x01;/


用户可以对

< br>




进行字节读

< br>


ISP_ADDRL


= addr;


ISP_ADDRH = addr>>8;


EA = 0;


ISP_TRIG = 0x46;


ISP_TRIG = 0xB9;


_nop_();


dat = ISP_DATA;


Q0();


return dat;


}//


取出数据



//


关闭



ISP/IAP


/*


函数:关闭< /p>


ISP/lAP


操作



void Q0()


ISP_CONTR = 0;


关闭



IAP


功能



ISP_CMD=


0;/



机模式,无



ISP


操作



ISP_TRIG= 0;


关闭


IAP


功能


,


清与


I SP


有关的特殊功能寄存器


}


6 / 43




*/



/*


STC89C52R


内部


EEPROM


羊细地址表

< br>:



第一扇区第二扇区第三扇区第四扇区



起始地址结束地址起始地址结束地址起始地址结束地址起始地址结束地址



2000h21FFh2200h23FFh2400h25FFh2600h27FFH


第五扇区第六扇区第七扇区第八扇区



起始地址结束地址起始地址结束地址起始地址结束地址起始地址结束地址



2800h29FFh2A00h2BFFh2C00h2DFFh2E00h2FFFh


*/


程序



2


:


************** *************************************************


作品:


EEP ROM


实验,开机还原关电前



LED


的亮灭状况



单片机:



STC89C52RC


晶振


:


12M


编译环境:



Keil uVision4 V9.00


************************ ***************************************/


//#include


#include


#include


#define uchar unsigned char


#define uint unsigned int


7 / 43





/****************


特殊功能寄存器声明



****************/


sfr ISP_DATA = 0xe2;


sfr ISP_ADDRH = 0xe3;


sfr ISP_ADDRL = 0xe4;


sfr ISP_CMD = 0xe5;


sfr ISP_TRIG = 0xe6;


sfr ISP_CONTR = 0xe7;


sbit LED1 = P 2



0;


sbit LED2 = P 2



1;


sbit K1= P 3



2;//


按钮



1


sbit K2= P3


八< /p>


3;//


按钮



2


voidcc(uint addr);


voidxcx(uint addr,uchar dat);


uchar dcx(uint addr);


voidQ0();


#ifndef uchar


#define uchar unsigned char


#endif


#ifndef uint


#define uint unsigned int


#endif


/**********************************


8 / 43





PIN


口定义



**********************************


#define LCD1602_DATAPINS P0


sbit LCD1602_E



P 2



7;


sbit LCD1602 _RW=



2



5;


sbit LCD1602_RS



P 2



6;


**********************************


函数声明



**********************************


/*




51


单片机



12MHZ


时钟下的延时函数



*/


void Lcd1602_Delay1ms(uint c);//


误差



Ous

< p>
/*LCD1602


写入


8


位命令子函数


*/


void LcdWriteCom(uchar com);


/*LCD16O2


写入



8


位数据子函数



*/


void LcdWriteData(uchar dat);


/*LCD16O2


初始化子程序



*/


void LcdInit();


/*LCD16O2


写入字符串



*/


void LCDWrite_String(uchar x, uchar y,uchar z, uchar *s);


/*


设置


LCD1602< /p>


写入字符串的位置


*/


void LCD_set_xy(uchar x, uchar y, uchar z);


9 / 43





uchar ON_Hour=0x07;//


初始开灯时间



07


:


OOluchar Warning_TempH=32;//




温报警温度



/*


/*


void main(void)


uchar V;


V = dcx(0x2002);//< /p>


开机读取


EEPROM



2002h


数据



状况



if(V == 2){LED1=0;LED2=1;}


else if(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


10 /


43




*/


LED


的亮灭



还原关电前



if(!K2)


while(!K2);


LED1=0;LED2=0;


cc(0x2000);//


擦除第



1


个扇区


(


2000h~21FFh


xcx(0x2002,6);//




EEPROM




2002h


写入



6


*/


void main(void)


LcdInit();


//


不注销下面三句,烧录一次



//


注销小面三句,再烧录一次



//


若两次烧录后现象一致,则操作内部



EEPROM


成功


< br>/////////////////////////////////////////////// //////////////////


cc(0x2000);//


擦除第



1


个扇区


(


2000h~21FFh < /p>


xcx(0x2000,ON_Hour);//




EEPROM




2002h


写入



2


xcx(0x2001,Warning_TempH); //




EEPROM




2002h


写入


///////// ////////////////////////////////////////////////// //////


11 /


43



2





ON_Hour = dcx(0x2000);


Warning_TempH = dcx(0x2001);


if((ON_Hour==0x07)||(Warning_TempH==32))


LcdWriteCom(0x80);


LCDWrite_String(0, 1, 7,


else


LCDWrite_String(0, 1, 5,


while(1);


/*


函 数:擦除某一扇区


(


每个扇区



512


字节


)


入口:



addr =


某一扇区首地址



*/


void cc(uint addr)


//


打开


lAP


功能


(

< p>
ISP_CONTR.7)=


允许编程改变


Fla sh


设置


Flash


操作等待时


// 0x83(


晶振



<5M)0x82(


晶振



v10M)0x81(


晶振



<20M)0x80(


晶振



<40M)


ISP_CONTR = 0x81;


ISP_CMD= 0x03;/


用户可以对

< br>




进行扇区擦除



操作时的地址寄存器低八位,



12 /


43






ISP_ADDRL = addr;// IS P/IA




ISP _ADDRH = addr>>8;// IS P/IA


操作时的地址寄存器高八位。



EA =0;


ISP_TRIG = 0x46;




ISPEN(ISP_ CONTR.7)






ISP_TRlGfe


写入



46h


,


ISP_TRIG = 0xB9;


再写入



B9h,ISP/ IAP


命令才会生效。



_nop_();


Q0();//


关闭



ISP/IAP


/*


函数:写一字节



入口:



addr =


扇区单元地址



, dat =


待写入数据



void xcx(uint addr,uchar dat)


ISP_CONTR = 0x81;


ISP_CMD= 0x02;/


用户可以对





进行字节编程< /p>



ISP_ADDRL = addr;


ISP_ADDRH = addr>>8;


ISP_DATA= dat;/


数据进



ISP_DATA


EA = 0;


ISP_TRIG = 0x46;


ISP_TRIG = 0xB9;


_nop_();


13 /


43




*/



Q0();//


关闭



ISP/IAP


/*


函数:读一字节



入口:



addr =


扇区单元地址



出口:



dat



读出的数据



uchar dcx(uint addr)


uchar dat;


ISP_CONTR = 0x81;


ISP_CMD= 0 x01;/


用户可以对





进行字节读


ISP_ADDRH = addr>>8;


EA = 0;


ISP_TRIG = 0x46;


ISP_TRIG = 0xB9;


_nop_();


dat = ISP_DATA;/


取出数据



Q0();//


关闭



ISP/IAP


return dat;


14 /


43



*/



ISP_ADDRL


= addr;




/*


函数:关闭


ISP/lAP


操作



*/


void Q0()


ISP_CONTR = 0;


关闭



lAP


功能



ISP_CMD= 0;/


待机模式,无


ISP


操作



ISP_TRIG= 0;


关闭


IAP


功能

< br>,


清与


ISP


有关的特殊功能寄 存器




/*


STC89C52R


内部


EEPROM


羊细地址表


:



第一扇区第二扇区第三扇区第四扇区



起始地址结束地址起始地址结束地址起始地址结束地址起始地址结束地址



2000h21FFh2200h23FFh2400h25FFh2600h27FFH


第五扇区第六扇区第七扇区第八扇区



起始地址结束地址起始地址结束地址起始地址结束地址起始地址结束地址



2800h29FFh2A00h2BFFh2C00h2DFFh2E00h2FFFh


*/


/************************ *****************************************


**************


函数名



: Lcd1602_Delay1ms


函数功能



:


延时函数,延时



1ms



15 /


43





输入



: c


输出


:



< /p>


说名


:


该函数是在


12MHZ


晶振下,


12


分频单片机 的延时。



*********************** ******************************************


**************


void Lcd1602_Delay1ms(uint c)//


误差



Ous


uchar a,b;


for (; c>O; c--)


for (b=199;b>O;b--)


for(a=1;a>O;a--);

< p>
/******************************************* **********************


**************


*


函数名



: void LCDWrite_String(uchar x, uchar y, uchar *s)


*


函数功能




LCD


写入一个字符串



*


输入



: x,y,*s


*


输出

< p>




******** ************************************************** *******


**************


16 /


43





void LCDWrite_String(uchar x, uchar y, uchar z, uchar *s)//x 0~15 , y 0,1,2,3


LCD_set_xy(x,y,z);


while(*s)


LcdWriteData(*s);


s++;

< p>
******************************************** *********************


**************


*


函数名




void LCD_set_xy(uchar x, uchar y,uchar z)


*


函数功能



指定向


LCD


写入字符串 的位置



*


输入



x,y,z//x:


横坐标


y:< /p>


纵坐标


Z



字符 串长度



*


输出





************* ************************************************** **


**************


void LCD_set_xy(uchar x,uchar y,uchar z)


uchar i;


if(y==0)


17 /


43




LcdWriteCom(0x80+x);


for(i=0;i


LcdWriteData(' ');


LcdWriteCom(0x80+x);


if(y==1)


LcdWriteCom(0xc0+x);


for(i=0;i


LcdWriteData(' ');


LcdWriteCom(0xc0+x);


if(y==2)


LcdWriteCom(0x94+x);


for(i=0;i


LcdWriteData(' ');




18 /


43




LcdWriteCom(0x94+x);


if(y==3)


LcdWriteCom(0xd4+x);


for(i=0;i


LcdWriteData(' ');


LcdWriteCom(0xd4+x);


/****** ************************************************** *********


**************


*


函数名


: LcdWriteCom


*


函数功能




LCD


写入一个字节的命令



*


输入



: com


*


输出




************************ *****************************************


**************


#ifndefLCD1602 4PINS/


当没有定义这个



LCD1602 4PIN




void LcdWriteCom(uchar com)//


写入命令



19 /


43





LCD1602_E = 0;/


使


/




LCD1602_RS = 0;


选择发送命令



LCD1602_RW = 0;/



/


择写入



LCD1602_DATA PINS = com




入命令



Lcd1602_Delay 1ms(1);//


等待数据稳定



LCD1602_E = 1;/



/


入时序



Lcd1602_Delay 1ms(5);//


保持时间



LCD1602_E = 0;


#else


void LcdWriteCom(uchar com)//


写入命令



LCD1602_E = 0;/


使


/


能清零



LCD1602_RS = 0;/



/


择写入命令



LCD1602_RW = 0;/



/


择写入



LCD1602_DATAPINS = com


由于


4


位的接线是接到


P0


口的高四位,所以传



送高四位不用改



//Lcd1602_Delay1ms(1);


LCD1602_E = 1;/



/


入时序



Lcd1602_Delay1ms(5);


LCD1602_E = 0;


Lcd1602_Delay1ms(1);


20 /


43



-


-


-


-


-


-


-


-



本文更新与2021-02-09 08:47,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/620130.html

51单片机读写内部EEPROM详解的相关文章

  • 爱心与尊严的高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊严高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊重的作文题库

    1.作文关爱与尊重议论文 如果说没有爱就没有教育的话,那么离开了尊重同样也谈不上教育。 因为每一位孩子都渴望得到他人的尊重,尤其是教师的尊重。可是在现实生活中,不时会有

    小学作文
  • 爱心责任100字作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任心的作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文