51单片机内部EEPROM的应用

合集下载

实验八 51系列单片机IIC

实验八 51系列单片机IIC
8.3 I2C总线器件的寻址方式
I2C总线上的所有器件连接在一个公共的总线上,因此,主器件在进行数据传输前选择需要通信的从器件,即进行总线寻址。 I2C总线上所有外围器件都需要有惟一的地址,由器件地址和引脚地址两部分组成,共7位。器件地址是I2C器件固有的地址编码,器件出厂时就已经给定,不可更改。引脚地址是由I2C总线外围器件的地址引脚(A2,A1,A0)决定,根据其在电路中接电源正极、接地或悬空的不同,形成不同的地址代码。引脚地址数也决定了同一种器件可接入总线的最大数目。 地址位与一个方向位共同构成I2C总线器件寻址字节。寻址字节的格式如表所示。方向位(R/)规定了总线上的主器件与外围器件(从器件)的数据传输送方向。当方向位R/=1,表示主器件读取从器件中的数据;R/=0,表示主器件向从器件发送数据。
从地址中读取一个字节的数据
INT8U read_random(INT8U RomAddress) { INT8U Read_data; I_Start(); I_Write8Bit(WriteDeviceAddress); I_TestAck(); I_Write8Bit(RomAddress); I_TestAck(); I_Start(); I_Write8Bit(ReadDeviceAddress); I_TestAck(); Read_data=I_Read8Bit(); I_NoAck(); I_Stop(); return (Read_data); }
8.4.1 串行EEPROM存储器简介
串行EEPROM存储器是一种采用串行总线的存储器,这类存储器具有体积小、功耗低、允许工作电压范围宽等特点。目前,单片机系统中使用较多的EEPROM芯片是24系列串行EEPROM。其具有型号多、容量大、支持I2C总线协议、占用单片机I/O端口少,芯片扩展方便、读写简单等优点。 目前,Atmel、MicroChip、National等公司均提供各种型号的I2C总线接口的串行EEPROM存储器。下面以Atmel公司的产品为例进行介绍。 AT24C01/02/04/08系列是Atmel公司典型的I2C串行总线的EEPROM。这里以AT24C08为例介绍。AT24C08具有1024×8位的存储容量,工作于从器件模式,可重复擦写100万次,数据可以掉电保存100年。8引脚DIP封装的AT24C08的封装结构,如图所示。

51单片机 原理

51单片机 原理

51单片机原理
51单片机,又称作8051单片机,是一种微控制器,广泛应用
于嵌入式系统中。

它是由英特尔公司在1980年推出的,并成
为了应用最广泛的单片机架构之一。

51单片机采用哈佛架构,具有8位数据总线和16位地址总线。

它内部集成了CPU、RAM、ROM、I/O口等组成部分。

在工
作时,通过外部时钟源供给给单片机提供时钟信号。

CPU是51单片机的核心部件,用于执行程序指令。

51单片机
的指令集支持多种操作,包括算术、逻辑、移位、跳转等。

数据的存储和处理则在RAM中进行,程序的存储则在ROM中。

RAM是51单片机的临时存储器,用于存储程序中的变量和计算结果。

ROM则是只读存储器,用于存储程序指令。

在单片
机启动时,ROM中的程序会被加载到RAM中,并由CPU执行。

I/O口是51单片机与外部设备进行交互的接口。

它可以被配置为输入或输出,用于连接各种传感器、执行器、显示器等外围设备。

通过I/O口,51单片机可以与外部世界进行数据交换和控制。

为了编程和调试51单片机,我们通常使用专用软件和编程器。

这些工具可以将用户编写的程序烧录到51单片机的ROM中,并通过与单片机的通信接口进行通信。

总的来说,51单片机是一种功能强大且应用广泛的微控制器。

它可以用于控制各种嵌入式系统,如家用电器、车辆电子、工业自动化等领域,为我们的生活和工作提供了便利。

三线制Microware同步串行EEPROM在MCS—51单片机上的运用

