最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

STC89C52内部EEPROM

IT圈 admin 29浏览 0评论

2024年10月3日发(作者:年春)

STC89C52内部EEPROM

单片机运行时的数据都存在于RAM(随机存储器)中,在掉电后

RAM 中的数据是无法保留的,那么怎样使数据在掉电后不丢失呢?这

就需要使用EEPROM 或FLASHROM 等存储器来实现。在传统的单片

机系统中,一般是在片外扩展存储器,单片机与存储器之间通过IIC 或

SPI 等接口来进行数据通信。这样不光会增加开发成本,同时在程序开

发上也要花更多的心思。在STC 单片机中内置了EEPROM(其实是采

用IAP 技术读写内部FLASH 来实现EEPROM),这样就节省了片外

资源,使用起来也更加方便。下面就详细介绍STC 单片机内置

EEPROM 及其使用方法。STC 各型号单片机内置的EEPROM 的容量

各有不同,见下表:

(内部EEPROM 可以擦写100000 次以上)

上面提到了IAP,它的意思是“在应用编程”,即在程序运行时程

序存储器可由程序自

身进行擦写。正是是因为有了IAP,从而可以使单片机可以将数据

写入到程序存储器中,使

得数据如同烧入的程序一样,掉电不丢失。当然写入数据的区域

与程序存储区要分开来,以使程序不会遭到破坏。要使用IAP 功能,

与以下几个特殊功能寄存器相关:

ISP_DA T A:ISP/IAP 操作时的数据寄存器。

ISP/IAP 从Flash 读出的数据放在此处,向Flash 写的数据也需放

在此处

ISP_ADDRH:ISP/IAP 操作时的地址寄存器高八位。

ISP_ADDRL:ISP/IAP 操作时的地址寄存器低八位。

ISP_CMD:ISP/IAP 操作时的命令模式寄存器,须命令触发寄存

器触发方可生效。ISP_TRIG:ISP/IAP 操作时的命令触发寄存器。

当ISPEN(ISP_CONTR.7)=1 时,对ISP_TRIG先写入0x46,

再写入0xb9,ISP/IAP 命令才会生效。

单片机芯片型号起始地址内置EEPROM 容量(每扇区512 字节)

STC89C51RC,STC89LE51RC 0x2000 共八个扇区

STC89C52RC,STC89LE52RC 0x2000 共八个扇区

STC89C54RD+,STC89LE54RD+ 0x8000 共五十八个扇区

STC89C55RD+,STC89LE55RD+ 0x8000 共五十八个扇区

STC89C58RD+,STC89LE58RD+ 0x8000 共五十八个扇区

寄存器标识地址名称7 6 5 4 3 2 1 0 初始值

ISP_DA TA 0xE2 ISP/IAP闪存数据寄存器11111111

ISP_ADDRH 0xE3 ISP/IAP 闪存地址高位00000000

ISP_ADDRL 0xE4 ISP/IAP 闪存地址低位00000000

ISP_CMD 0xE5 ISP/IAP闪存命令寄存器MS2

MS1 MS0 xxxxx000

ISP_TRIG 0xE6 ISP/IAP 闪存命令触发xxxxxxxx

ISP_CONTR 0xE7 ISP/IAP 控制寄存器ISPEN SWBS SWRST

WT2

WT1 WT0 00xx000

B7 B6 B5 B4 B3 B2 B1 B0 命令/操作模式选择

保留命令选择

-----0 0 0 待机模式,无ISP/IAP 操作

-----0 0 1 对用户的应用程序Flash 区及数据Flash 区字节

-----0 1 0 对用户的应用程序Flash 区及数据Flash 区字节

编程

-----0 1 1 对用户的应用程序Flash 区及数据Flash 区扇区

擦除

ISP_CONTR:ISP/IAP 控制寄存器。

ISPEN:ISP/IAP 功能允许位。0:禁止ISP/IAP 编程改变Flash,

1:允许编程改变Flash SWBS:软件选择从用户主程序区启动(0),

还是从ISP 程序区启动(1)。SWRST:0:不操作,1:产生软件系

统复位,硬件自动清零。

ISP_CONTR 中的SWBS 与SWRST 这两个功能位,可以实现单片

机的软件启动,并启动到ISP 区或用户程序区,这在“STC 单片机自

动下载”一节,亦有所应用。

如:

ISP_CONTR=0x60? 则可以实现从用户应用程序区软件复位到ISP

程序区开始运行

程序。

ISP_CONTR=0x20? 则可以实现从ISP 程序区软件复位到用户应

用程序区开始运行

程序。

用IAP 向Flash 中读写数据,是需要一定的读写时间的,读写数

据命令发出后,要等待

一段时间才可以读写成功。这个等待时间就是由WT2、WT1、

WT0 与晶体振荡器频率决定的。

(以上的建议时钟是(WT2、WT1、WT0)取不同的值时的标称

时钟,用户系统中的时钟不要过高,否则可能使操作不稳定。)

#include "reg52.h"

#include "eeprom.h"

//****************** 关闭 ISPIAP 功能 **************

void ISP_IAP_Disable(void)

{

ISP_CONTR = 0x00;

ISP_CMD = 0X00;

ISP_TRIG = 0x00;

EA = 1; //开中断

}

//*******************字节读***************************

uchar Byte_read(uint byte_addr)

{

ISP_CONTR = En_Wait_TIME; //开启ISP/IAP;并送等待时间

ISP_CMD = Read_COM; //送字节读命令字

ISP_ADDRH = (uchar)(byte_addr >>8); //送地址高字节

ISP_ADDRL = (uchar)(byte_addr &0X00FF); //送地址低字节

EA = 0; //关中断

ISP_TRIG = 0X46; //送触发命令字 0X46、0XB9

ISP_TRIG = 0XB9;

_nop_();

ISP_IAP_Disable(); //关闭ISP/IAP功能

EA = 1; //开中断

return ((unsigned char)ISP_DATA);

}

//********************字节编程***********************

void Byte_program(uint byte_addr uchar isp_iap_data)

{

ISP_CONTR = En_Wait_TIME; //开启ISP/IAP;并送等待时间

ISP_CMD = Prog_COM; //送字节编程命令字

ISP_ADDRH = (uchar)(byte_addr >>8); //送地址高字节

ISP_ADDRL = (uchar)(byte_addr &0X00FF); //送地址低字节

ISP_DATA = isp_iap_data; //送数据进ISP_DATA

EA = 0; //关中断

ISP_TRIG = 0X46; //送触发命令字 0X46、0XB9

ISP_TRIG = 0XB9;

_nop_();

ISP_IAP_Disable(); //关闭ISP/IAP功能

EA = 1; //开中断

}

//********************* 扇区擦除*********************

void Sector_erase(uint sector_addr)

{

ISP_CONTR = En_Wait_TIME; //开启ISP/IAP;并送等待时间

// ISP_CONTR=0xc1;

ISP_CMD = Dele_COM; //送扇区擦除命令字

ISP_ADDRH = (uchar)(sector_addr >>8); //送地址高字节

ISP_ADDRL = (uchar)(sector_addr &0X00FF); //送地址低字节

EA = 0; //关中断

ISP_TRIG = 0X46; //送触发命令字 0X46、0XB9

ISP_TRIG = 0XB9;

_nop_();

ISP_IAP_Disable(); //关闭ISP/IAP功能

EA = 1;

}

#ifndef _eeprom_h

#define _eeprom_H

//*********************EEPROM定义命令字节

****************** #define Read_COM 0X01 //字节读数据存储区

#define Prog_COM 0X02 //字节编程数据存储区

#define Dele_COM 0X03 //扇区擦除数据存储区

#define En_Wait_TIME 0X81 //设置等待时间并使能ISP/IAP

//从用户区启动程序

//0X00==40MHZ以下0X01==20MHZ以下

//0X02==10MHZ以下0X03==5MHZ以下现在设置了20MHZ

以下的

//

#define Start_ADDRH 0X20 //扇区地址高位STC89C/LE52RC

#define Start_ADDRL 0X00 //扇区地址低位

#endif

注意了,要写数据时,一定要对该扇区先擦除后写数据的,所以

要写的数据尽量不要多,也可以对不同功能的数据存在不同的扇区里。

如:

Sector_erase(0X2e00); //扇区擦除第八个扇区

Byte_program(0X2e00Eeprom_ReadCode);//写EEPROM保存

可读命令

要读数据时,就直接读就可以了。

ReadData=Byte_read(0X2002);//读取该地址的数据

读一个字节、编程一个字节、擦除一个扇区分别用时10us、60us、

