您的位置:首页 > 其它

内置E2PROM,静态数码管记忆显示

2013-11-23 11:43 176 查看
C89C51、52内部都自带有2K字节的EEPROM,54、55和58都自带有16K字节的EEPROM,STC单片机是利用IAP技术实现的EEPROM,内部Flash擦写次数可达100,000 次以上~

ISP:In System Programable 是指在系统编程,通俗的讲,就是片子已经焊板子上,不用取下,就可以简单而方便地对其进行编程。比如我们通过电脑给STC单片机下载程序,或给AT89S51单片机下载程序,这就是利用了ISP技术。

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

适用于:89C52RC

数码管记忆显示,内置E2PROM

#include <intrins.h>
#include <reg52.h>      //52系列单片机头文件
#define uchar unsigned char
#define uint unsigned int
#define RdCommand 0x01 //定义ISP的操作命令
#define PrgCommand 0x02
#define EraseCommand 0x03
#define Error 1
#define Ok 0
#define WaitTime 0x01 //定义CPU的等待时间
sfr ISP_DATA=0xe2;  //寄存器申明
sfr ISP_ADDRH=0xe3;
sfr ISP_ADDRL=0xe4;
sfr ISP_CMD=0xe5;
sfr ISP_TRIG=0xe6;
sfr ISP_CONTR=0xe7;
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f};
bit flag;
uchar count;
uchar time;
void delay()
{
uint i,j;
for (i=100;i>0;i--)       //i=xms即延时约xms毫秒
for (j=110;j>0;j--);
}
/* ================ 打开 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 char byte_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_DATA);    /* 返回读到的数据 */
}
/* ================== 扇区擦除 ======================== */
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 int byte_addr, unsigned char original_data)
{
ISP_ADDRH = (unsigned char)(byte_addr >> 8);  /* 取地址  */
ISP_ADDRL = (unsigned char)(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 init()
{
TMOD=0x01;
EA=1;
ET0=1;
TR0=1;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
}
void main()
{
init();
time=byte_read(0x2006);
delay();
if (time==15)
{
time=0;
}
while (1)
{

P1=table[time];
if (flag==1)
{
flag=0;
SectorErase(0x2000);
delay();
byte_write(0x2006,time);
delay();
}
}
}

void time0() interrupt 1
{

TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if (count==20)
{
count=0;
time++;
flag=1;
if (time==15)
{
time=0;
}
}
}


芯片手册果然给力!!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: