STC89C52MCU --内部EEPROM的应用和内部扩展RAM的应用

来源:互联网 发布:白鲨淘宝店 编辑:程序博客网 时间:2024/04/25 13:44

STC89C52单片机自带4KB的EEPROM,STC单片机是利用IAP技术实现的EEPROM,内部Flash擦写次数可达100 000次以上。

ISP(In System Programable)是指在线编程,通俗来讲,就是在片子已经焊接在板子上,不用取下来,就可以简单而方便的对其尽行编程,比如,我们通过计算机给STC单片机下载程序。

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


STC单片机有几个特殊功能寄存器负责管理ISP/IAP功能


ISP_CMD寄存器设置模式


ISP_DATA: ISP/IAP操作时候的数据寄存器。ISP/IAP从Flash读出的数据放在此处,向Flash写入的数据也放在此处。 

ISP_AFFRH/ADDRL: ISP/IAP操作时的地址寄存器的高低八位

ISP_CMD: ISP/IAP操作时候的命令模式寄存器,须命令触发寄存器触发方可生效,设置模式如上列表。程序在系统ISP程序去时可以可以对用户应用程序区/数据Flash区(EEPROM)进行字节读/扇区擦除/编程;程序在用户程序去时,仅可以对数据Flash区(EEPROG)进行字节读/自己编程/扇区擦除。STC89C51RC/RD+系列单片机出厂时已经固化有ISP引导码,并设置为上电复位进入ISP程序区,并且出厂时就已经加密。

ISP_TRIG:  ISP/IAP操作时的命令触发寄存器。在ISPEN = 1时,对ISP_TRIG 先写入46H,再写入B9H,ISP/IAP 命令才会生效。

STC89C52RC,STC89LE52RC单片机内部可用的Data Flash(EEPROM)的地址如表所示:


每个扇区为512B,建议写程序时,将同一次修改的数据放在同一个扇区,方便修改。因为在执行擦除命令时,一次最少擦除一个扇区的数据,每次更新数据前都必须擦出原来的数据方可重新写入,不能在原来的位置直接更新数据。



内部扩展RAM的应用

RAM在程序运行过程中存放随机变量的数据空间。51单片机默认内部RAM只有128B;52单片机默认256B;STC89C52增加到512B ;

在Keil中编写程序,总程序中所有变量占用的字节数少于128B时候,并且储存模式为small时,对不定义的变量编译器将默认为0;一旦程序中变量总数量超过128B,必须对所有变量进行初始化,否则未被初始化的变量的默认值僵尸不确定的。当变量总和超过128B时候,必须重设定存储器的存储模式。

存储器模式一共有三种,分别为small、large、compact模式。

1.small模式

在small模式中,所有默认变量均装入单片机内部的RAM中,例如:uchar a ; float b等变量时候;;该模式下的优点:访问速度快、缺点是空间有限,且对堆栈的分配比较少,难以把握,碰到递归调用时候需要小心。这种模式只适用于小程序。

2. compact模式

在compact模式中,所有默认变量均位于单片机的256B RAM中,和在small模式中使用关键字 pdata来定义数据变量的效果一样,如 uchar pdata a[100];在该模式下程序总变量空间不能超过256B。 对于只有128B的单片机来说,使用此模式定义超过128B变量数据时,将发生错误。其优点是觉small模式宽裕,速度较small慢,但是比large块,是一种中间状;’

3. large模式

在large模式中,所有默认变量可放在多达64KB的RAM中,包括内部RAM和外部RAM,这和使用关键子xdata 来定义变量的效果一样。该模式的优点是空间大,可存变量多;缺点是:访问速度慢,尤其对于两个以上字节变量访问速度来说更是如此。在large模式下编写程序,定义的变量总数前外不能超过对应单片机的内部最大RAM字节数,因为即使超过了,编译器也不会提示错误,但是程序必然会出错。


ISP/IAP程序例子


#include<intrins.h>

#define WaitTime 0x01

#define RdCommand 0x01

#define PrgCommand 0x02

#define EraseCommand 0x03

sfr ISP_DATA = 0xe2;

sfr ISP_ADDRH = 0xe3;

sfr ISP_ADDRL  = 0xe4;

sfr ISP_CMD = 0xe5;

sfr ISP_TRIG = 0xe6;

sfr ISP_CONTR  = 0xe7;


void ISP_IAP_enable()

{

EA = 1; //关中断

ISP_CONTR = ISP_CONTR & 0x18;//0x 0001 1000

ISP_CONTR = ISP_CONTR | WaitTime;//写入硬件延时

ISP_CONTR = ISP_CONTR | 0x80;//ISPEN = 1;

}


void ISP_IAP_disable()

{

ISP_CONTR = ISP_CONTR & 0x7F;//ISPEN  =0

ISP_TRIG = 0x00;

EA = 0;

}

//公用的触发代码

vois ISPgoon()

{

ISP_IAP _enable();

ISP_TRIG = 0x46;

ISP_TRIG = 0xb9;

_nop_();

}


//字节读取

unsigned chat byte_read(unsigned int byte_arrd)

{

ISP_ADDRH  =(unsigned char)(byte_addr>>8);

ISP_ADDRL = (unsigned char)(byte_addr& 0x00ff);

ISP_CMD = ISP_CMD & 0xf8;//清除低三位

ISP_CMD = ISP_CMD | RdCommand;//写入读命令

ISPgoon(); //触发执行

ISP_IAP_diasble();//关闭ISP,IAP功能

return(ISP_DATA);

}

//扇区擦除

void SectorErase(unsigned int sector_arrd)

{

unsigned int iSectorAddr = (sector_addr & xfe00);


ISP_ADDRH  =(unsigned char)(iSectorAddr >> 8);

ISP_ADDRL = 0x00;

ISP_CMD = ISP_CMD & 0xf8;//清除低三位

ISP_CMD = ISP_CMD | EraseCommand;//写入读命令

ISPgoon(); //触发执行

ISP_IAP_diasble();//关闭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;//清除低三位

ISP_CMD = ISP_CMD | PrgCommand;//写入读命令

ISP_DATA = original_data;

ISPgoon();

ISP_IAP_disable();

}



原创粉丝点击