三线制Microware同步串行EEPROM在MCS—51单片机上的运用
厦 门 大 学机 电工 程 系 扈宏毅 游 龙 翔
Th p ia i n o e Ap l to fEEPROM 、ih M ir wa e S —a l n M CS一5 c v t c o r e lBl o s 1
Si gl -Chi ir c m put r n e- pM co o e
C S
S K DI D O
V CC N C
OR G GN D
E P O 之 间通 信 的 同步 信 号 ,数 据 在 它 的上 升 沿 ER M
锁定有效 ;
D : 据输入 ; I数 D 数据输 出 ; O: O G:Mi ohp公 司 产 品 特 有 引 脚 。 该 引脚 接 R c ci r V c时 ,器 件 的 内部 存 储 组 织 结 构 以 1 位 为 一 个 单 c 6
分 类 号 :P 7 T 23
文 献 标 识 码 : B
文 章 编 号 :0 6—6 7 ( 0 2 0 —0 0 10 9 7 2 0 ) 8 0 9—0 3
1 三 线 制 Mirwae串 行 总 线 co r
三 线 制 Mi o ae同 步 串 行 总线 接 口是 N t n l c wr r ai a o S m cn uo 公 司 在 其 生 产 的 C P系 列 和 H C 系 列 e iod t r O P 微 控 制 器 上 采 用 的 一 种 串行 总线 ,它 使 用 的 三 根 信 号线 分 别 为 数 据 输 入 线 S 、数 据 输 出线 S I 0和 时 钟 信 号线 S K。由 于 三 线 制 Mi o a c wr r e总线 只 需 3 ~4根 数 据 线 和 控 制 线 即 可 扩 展 具 有 三 线 制 Mir ae总 co r w 线 的 各 种 I 0器 件 ,而并 行 总 线 扩 展 方 法 却 需 要 8 / 根 数 据 线 、8~1 6根 地 址 线 和 2~3位 的 控 制 线 ,因

51内部eeprom读写,实现掉电存储

51内部eeprom读写,实现掉电存储