10ms

2024年10月3日发(作者:年春)

STC89C52内部EEPROM

单片机运行时的数据都存在于RAM(随机存储器)中,在掉电后

RAM 中的数据是无法保留的,那么怎样使数据在掉电后不丢失呢?这

就需要使用EEPROM 或FLASHROM 等存储器来实现。在传统的单片

机系统中,一般是在片外扩展存储器,单片机与存储器之间通过IIC 或

SPI 等接口来进行数据通信。这样不光会增加开发成本,同时在程序开

发上也要花更多的心思。在STC 单片机中内置了EEPROM(其实是采

用IAP 技术读写内部FLASH 来实现EEPROM),这样就节省了片外

资源,使用起来也更加方便。下面就详细介绍STC 单片机内置

EEPROM 及其使用方法。STC 各型号单片机内置的EEPROM 的容量

各有不同,见下表:

(内部EEPROM 可以擦写100000 次以上)

上面提到了IAP,它的意思是“在应用编程”,即在程序运行时程

序存储器可由程序自

身进行擦写。正是是因为有了IAP,从而可以使单片机可以将数据

写入到程序存储器中,使

得数据如同烧入的程序一样,掉电不丢失。当然写入数据的区域

与程序存储区要分开来,以使程序不会遭到破坏。要使用IAP 功能,

与以下几个特殊功能寄存器相关:

ISP_DA T A:ISP/IAP 操作时的数据寄存器。

ISP/IAP 从Flash 读出的数据放在此处,向Flash 写的数据也需放

在此处

ISP_ADDRH:ISP/IAP 操作时的地址寄存器高八位。

ISP_ADDRL:ISP/IAP 操作时的地址寄存器低八位。

ISP_CMD:ISP/IAP 操作时的命令模式寄存器,须命令触发寄存

器触发方可生效。ISP_TRIG:ISP/IAP 操作时的命令触发寄存器。

当ISPEN(ISP_CONTR.7)=1 时,对ISP_TRIG先写入0x46,

再写入0xb9,ISP/IAP 命令才会生效。

单片机芯片型号起始地址内置EEPROM 容量(每扇区512 字节)

STC89C51RC,STC89LE51RC 0x2000 共八个扇区

STC89C52RC,STC89LE52RC 0x2000 共八个扇区

STC89C54RD+,STC89LE54RD+ 0x8000 共五十八个扇区

STC89C55RD+,STC89LE55RD+ 0x8000 共五十八个扇区

STC89C58RD+,STC89LE58RD+ 0x8000 共五十八个扇区

寄存器标识地址名称7 6 5 4 3 2 1 0 初始值

ISP_DA TA 0xE2 ISP/IAP闪存数据寄存器11111111

ISP_ADDRH 0xE3 ISP/IAP 闪存地址高位00000000

ISP_ADDRL 0xE4 ISP/IAP 闪存地址低位00000000

ISP_CMD 0xE5 ISP/IAP闪存命令寄存器MS2

MS1 MS0 xxxxx000

ISP_TRIG 0xE6 ISP/IAP 闪存命令触发xxxxxxxx

ISP_CONTR 0xE7 ISP/IAP 控制寄存器ISPEN SWBS SWRST

WT2

WT1 WT0 00xx000

B7 B6 B5 B4 B3 B2 B1 B0 命令/操作模式选择

保留命令选择

-----0 0 0 待机模式,无ISP/IAP 操作

-----0 0 1 对用户的应用程序Flash 区及数据Flash 区字节

-----0 1 0 对用户的应用程序Flash 区及数据Flash 区字节

编程

-----0 1 1 对用户的应用程序Flash 区及数据Flash 区扇区

擦除

ISP_CONTR:ISP/IAP 控制寄存器。

ISPEN:ISP/IAP 功能允许位。0:禁止ISP/IAP 编程改变Flash,

1:允许编程改变Flash SWBS:软件选择从用户主程序区启动(0),

还是从ISP 程序区启动(1)。SWRST:0:不操作,1:产生软件系

统复位,硬件自动清零。

ISP_CONTR 中的SWBS 与SWRST 这两个功能位,可以实现单片

机的软件启动,并启动到ISP 区或用户程序区,这在“STC 单片机自

动下载”一节,亦有所应用。

如:

ISP_CONTR=0x60? 则可以实现从用户应用程序区软件复位到ISP

