STC单片机内部EEPROM详解及应用

4星 · 超过85%的资源 需积分: 10 27 下载量 165 浏览量 更新于2024-09-09 收藏 168KB PDF 举报
"STC单片机的内部EEPROM应用主要涉及如何在单片机系统中保存数据以便在电源断开后仍然能保持信息,避免使用外部扩展存储器带来的额外成本和复杂性。STC单片机通过内置的EEPROM功能,利用IAP(在应用编程)技术读写内部FLASH来实现这一目的。IAP允许程序在运行时更新自身的存储器,确保数据安全存储。使用内置EEPROM时,需要了解并操作相关的特殊功能寄存器,如ISP_DATA、ISP_ADDRH、ISP_ADDRL、ISP_CMD和ISP_TRIG,以执行读写操作。不同型号的STC单片机,如STC89C51RC、STC89C52RC、STC89C54RD+、STC89C55RD+和STC89C58RD+,其内置EEPROM的容量和起始地址各不相同,通常每个扇区为512字节。" STC单片机的内部EEPROM是一个关键特性,它解决了在单片机系统中实现非易失性存储的问题。EEPROM(电可擦除可编程只读存储器)是一种能够在电源断开后保留数据的存储器类型。在传统的设计中,若要实现这种功能,通常需要额外添加外部的EEPROM或FLASHROM芯片,并通过IIC(集成电路互连)或SPI(串行外围接口)等通信协议与单片机连接。然而,这样做会增加硬件成本,同时也会使得软件设计更为复杂。 STC单片机通过内置的EEPROM功能,巧妙地利用了IAP(在应用编程)技术。IAP允许在程序运行期间动态地擦除和重新编程单片机的FLASH存储器,而不会影响正在运行的程序。这种方法使得用户可以在不增加额外硬件的情况下,安全地将数据存储在程序存储区的一部分,这些数据在电源断电后仍能保持。为了防止写入的数据破坏程序代码,必须将数据存储区域与程序存储区分开。 在实际使用STC单片机的内部EEPROM时,开发者需要操作一系列特殊功能寄存器。ISP_DATA寄存器用于存放读取或写入的数据;ISP_ADDRH和ISP_ADDRL组合成32位地址,指示操作的位置;ISP_CMD寄存器设置操作的命令;而ISP_TRIG寄存器则是触发IAP操作的关键,通过写入特定值(如0x46和0x59)来启动命令。ISPEN位(位于ISP_CONTR寄存器的第7位)必须设为1,以启用ISP/IAP功能。 不同型号的STC单片机内置的EEPROM容量不同,例如,STC89C51RC和STC89LE51RC从0x2000地址开始,共有8个512字节的扇区;STC89C52RC和STC89LE52RC也有相同的配置。STC89C54RD+和STC89LE54RD+以及STC89C55RD+和STC89LE55RD+的EEPROM容量更大,分别有58个512字节的扇区。开发者应根据具体应用选择合适的单片机型号,并正确配置和使用这些寄存器,以充分利用内部EEPROM的功能。
2021-11-16 上传
STC8单片机读写内部EEPROM KEIL工程文件源码: /* STC8 内部EEPROM测试 从手册717页上可以看出 STC8的 EEPROM空间为1k 地址在0000h-03ffh 地址也是1024的大小 次程序结合手册 编写 大同小异 程序的主要目的是 先清楚地址0 到512 (一个扇区)的数据 然后读取 清楚扇区的数据 如果清楚成功 则读到的数据都为0xff 然后在向里写入 1-ff 1-ff 512个这样的字节 然后在读里面的字节 判断是否和写入的一样 整个过程都是通过串口在不停的上传给电脑 重点强调 更新数据一定是要先擦除整个扇区 才能更新 这是和外部E2的比较大的区别 但是和flash的写法差不多 要求 下载时 STC8 内部晶振为11.0592 电脑打开串口的波特率为9600 */ #include "stc8.h" #define u8 unsigned char #define u16 unsigned int #define CMD_IDLE 0 //空闲模式 #define CMD_READ 1 //IAP字节读命令 #define CMD_PROGRAM 2 //IAP字节编程命令 #define CMD_ERASE 3 //IAP字节擦除命令 #define ENABLE_IAP 0X82 //if SYSCLK<20MHz //测试地址 #define IAP_ADDRESS 0X0000 //从手册上可以看出 STC15F2K60S2的EEPROM地址是0x0000- 0x03ff 正好是1k的地址空间 sbit led=P5^5; //P3.5口LED灯定义 //延时函数 void delay(u8 n) { while(n--); } //关闭IAP void IapIdle() { IAP_CONTR=0; //关闭IAP功能 IAP_CMD =0; //清除命令寄存器 IAP_TRIG =0; //清楚触发寄存器 IAP_ADDRH=0X80; //将地址设置到非IAP区域 IAP_ADDRL=0; } //从ISP/IAP/EEPROM区域读取一个字节 u8 IapReadByte(u16 addr) { u8 dat; //数据缓冲区 IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间 IAP_CMD=CMD_READ; //设置IAP命令 IAP_ADDRL=addr; //设置IAP低地址 IAP_ADDRH=addr>>8; //设置IAP高地址 IAP_TRIG=0X5a; //写触发命令(0x5a) 写触摸命令以后 命令才会生效 手册713页 IAP_TRIG=0Xa5; //写触发命令(0xa5) delay(10); //等待ISP/IAP/EEPROM操作完成 dat=IAP_DATA; //读ISP/IAP/EEPROM数据 IapIdle(); //关闭IAP功能 return dat; //返回 } //写一个字节数据到ISP/IAP/EEPROM区域 void IapProgramByte(u16 addr,u8 dat) { IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间 IAP_CMD=CMD_PROGRAM; //设置IAP命令 IAP_ADDRL=addr; //设置IAP低地址 IAP_ADDRH=addr>>8; //设置IAP高地址 IAP_DATA=dat; //写ISP/IAP/EEPROM数据 IAP_TRIG=0X5a; //写触发命令(0x5a) 写触摸命令以后 命令才会生效 手册713页 IAP_TRIG=0Xa5; //写触发命令(0xa5) delay(10); //等待ISP/IAP/EEPROM操作完成 IapIdle(); //关闭IAP功能 } //扇区擦除 void IapEraseSector(u16 addr) { IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间 IAP_CMD=CMD_ERASE; //设置IAP命令 IAP_ADDRL=addr; //设置IAP低地址 IAP_ADDR