主函数:#include<reg52.h>#include"EEPROM.h"#include"smg.h"void main(){num=byte_read(DEBUG_Data_Memory_Begin_Sector_addr);//字节读(程序开始时读取EEPROM中数据)if(num>=60)num=0;//防止首次上电时读取出错??while(1){if(num<60){display(num);num++;delay(5);delay1(DELAY_CONST);sector_erase(DEBUG_Data_Memory_Begin_Sector_addr);//擦出扇区byte_program (DEBUG_Data_Memory_Begin_Sector_addr,num);//字节编程}if(num==60)num=0;}}EEPROM.h:/*STC89C51RC,STC89LE51RC 0x2000 共八个扇区STC89C52RC,STC89LE52RC 0x2000 共八个扇区STC89C54RD+,STC89LE54RD+ 0x8000 共五十八个扇区STC89C55RD+,STC89LE55RD+ 0x8000 共五十八个扇区STC89C58RD+,STC89LE58RD+ 0x8000 共五十八个扇区*/#include<reg52.h>#include<intrins.h>//sfr定义特殊功能寄存器sfr ISP_DATA =0xe2;//ISP/IAP 操作时的数据寄存器,从Flash 读出的数据放在此处,向Flash 写的数据也需放在此处sfr ISP_ADDRH =0xe3;//ISP/IAP 操作时的地址寄存器高八位sfr ISP_ADDRL =0xe4;//ISP/IAP 操作时的地址寄存器低八位sfr ISP_CMD =0xe5;//ISP/IAP 操作时的命令模式寄存器,须命令触发寄存器触发方可生效sfr ISP_TRIG =0xe6;//ISP/IAP 操作时的命令触发寄存器sfr ISP_CONTR =0xe7;//ISP/IAP 控制寄存器/* 定义命令*/#define uchar unsigned char /*8bit无符号整型*/#define uint unsigned int /*16bit无符号整型*/#define READ_AP_and_Data_Memory_Command 0x01 /*字节读数据存储区*/#define PROGRAM_AP_and_Data_Memory_Command 0x02 /*字节编程数据存储区*/#define SECTOR_ERASE_AP_and_Data_Memory_Command 0x03 /*扇区擦除数据存储*/#define DEBUG_Data_Memory_Begin_Sector_addr 0x2000//扇区地址#define DELAY_CONST 60000//延时#define WAIT_TIME 0x01uchar num;/* 打开ISP,IAP 功能*/void ISP_IAP_enable(void){EA=0;/* 关中断*/ISP_CONTR=ISP_CONTR & 0x18; /* 0001,1000 */ISP_CONTR=ISP_CONTR|WAIT_TIME;ISP_CONTR=ISP_CONTR|0x80; /* 1000,0000 */}/* 关闭ISP,IAP 功能*/void ISP_IAP_disable(void){ISP_CONTR=ISP_CONTR&0x7f;/* 0111,1111 */ISP_TRIG=0x00;EA=1;/* 开中断*/}/* 字节读*/uchar byte_read(uint byte_addr){ISP_ADDRH = (uchar)(byte_addr >> 8);ISP_ADDRL = (uchar)(byte_addr & 0x00ff);ISP_CMD = ISP_CMD&0xf8;/* 1111,1000 */ISP_CMD = ISP_CMD|READ_AP_and_Data_Memory_Command;/* 0000,0001 */ISP_IAP_enable();ISP_TRIG = 0x46;ISP_TRIG = 0xb9;_nop_();ISP_IAP_disable();return (ISP_DATA);}/* 扇区擦除*/void sector_erase(uint sector_addr){uint get_sector_addr=0;get_sector_addr=(sector_addr & 0xfe00); /* 1111,1110,0000,0000; 取扇区地址*/ ISP_ADDRH = (uchar)(get_sector_addr >> 8);ISP_ADDRL = 0x00;ISP_CMD = ISP_CMD&0xf8;/* 1111,1000 */ISP_CMD =ISP_CMD|SECTOR_ERASE_AP_and_Data_Memory_Command;/* 0000,0011 */ ISP_IAP_enable();ISP_TRIG = 0x46;/* 触发ISP_IAP命令*/ISP_TRIG = 0xb9;/* 触发ISP_IAP命令*/_nop_();ISP_IAP_disable();}/* 字节编程*/void byte_program(uint byte_addr, uchar original_data){ISP_ADDRH = (uchar)(byte_addr >> 8);ISP_ADDRL = (uchar)(byte_addr & 0x00ff);ISP_CMD = ISP_CMD & 0xf8; /* 1111,1000 */ISP_CMD = ISP_CMD |PROGRAM_AP_and_Data_Memory_Command; /* 0000,0010 */ISP_DATA = original_data;ISP_IAP_enable();ISP_TRIG = 0x46; /* 触发ISP_IAP命令*/ISP_TRIG = 0xb9; /* 触发ISP_IAP命令*/_nop_();ISP_IAP_disable();}void delay1(uint counter){uint temp=0;for(temp=counter;temp>0;temp--){_nop_();_nop_();_nop_();}}Smg.h:/****************************************************************************** ***** 标题: 试验数码管上显示数字( 单片机直接实现位选共阴极) ** 用573锁存器控制和单片机脚直接位选控制(非译码器控制)数码管******************************************************************************** ****/#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intuchar code smg_duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //段码0-9.uchar code smg_wei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdF,0xbF,0x7F}; //位选控制查表的方法控制void delay(uint i){uchar j;for(i;i>0;i--)for(j=200;j>0;j--);}void display(uint dat)//数码管显示函数{uint i;uint LedOut[10];LedOut[0]=smg_duan[dat%10000/1000];//(若要显示小数点,则|0x80)LedOut[1]=smg_duan[dat%1000/100];LedOut[2]=smg_duan[dat%100/10];LedOut[3]=smg_duan[dat%10];for( i=0; i<4; i++){P0=LedOut[i];P2=smg_wei[i];//使用查表法进行位选delay(10);//扫描间隔时间,数码管每位显示的时间,太长会数码管会有闪烁感}}。

用EEPROM扩展单片机ROM实验

用EEPROM扩展单片机ROM实验

实验九用EEPROM扩展单片机ROM实验一、实验目的1.用EEPROM 27C64扩展51单片机ROM(27C64为外ROM)。

2.用proteus设计、仿真基于AT89C51单片机ROM的扩展实验。

