单片机内部EEPROM的读写原理及驱动程序编写_第1页
单片机内部EEPROM的读写原理及驱动程序编写_第2页
单片机内部EEPROM的读写原理及驱动程序编写_第3页
单片机内部EEPROM的读写原理及驱动程序编写_第4页
单片机内部EEPROM的读写原理及驱动程序编写_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第第页单片机内部EEPROM的读写原理及驱动程序编写

18.1内部E2PROM简介

(单片机)在运行时数据均存储在内部(RAM)(随机存储器)中,在掉电时无法保存数据。前面提到过可以通过增加外部存储器AT24C01(芯片)的方式解决,但因为需要增加外部电路,性价比并不高,因此不(推荐)该方法。STC89C51、52内部都自带有2K字节的E2PROM。可通过对STC单片机内部的E2PROM(编程)来实现,这样节省了片外资源,使用也比较方便。

STC单片机内部的E2PROM并不是真正的E2PROM,而是用DATAFLASH(模拟)出来的,因此操作方法与普通E2PROM不同。STC单片机内部的E2PROM采用的是IAP(在应用编程)技术实现读写操作,擦写次数可达100,000次以上。所谓IAP指程序在运行时程序存储器可有程序本身进行擦写。IAP是相对ISP而言的,下面进行详细的分析。

18.2ISP和IAP区别

ISP:InSystemProgramable是指在系统编程,通俗的讲,就是片子已经焊板子上,不用取下,就可以简单而方便地对其进行编程。比如我们通过(电脑)给STC单片机(下载)程序。

IAP:InAppl(ic)ationProgramable是指在应用编程,就是片子提供一系列的机制((硬件)/软件上的)当片子在运行程序的时候可以提供一种改变存储器数据的方法。通俗点讲,也就是说程序自己可以往程序存储器里写数据或修改程序。这种方式的典型应用就是用一小段代码来实现程序的下载,实际上单片机的ISP功能就是通过IAP技术来实现的,即片子在出厂前就已经有一段小的boot程序在里面,片子上电后,开始运行这段程序,当(检测)到(上位机)有下载要求时,便和上位机(通信),然后下载程序到程序存储区。

以STC89C52为例进行分析,存储空间包括8KBflash程序存储空间、512BRAM数据存储空间、2KBE2PROM存储空间。在51单片机中采用的是数据和程序存储地址空间并行的哈佛结构,地址分配如下所示:

8KBflash地址:0——1FFFH

512BRAM地址:0——0200H

2KBE2PROM地址:2000H——27FFH

ISP操作对象为8KBflash,IAP的操作对象为2KBE2PROM,IAP不能对flash进行读写操作。IAP在读写操作的结果为,将要写入的值与E2PROM中原来的值进行与操作然后将结果存入。例如在地址2000H处第一次成功写入11010110,第二次写入00111010,读出的结果将会是这两个结果的相与0010010,因此如果写入数据前该处数据不为FFH,那么写入的数据将会不正确。IAP的擦除操作的功能就是将数据变为FFH,但擦除操作是以扇区为基本操作单位的,STC89C52的E2PROM扇区地址安排如下表所示。每个扇区的大小为512B。

数据存储操作按照以下步骤进行:

1.写操作之前先将对应扇区的有效数据读取到RAM中暂存(这步不是必须的);

2.对整个扇区进行擦除操作,擦除后该扇区的数据均为FFH;

3.将要写入的字节写入;

4.将暂存的数据写入;

STC单片机IAP程序操作步骤如下:

1.配置ISP_CONTR(寄存器),使能第7位ISPEN,让ISP_IAP功能生效,并配置低三位的等待时间;

2.写指令:读/写/擦除,3个命令;

3.赋值ISP_(AD)DRH和ISP_ADDRL的地址值,分别为所要操作位置的地址高低位;

4.关闭总中断EA,因为下面要写的2个触发指令必须是连续操作;

5.执行ISP_IAP触发指令,触发后才能进行读写;

6.打开总中断EA,关闭ISP_IAP功能,清除相关寄存器。

IAP及E2PROM新增特殊功能寄存器如下图所示:

1.ISP_DATA:ISP/IAP数据寄存器

ISP/IAP操作时的数据存储器,ISP/IAP从Flash读出来的数据存放在此处,向Flash写的数据也需要放在此处。

