您的位置 首页 知识

STC单片机EEPROM的使用和程序

最近,由于工作的需要,用STC89C52来开发新产品,要用天STC的Eeprom的功能,上网也找了一点资料,得到很大帮助,真的非常感谢。程序是我在

最近,因为作业的需求,用STC89C52来开发新产品,要用天STC的Eeprom的功用,上网也找了一点材料,得到很大协助,真的非常感谢。程序是我在网上摘抄的,调试通过了,不过我产品在用动态扫描显现的,因为在Eeprom擦除时要用几十毫秒,会有一闪耀的。不过这是正常的。

单片机运转时的数据都存在于RAM(随机存储器)中,在掉电后RAM 中的数据是无
法保存的,那么怎样使数据在掉电后不丢掉呢?这就需求运用EEPROM 或FLASHROM 等
存储器来完成。在传统的单片机体系中,一般是在片外扩展存储器,单片机与存储器之间通
过IIC 或SPI 等接口来进行数据通信。这样不光会添加开发本钱,一起在程序开发上也要花
更多的心思。在STC 单片机中内置了EEPROM(其实是选用IAP 技能读写内部FLASH 来
完成EEPROM),这样就节省了片外资源,运用起来也愈加便利。下面就具体介绍STC 单
片机内置EEPROM 及其运用方法。
STC 各类型单片机内置的EEPROM 的容量各有不同,见下表:
(内部EEPROM 能够擦写100000 次以上)
上面提到了IAP,它的意思是“在运用编程”,即在程序运转时程序存储器可由程序自
身进行擦写。正是是因为有了IAP,然后能够使单片机能够将数据写入到程序存储器中,使
得数据好像烧入的程序相同,掉电不丢掉。当然写入数据的区域与程序存储区要分开来,以
使程序不会遭到损坏。
要运用IAP 功用,与以下几个特别功用寄存器相关:
ISP_DATA: 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_DATA 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”

//****************** 封闭 ISP,IAP 功用 **************
void ISP_IAP_Disable(void)
{
ISP_CONTR = 0x00;
ISP_CMD = 0X00;
ISP_TRIG = 0x00;
EA = 1; //开中止
}

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

ucharByte_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; //开中止
}

//********************* 扇区擦除*********************
voidSector_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_COM0X01//字节读数据存储区
#define Prog_COM0X02//字节编程数据存储区
#define Dele_COM0X03//扇区擦除数据存储区
#define En_Wait_TIME 0X81//设置等候时刻 ,并使能ISP/IAP
//从用户区发动程序
//0X00==40MHZ以下,0X01==20MHZ以下
//0X02==10MHZ以下,0X03==5MHZ以下,现在设置了20MHZ以下的,
//
#define Start_ADDRH0X20 //扇区地址高位,STC89C/LE52RC
#define Start_ADDRL0X00 //扇区地址低位

#endif

留意了,要写数据时,必定要对该扇区先擦除后写数据的,所以要写的数据尽量不要多,也能够对不同功用的数据存在不同的扇区里。如:

Sector_erase(0X2e00);//扇区擦除,第八个扇区
Byte_program(0X2e00,Eeprom_ReadCode);//写EEPROM,保存可读指令

要读数据时,就直接读就能够了。

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

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

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/260545.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部