3.借助proteus VSM的虚拟逻辑分析仪,观测单片机访问外ROM(即27C64)时地址、数据和控制总线的信号状态。

二、电路设计1.从PROTEUS库中选取元件①AT89C51.BUS:总线式的单片机;②RES:电阻;③7SEG-BCD- GRN:带BCD译码七段绿光数码管;④CAP、CAP-ELEC:电容、电解电容;⑤CRYSTAL:晶振;⑥74LS373:8D锁存器;⑦27C64:EEPROM存储器。

2.放置元器件3.放置电源和地4.连线5.元器件属性设置6.电气检测三、源程序设计、生成目标代码文件1.流程图2.源程序设计(1)通过菜单“sourc e→Build All”编译汇编源程序,生成目标代码文件。

若编译失败,可对程序进行修改调试直至汇编成功。

(1)加载单片机目标代码文件对AT89C51单片机先右击后左击,打开其属性编辑窗口,在“Program File”栏中添加目标代码文件2764.HEX;在“Clock Frequency”栏中输入晶振频率为120HZ。

(2)加载27C64目标代码文件对2764先右击后左击,打开其属性编辑窗口,在映像文件“Image File”栏中输入外ROM程序的目标代码文件P2764.HEX。

四、PROTEUS仿真1.加载目标代码文件2.仿真单击按钮,启动仿真。

启动仿真后,因单片机的EA脚接电源,从单片机内ROM地址0H开始执行指令LJMP 1000H。

因内ROM的最大地址为0FFFH,而外ROM 27C64的地址从0H到1FFFH,当指令地址大于0FFFH时就自动转到外ROM中去执行程序,所以执行LJMP 1000H是跳转到外ROM 27C64的地址1000H处执行外ROM 27C64中的程序。

51单片机的组成

51单片机的组成

51单片机的组成51单片机的组成51单片机是一种非常普及的单片机,其名字来源于其指令集中的51条指令。

51单片机的组成主要包括芯片内部逻辑设计、存储、外设及与外部器件通信等几个部分。

1. 芯片内部逻辑设计51单片机内部逻辑设计是由微控制器内核、地址总线、数据总线、控制总线、时钟电路等几部分构成的。

微控制器内核是整个51单片机的核心。

它包含一个CPU及其指令集、寄存器、标志寄存器以及一些特殊功能寄存器。

地址总线用于指定程序和数据在存储器中的位置,地址总线的宽度为16位,最大抵达到2^16=65536,即可以对64K的存储空间进行寻址。

数据总线用于CPU与其他器件之间的数据传送,数据总线的宽度为8位,即每次可以传送一个字节大小的数据。

控制总线用于传送指南信号,包括读写控制信号、中断控制信号等。

时钟电路为51单片机提供了一个系统时钟,时钟的频率可以通过输入时钟信号的频率分频器来调节。

2. 存储51单片机中有很多存储器,比如程序存储器(ROM)、数据存储器(RAM)和非易失性存储器(EEPROM)等。

ROM是51单片机存储程序的地方,用于存放CPU指令和程序数据。

ROM一般是只读存储器,无法在运行中写入和修改。

程序存储器的大小为2K到64K。

RAM是51单片机存储数据的地方,用于存放程序运行中的数据、变量和寄存器的值等。

RAM的大小一般在128字节到8K之间,一般只存储运行时的数据。

EEPROM是一种非易失性存储器,用于持久存储用户程序和数据。

EEPROM可以使用电子擦除或编程器写入,而且数据不会因为断电而丢失。

3. 外设51单片机的外设包括IO口、定时器、串口、中断控制器、ADC、DAC等。

它们扩展了51单片机的应用。

IO口(Input Output Port)是外设中最简单也是最常用的一种外设,通过IO口,51单片机可以与外部器件进行交互,比如控制电器或读取传感器的值等。

定时器是一种定时功能外设,可以实现定时、计数和PWM等功能,用于控制系统时间和各种周期性动作。

STC单片机内部EEPROM的应用

STC单片机内部EEPROM的应用