2.ISP_ADDRH/ISP_ADDRL:ISP/IAP地址寄存器

分别为地址的高、低八位,复位值为0x0000。

3.ISP_CMD:ISP/IAP命令寄存器

MS1MS0=00

待机模式,无数据读写操作;

MS1MS0=01

从应用程序区对”DataFlash/E2PROM区”进行字节读命令

MS1MS0=10

从应用程序区对”DataFlash/E2PROM区”进行字节写命令

MS1MS0=11

从应用程序区对”DataFlash/E2PROM区”进行扇区擦除命令

4.ISP_TRIG:ISP/IAP命令触发寄存器

在ISPEN(ISP_CONTR.7)=1时,对ISP_TRIG先写入0x46,再写入0xB9,ISP/IAP功能才会生效。

5.ISP_CONTR:ISP/IAP控制寄存器

ISPEN:ISP/IAP功能允许位。ISPEN=0,禁止ISP/IAP读、写、擦除操作。ISPEN=1,允许ISP/IAP读、写、擦除操作。

SWBS:0表示,软件从应用程序区启动,1表示,从系统ISP监控程序区启动。需与SW(RS)T配合使用。

SWRST:0不操作,1表示产生软件系统复位,硬件自动复位。

SWBS=1,SWRST=1时,表示在应用程序区软件复位并从系统ISP监控程序区开始执行程序。SWBS=0,SWRST=1时,表示在应用程序区软件复位并从应用程序区开始处执行程序。

B2~B0表示在读、写、擦除操作过程中(CPU)插入的等待时间,推荐选择如下所示。

18.3E2PROM驱动函数编写

前面已经讲解了与内部E2PROM有关的6个寄存器的功能,下面我们结合这些寄存器编写驱动函数,因为在正常的reg52.h中并没有对上述6个特殊功能寄存器进行声明,所以首先得进行声明以及名字字节定义,如下代码所示:

/****************特殊功能寄存器声明****************/sfrISP_DATA=0xE2;sfrISP_ADDRH=0xE3;sfrISP_ADDRL=0xE4;sfrISP_CMD=0xE5;sfrISP_TRIG=0xE6;sfrISP_CONTR=0xE7;/******************定义命令字节******************/#defineread_cmd0x01//读命令#definewirte_cmd0x02//写命令#defineerase_cmd0x03//擦除命令/****定义操作等待时间以及允许IAP操作*******/#defineenable_w(ai)t(Ti)me0x82//系统工作(时钟)接下来两个函数分别为关闭、开启ISP/IAP功能函数,以便后续调用,如下所示:

voidISP_IAP_disable(void)//关闭ISP_IAP{EA=1;//恢复中断ISP_CONTR=0x00;ISP_CMD=0x00;ISP_TRIG=0x00;}voidISP_IAP_trigger()//开启{EA=0;//下面的2条指令必须连续执行,故关中断ISP_TRIG=0x46;//送触发命令字0x46ISP_TRIG=0xB9;//送触发命令字0xB9}如上所示,在开启功能也成为功能触发函数时需要关闭系统中断EA,保证命令字0x46、0xB9被连续写入。单片机对E2PROM的操作包括读、写以及擦除,读数据操作步骤如下所示:

1.清零数据寄存器ISP_DATA,这一步不是必须的;

2.向寄存器ISP_CMD写入读数据命令;

3.允许ISP/IAP,并给出操作等待时间;

4.发送要读取的目标数据的存储地址;

5.开启ISP/IAP功能;

6.读出ISP_DATA中的数据并保存;

7.关闭ISP/IAP功能;

上面讲解的是读取单个字节的步骤,如需读取多个字节的数据只需重复第4到第6步,读数据函数如下所示:

voidISP_IAP_readData(uintbeginAddr,uchar*pBuf,uintdataSize)//读取数据{ISP_DATA=0;//清零,不清也可以ISP_CMD=read_cmd;//指令:读取ISP_CONTR=enable_waitTime;//开启ISP_IAP,并送等待时间while(dataSize--)//循环读取{ISP_ADDRH=(uchar)(beginAddr>>8);//送地址高字节ISP_ADDRL=(uchar)(beginAddr//送地址低字节ISP_IAP_trigger();//触发beginAddr++;//地址++*pBuf++=ISP_DATA;//将数据保存到接收缓冲区}ISP_IAP_disable();//关闭ISP_IAP功能}写数据函数与读数据函数类似,如下所示:

voidISP_IAP_wri(te)Data(uintbeginAddr,uchar*pDat,uintdataSize)//写数据{ISP_CONTR=enable_waitTime;//开启ISP_IAP,并送等待时间ISP_CMD=wirte_cmd;//送字节编程命令字while(dataSize--){ISP_ADDRH=(uchar)(beginAddr>>8);//送地址高字节ISP_ADDRL=(uchar)(beginAddr//送地址低字节ISP_DATA=*pDat++;//送数据beginAddr++;ISP_IAP_trigger();//触发}ISP_IAP_disable();//关闭}擦除扇区函数如下所示:

voidISP_IAP_sectorErase(uintsectorAddr)//扇区擦除{ISP_CONTR=enable_waitTime;//开启ISP_IAP;并送等待时间ISP_CMD=erase_cmd;//送扇区擦除命令字ISP_ADDRH=(uchar)(sectorAddr>>8);//送地址高字节ISP_ADDRL=(uchar)(sectorAddr//送地址低字节ISP_IAP_trigger();//触发ISP_IAP_disable();//关闭ISP_IAP功能}值得注意的是:在擦除扇区函数中,地址只需在该扇区范围内即可,不要求发送该扇区的首地址。到此我们编写完成了所有函数,因此将函整合到完整的驱动代码中。"Drive_Eep(rom).h"代码如下:

#ifndef__Eeprom_H__#define__Eeprom_H__externvoidISP_IAP_disable(void);//关闭ISP_IAPexternvoidISP_IAP_trigger();//触发externvoidISP_IAP_readData(unsignedintbeginAddr,unsignedchar*pBuf,unsignedintdataSize);//读取数据externvoidISP_IAP_writeData(unsignedintbeginAddr,unsignedchar*pDat,unsignedintdataSize);//写数据externvoidISP_IAP_sectorErase(unsignedintsectorAddr);//扇区擦除#endif"Drive_Eeprom.c"代码如下:

#include#defineuintunsignedint#defineucharunsignedchar/****************特殊功能寄存器声明****************/sfrISP_DATA=0xE2;sfrISP_ADDRH=0xE3;sfrISP_ADDRL=0xE4;sfrISP_CMD=0xE5;sfrISP_TRIG=0xE6;sfrISP_CONTR=0xE7;/******************定义命令字节******************/#defineread_cmd0x01//读命令#definewirte_cmd0x02//写命令#defineerase_cmd0x03//擦除命令/****定义操作等待时间以及允许IAP操作*******/#defineenable_waitTime0x82//系统工作时钟>8);//送地址高字节ISP_ADDRL=(uchar)(beginAddr//送地址低字节ISP_IAP_trigger();//触发beginAddr++;//地址++*pBuf++=ISP_DATA;//将数据保存到接收缓冲区}ISP_IAP_disable();//关闭ISP_IAP功能}voidISP_IAP_writeData(uintbeginAddr,uchar*pDat,uintdataSize)//写数据{ISP_CONTR=enable_waitTime;//开启ISP_IAP,并送等待时间ISP_CMD=wirte_cmd;//送字节编程命令字while(dataSize--){ISP_ADDRH=(uchar)(beginAddr>>8);//送地址高字节ISP_ADDRL=(uchar)(beginAddr//送地址低字节ISP_DATA=*pDat++;//送数据beginAddr++;ISP_IAP_trigger();//触发}ISP_IAP_disable();//关闭}voidISP_IAP_sectorErase(uintsectorAddr)//扇区擦除{ISP_CONTR=enable_waitTime;//开启ISP_IAP;并送等待时间ISP_CMD=erase_cmd;//送扇区擦除命令字ISP_ADDRH=(uchar)(sectorAddr>>8);//送地址高字节ISP_ADDRL=(uchar)(sectorAddr//送地址低字节ISP_IAP_trigger();//触发ISP_IAP_disable();//关闭ISP_IAP功能}18.4E2PROM应用

下面我们下一个小的应用程序来验证我们驱动函数,函数实现的功能为记录开发板上电的次数。并把上电的次数,显示到1602液晶显示器上,主函数如下图所示:

#include#include"

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论