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

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;
        }
    }
}

芯片手册果然给力!!!!

你可能感兴趣的:(内置E2PROM,静态数码管记忆显示)