ISP_IAP_enable()?/* 打开IAP 功能*/
for(i=0?i<len?i++)
{
/* 写一个字节*/
ISP_ADDRH=(unsigned char)(in_addr >> 8)?
ISP_TRIG=0xb9?/* 触发ISP_IAP 命令字节2 */
_nop_()?
}
/*
字节读
*/
unsigned char byte_read(unsigned int byte_addr)
{
ISP_ADDRH=(unsigned char)(byte_addr>>8)? /* 地址赋值*/
stc单片机EEPROM读写(一)
EEPROM 操作函数:
#define RdCommand 0x01
#define PrgCommand 0x02
#define EraseCommand 0x03
#define Error 1
#define Ok 0
#define WaitTime 0x01
#define PerSector 512
unsigned char xdata Ttotal[512]?
/*
打开ISP,IAP 功能
*/
void ISP_IAP_enable(void)
D7 D6 D5 D4 D3 D2 D1 D0
ISPEN SWBS SWRST - - WT2 WT1 WT0
启动到ISP 区或用户程序区,这在“STC 单片机自动下载”一节,亦有所应用。
如:
ISP_CONTR=0x60? 则可以实现从用户应用程序区软件复位到ISP 程序区开始运行

常用串行EEPROM的编程应用

常用串行EEPROM的编程应用

常⽤串⾏EEPROM的编程应⽤常⽤串⾏EEPROM的编程应⽤(⼀)作者:温正伟原载:⽆线电本⽂所提供的实例程序:cdle070002.rarEEPROM是"Electrically Erasable Programmable Read-only"(电可擦写可编程只读存储器)的缩写,EEPROM 在正常情况下和EPROM⼀样,可以在掉电的情况下保存数据,所不同的是它可以在特定引脚上施加特定电压或使⽤特定的总线擦写命令就可以在在线的情况下⽅便完成数据的擦除和写⼊,这使EEPROM被⽤于⼴阔的的消费者范围,如:汽车、电信、医疗、⼯业和个⼈计算机相关的市场,主要⽤于存储个⼈数据和配置/调整数据。

EEPROM⼜分并⾏EEPROM和串⾏EEPROM,并⾏EEPROM器件虽然有很快的读写的速度,但要使⽤很多的电路引脚。

串⾏EEPROM器件功能上和并⾏EEPROM基本相同,提供更少的引脚数、更⼩的封装、更低的电压和更低的功耗,是现在使⽤的⾮易失性存储器中灵活性最⾼的类型。

串⾏EEPROM按总线分,常⽤的有I2C,SPI,Microwire总线。

本⽂将介绍这三种总线连接单⽚机的编程⽅法。

I2C总线I2C总线(Inter Integrated Circuit内部集成电路总线)是两线式串⾏总线,仅需要时钟和数据两根线就可以进⾏数据传输,仅需要占⽤微处理器的2个IO引脚,使⽤时⼗分⽅便。

I2C总线还可以在同⼀总线上挂多个器件,每个器件可以有⾃⼰的器件地址,读写操作时需要先发送器件地址,该地址的器件得到确认后便执⾏相应的操作,⽽在同⼀总线上的其它器件不做响应,称之为器件寻址,这个原理就像我们打电话的原理相当。

I2C总线产⽣80年代,由PHLIPS公司开发,早期多⽤于⾳频和视频设备,如今I2C总线的器件和设备已多不胜数。

最常见的采⽤I2C总线的EEPROM也已被⼴泛使⽤于各种家电、⼯业及通信设备中,主要⽤于保存设备所需要的配置数据、采集数据及程序等。

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

用51hei-5板子学习单片机内部EEPROM的应用STC89C51、52内部都自带有2K字节的EEPROM,54、55和58都自带有16K字节的EEPRO M,STC单片机是利用IAP技术实现的EEPROM,内部Flash擦写次数可达100,000 次以上,先来介绍下ISP与IAP的区别和特点。

ISP:In System Programable 是指在系统编程,通俗的讲,就是片子已经焊板子上,不用取下,就可以简单而方便地对其进行编程。

比如我们通过电脑给STC单片机下载程序,或给AT89S51单片机下载程序,这就是利用了ISP技术。

IAP:In Application Programable 是指在应用编程,就是片子提供一系列的机制(硬件/软件上的)当片子在运行程序的时候可以提供一种改变flash数据的方法。

通俗点讲,也就是说程序自己可以往程序存储器里写数据或修改程序。

这种方式的典型应用就是用一小段代码来实现程序的下载,实际上单片机的ISP功能就是通过IAP技术来实现的,即片子在出厂前就已经有一段小的boot程序在里面,片子上电后,开始运行这段程序,当检测到上位机有下载要求时,便和上位机通信,然后下载数据到存储区。

大家要注意千万不要尝试去擦除这段ISP引导程序,否则恐怕以后再也下载不了程序了。

STC单片机内部有几个专门的特殊功能寄存器负责管理ISP/IAP 功能的,见表1。

表1 ISP/IAP相关寄存器列表名称地址功能描述D7D6D5D4D3D2D1D0复位值ISP_DATA E2h Flash数据寄存器11111111ISP_ADDRH E3h Flash高字节地址寄存器0000 0000ISP_ADDRL E4h Flash低字节地址寄存器0000 0000ISP_CMD E5h Flash命令模式寄存器----------MS2MS1MS0xxxx x000ISP_TRIG E6h Flash命令触发寄存器xxxx xxxx ISP_CONTR E7h ISP/IAP 控制寄存器ISPEN SWBS SWRST----WT2WT1WT0000x x000 ISP_DATA:ISP/IAP操作时的数据寄存器。

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

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

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

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

命令模式如表2所示。

表2 ISP_CMD寄存器模式设置D7D6D5D4D3D2D1D0模式选择保留命令选择----------000待机模式,无ISP操作----------001对用户的应用程序flash区及数据flash区字节读----------010对用户的应用程序flash区及数据flash区字节编程----------011对用户的应用程序flash区及数据flash区扇区擦除程序在系统ISP程序区时可以对用户应用程序区/数据Flash区(EEPROM)进行字节读/字节编程/扇区擦除;程序在用户应用程序区时,仅可以对数据Flash区(EEPROM)进行字节读/字节编程/扇区擦除。

STC89C51RC/RD+系列单片机出厂时已经固化有ISP引导码,并设置为上电复位进入I SP程序区,并且出厂时就已完全加密。

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

在ISPEN(ISP_CONTR.7) =1时,对ISP_TRIG 先写入46h,再写入B9h,ISP/IAP命令才会生效。

STC89C52RC,STC89LE52RC单片机内部可用Data Flash(EEPROM)的地址如表3所示,其它型号单片机请查阅相关资料。

表3 STC89C52RC、STC89LE52RC单片机内部EEPROM地址表第一扇区第二扇区第三扇区第四扇区起始地址结束地址起始地址结束地址起始地址结束地址起始地址结束地址2000H21FFH2200H23FFH2400H25FFH2600H27FFH 第五扇区第六扇区第七扇区第八扇区起始地址结束地址起始地址结束地址起始地址结束地址起始地址结束地址2800H29FFH2A00H2BFFH2C00H2DFFH2E00H2FFFH 每个扇区为512字节,建议大家在写程序时,将同一次修改的数据放在同一个扇区,方便修改,因为在执行擦除命令时,一次最少要擦除一个扇区的数据,每次在更新数据前都必须要擦除原数据方可重新写入新数据,不能直接在原来数据基础上更新内容。

下面通过一个例子来讲解STC系列单片机EEPROM的具体用法。

【例】:在实验板上实现如下描述,操作STC单片机自带的EEPROM,存储一组按秒递增的二位数据,并且将数据实时显示在数码管上,数据每变化一次就往EEPROM中写入一次,当关闭实验板电源,再次开启电源时,从EEPROM中读取先前存储的数据,接着递增显示。

#include <intrins.h>#include <reg52.h>//52系列单片机头文件#define uchar unsigned char#define uint unsigned int#define RdCommand 0x01 //定义ISP的操作命令#define PrgCommand 0x02#define EraseCommand0x03#define Error 1#define Ok 0#define WaitTime 0x01 //定义CPU的等待时间sfr ISP_DA TA=0xe2; //寄存器申明sfr ISP_ADDRH=0xe3;sfr ISP_ADDRL=0xe4;sfr ISP_CMD=0xe5;sfr ISP_TRIG=0xe6;sfr ISP_CONTR=0xe7;sbit dula=P2^6; //申明U1锁存器的锁存端sbit wela=P2^7; //申明U2锁存器的锁存端uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};uchar num;void delayms(uint xms){uint i,j;for(i=xms;i>0;i--)//i=xms即延时约xms毫秒for(j=110;j>0;j--);}void display(uchar shi,ucharge) //显示子函数{dula=1;P0=table[shi]; //送十位段选数据dula=0;P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时wela=1; //原来段选数据通过位选锁存器造成混乱P0=0xfe; //送位选数据wela=0;delayms(5); //延时dula=1;P0=table[ge]; //送个位段选数据dula=0;P0=0xff;wela=1;P0=0xfd;wela=0;delayms(5);}/* ================ 打开ISP,IAP 功能================= */void ISP_IAP_enable(void){EA = 0; /* 关中断*/ISP_CONTR =ISP_CONTR & 0x18; /*0001,1000 */ISP_CONTR =ISP_CONTR | WaitTime; /* 写入硬件延时*/ISP_CONTR =ISP_CONTR | 0x80; /*ISPEN=1 */}/* =============== 关闭ISP,IAP 功能================== */void ISP_IAP_disable(void){ISP_CONTR =ISP_CONTR & 0x7f; /* ISPEN =0 */ISP_TRIG = 0x00;EA = 1; /* 开中断*/}/* ================ 公用的触发代码==================== */void ISPgoon(void){ISP_IAP_enable(); /*打开ISP,IAP 功能*/ISP_TRIG = 0x46; /* 触发ISP_IAP命令字节1 */ISP_TRIG = 0xb9; /* 触发ISP_IAP命令字节2 */_nop_();}/*==================== 字节读========================*/unsigned charbyte_read(unsigned int byte_addr) {ISP_ADDRH = (unsigned char)(byte_addr >> 8);/* 地址赋值*/ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);ISP_CMD = ISP_CMD & 0xf8; /* 清除低3位*/ISP_CMD = ISP_CMD | RdCommand; /* 写入读命令*/ ISPgoon(); /* 触发执行*/ISP_IAP_disable(); /* 关闭ISP,IAP功能*/return (ISP_DA TA); /* 返回读到的数据*/}/* ================== 扇区擦除======================== */void SectorErase(unsigned int sector_addr){unsigned int iSectorAddr;iSectorAddr = (sector_addr & 0xfe00); /* 取扇区地址*/ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);ISP_ADDRL = 0x00;ISP_CMD = ISP_CMD & 0xf8; /* 清空低3位*/ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3 */ISPgoon(); /* 触发执行*/ISP_IAP_disable(); /* 关闭ISP,IAP功能*/}/*==================== 字节写========================*/void byte_write(unsigned intbyte_addr, unsigned charoriginal_data){ISP_ADDRH = (unsignedchar)(byte_addr >> 8); /* 取地址*/ISP_ADDRL = (unsignedchar)(byte_addr & 0x00ff);ISP_CMD = ISP_CMD &0xf8; /* 清低3位*/ISP_CMD = ISP_CMD |PrgCommand; /* 写命令2 */ISP_DATA = original_data;/* 写入数据准备*/ISPgoon(); /* 触发执行*/ISP_IAP_disable(); /*关闭IAP功能*/}void main(){uchar a,b,num1;TMOD=0x01; //设置定时器0为工作方式1(0000 0001)TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;num1=byte_read(0x2000);//程序开始时读取EEPROM中数据if(num1>=60) //防止首次上电时读取出错num1=0;while(1){if(num>=20){num=0;num1++;SectorErase(0x2000);//擦除扇区byte_write(0x2000,num1);//重新写入数据if(num1==60){num1=0;}a=num1/10;b=num1%10;}display(a,b);}}void timer0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;num++;}分析:程序中关健部分已经用注释加以说明,请读者编译程序下载后观察实际演示效果。

相关文档
最新文档