程序区开始运行

程序。

ISP_CONTR=0x20? 则可以实现从ISP 程序区软件复位到用户应

用程序区开始运行

程序。

用IAP 向Flash 中读写数据,是需要一定的读写时间的,读写数

据命令发出后,要等待

一段时间才可以读写成功。这个等待时间就是由WT2、WT1、

WT0 与晶体振荡器频率决定的。

(以上的建议时钟是(WT2、WT1、WT0)取不同的值时的标称

时钟,用户系统中的时钟不要过高,否则可能使操作不稳定。)

#include "reg52.h"

#include "eeprom.h"

//****************** 关闭 ISPIAP 功能 **************

void ISP_IAP_Disable(void)

{

ISP_CONTR = 0x00;

ISP_CMD = 0X00;

ISP_TRIG = 0x00;

EA = 1; //开中断

}

//*******************字节读***************************

uchar Byte_read(uint byte_addr)

{

ISP_CONTR = En_Wait_TIME; //开启ISP/IAP;并送等待时间

ISP_CMD = Read_COM; //送字节读命令字

ISP_ADDRH = (uchar)(byte_addr >>8); //送地址高字节

ISP_ADDRL = (uchar)(byte_addr &0X00FF); //送地址低字节

EA = 0; //关中断

ISP_TRIG = 0X46; //送触发命令字 0X46、0XB9

ISP_TRIG = 0XB9;

_nop_();

ISP_IAP_Disable(); //关闭ISP/IAP功能

EA = 1; //开中断

return ((unsigned char)ISP_DATA);

}

//********************字节编程***********************

void Byte_program(uint byte_addr uchar isp_iap_data)

{

ISP_CONTR = En_Wait_TIME; //开启ISP/IAP;并送等待时间

ISP_CMD = Prog_COM; //送字节编程命令字

ISP_ADDRH = (uchar)(byte_addr >>8); //送地址高字节

ISP_ADDRL = (uchar)(byte_addr &0X00FF); //送地址低字节

ISP_DATA = isp_iap_data; //送数据进ISP_DATA

EA = 0; //关中断

ISP_TRIG = 0X46; //送触发命令字 0X46、0XB9

ISP_TRIG = 0XB9;

_nop_();

ISP_IAP_Disable(); //关闭ISP/IAP功能

EA = 1; //开中断

}

//********************* 扇区擦除*********************

void Sector_erase(uint sector_addr)

{

ISP_CONTR = En_Wait_TIME; //开启ISP/IAP;并送等待时间

// ISP_CONTR=0xc1;

ISP_CMD = Dele_COM; //送扇区擦除命令字

ISP_ADDRH = (uchar)(sector_addr >>8); //送地址高字节

ISP_ADDRL = (uchar)(sector_addr &0X00FF); //送地址低字节

EA = 0; //关中断

ISP_TRIG = 0X46; //送触发命令字 0X46、0XB9

ISP_TRIG = 0XB9;

_nop_();

ISP_IAP_Disable(); //关闭ISP/IAP功能

EA = 1;

}

#ifndef _eeprom_h

#define _eeprom_H

//*********************EEPROM定义命令字节

****************** #define Read_COM 0X01 //字节读数据存储区

#define Prog_COM 0X02 //字节编程数据存储区

#define Dele_COM 0X03 //扇区擦除数据存储区

#define En_Wait_TIME 0X81 //设置等待时间并使能ISP/IAP

//从用户区启动程序

//0X00==40MHZ以下0X01==20MHZ以下

//0X02==10MHZ以下0X03==5MHZ以下现在设置了20MHZ

以下的

//

#define Start_ADDRH 0X20 //扇区地址高位STC89C/LE52RC

#define Start_ADDRL 0X00 //扇区地址低位

#endif

注意了,要写数据时,一定要对该扇区先擦除后写数据的,所以

要写的数据尽量不要多,也可以对不同功能的数据存在不同的扇区里。

如:

Sector_erase(0X2e00); //扇区擦除第八个扇区

Byte_program(0X2e00Eeprom_ReadCode);//写EEPROM保存

可读命令

要读数据时,就直接读就可以了。

ReadData=Byte_read(0X2002);//读取该地址的数据

读一个字节、编程一个字节、擦除一个扇区分别用时10us、60us、

10ms

发布评论

评论列表 (0)

  1. 暂无评论