51单片机读写内部EEPROM详解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

此文档共包含三个程序。

第一个程序最简单易懂,看懂了基本就会读写51单片机内部EEPROM了。

第二个程序和第一个读写EEPROM原理差不多,包含有LCD1602操作方法,有写字符串的方法。

第三个程序在原有基础上增加了外部中断功能,细心的人会发现,操作内部EEPROM 过程会将总中断关闭,实际上程序要用到中断时只需在原有的EEPROM操作后加上开总中断即可。

验证第二、第三个程序时需按程序内主程序中的操作说明进行烧录单片机,以验证是否成功操作单片机内部EEPROM。

程序1:

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

作品:EEPROM实验,开机还原关电前LED的亮灭状况

单片机:STC89C52RC

晶振:12M

编译环境:Keil uVision4 V9.00

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

//#include

#include

#include

#define uchar unsigned char

#define uint unsigned int

/****************特殊功能寄存器声明****************/

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 = P2^0;

sbit LED2 = P2^1;

sbit K1 = P3^2; //按钮1

sbit K2 = P3^3; //按钮2

void cc(uint addr);

void xcx(uint addr,uchar dat);

uchar dcx(uint addr);

void Q0();

/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

函数:主程序

┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/

/*

void main(void)

{

uchar V;

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

}

}

}

*/

/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈

函数:擦除某一扇区(每个扇区512字节)

入口:addr = 某一扇区首地址

┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/

void cc(uint addr)

{

// 打开IAP 功能(ISP_CONTR.7)=1:允许编程改变Flash, 设置Flash操作等待时间

// 0x83(晶振<5M) 0x82(晶振<10M) 0x81(晶振<20M) 0x80(晶振<40M) ISP_CONTR = 0x81;

ISP_CMD = 0x03; // 用户可以对"Data Flash/EEPROM区"进行扇区擦除ISP_ADDRL = addr; // ISP/IAP操作时的地址寄存器低八位,

ISP_ADDRH = addr>>8; // 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 = 待写入数据

┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/

void xcx(uint addr,uchar dat)

{

ISP_CONTR = 0x81;

ISP_CMD = 0x02; // 用户可以对"Data Flash/EEPROM区"进行字节编程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)

{

uchar dat;

ISP_CONTR = 0x81;

ISP_CMD = 0x01; // 用户可以对"Data Flash/EEPROM区"进行字节读

ISP_ADDRL = addr;

ISP_ADDRH = addr>>8;

相关文档
最新文档