单片机STC89C52RC 内部EEPROM
STC89C52与有什么区别?
ISP一般需要专用下载器。
STC有内部EEPROM,AT没有。
STC解密相对S52来说要难一点。
批量的话STC价格比S52低。
STC的Datasheet含糊其辞,就像一本广告,很多关键参数都找不到;Atmel
的Datashቤተ መጻሕፍቲ ባይዱet编写详尽且规范。
STC89C52与有什么区别?
STC89C52与AT89C52有什幺区别?
STC89C52RC单片机:
8K字节程序存储空间;
512字节数据存储空间;
内带2K字节EEPROM存储空间;
AT89S52单片机:
8K字节程序存储空间;
256字节数据存储空间;
没有内带EEPROM存储空间;
另外sTC系列的直接用串口下载就可以AT系列的貌似要多装一个驱动
一般认为S52比STC抗干扰差。
初学者如果有串口的话,STC在一定程度上可以降低开发的成本;
如果只有USB的话,用USBASP下载S52更方便一点。
STC89C52RC单片机介绍 (2)
STC89C52RC单片机介绍STC89C52RC单片机是宏晶科技推出的新一代高速/低功耗/超强抗干扰的单片机,指令代码完全兼容传统8051单片机,12时钟/机器周期和6时钟/机器周期可以任意选择。
主要特性如下:1. 增强型8051单片机,6时钟/机器周期和12时钟/机器周期可以任意选择,指令代码完全兼容传统8051.2. 工作电压:5.5V~3.3V(5V单片机)/3.8V~2.0V(3V单片机)3. 工作频率范围:0~40MHz,相当于普通8051的0~80MHz,实际工作频率可达48MHz4. 用户应用程序空间为8K字节5. 片上集成512字节RAM6. 通用I/O口(32个),复位后为:P1/P2/P3/P4是准双向口/弱上拉,P0口是漏极开路输出,作为总线扩展用时,不用加上拉电阻,作为I/O口用时,需加上拉电阻。
7. ISP(在系统可编程)/IAP(在应用可编程),无需专用编程器,无需专用仿真器,可通过串口(RxD/P3.0,TxD/P3.1)直接下载用户程序,数秒即可完成一片8. 具有EEPROM功能9. 具有看门狗功能10. 共3个16位定时器/计数器。
即定时器T0、T1、T211. 外部中断4路,下降沿中断或低电平触发电路,Power Down模式可由外部中断低电平触发中断方式唤醒12. 通用异步串行口(UART),还可用定时器软件实现多个UART13. 工作温度范围:-40~+85℃(工业级)/0~75℃(商业级)14. PDIP封装STC89C52RC单片机的工作模式掉电模式:典型功耗<0.1μA,可由外部中断唤醒,中断返回后,继续执行原程序● 空闲模式:典型功耗2mA● 正常工作模式:典型功耗4Ma~7mA● 掉电模式可由外部中断唤醒,适用于水表、气表等电池供电系统及便携设备STC89C52RC引脚图STC89C52RC引脚功能说明VCC(40引脚):电源电压VSS(20引脚):接地P0端口(P0.0~P0.7,39~32引脚):P0口是一个漏极开路的8位双向I/O 口。
stc8952EEprom
ISPgoon()?/* 触发执行*/
ISP_IAP_disable()?/* 关闭IAP 功能*/
}
/*
字节写并校验
*/
unsigned char byte_write_verify(unsigned int byte_addr, unsigned char
SWRST:0:不操作,1:产生软件系统复位,硬件自动清零。
ISP_CONTR 中的SWBS 与SWRST 这两个功能位,可以实现单片机的软件启动,并
启动到ISP 区或用户程序区,这在“STC 单片机自动下载”一节,亦有所应用。
如:
ISP_CONTR=0x60? 则可以实现从用户应用程序区软件复位到ISP 程序区开始运行
ISP_CMD 0xE5 ISP/IAP闪存命令寄存器MS2
MS1 MS0 xxxxx000
ISP_TRIG 0xE6 ISP/IAP 闪存命令触发xxxxxxxx
ISP_CONTR 0xE7 ISP/IAP 控制寄存器ISPEN SWBS SWRST WT2
WT1 WT0 00xx000
ISP_CMD: ISP/IAP 操作时的命令模式寄存器,须命令触发寄存器触发方可生效。
ISP_TRIG:ISP/IAP 操作时的命令触发寄存器。
当ISPEN(ISP_CONTR.7)=1 时,对ISP_TRIG 先写入0x46,再写入0xb9,ISP/IAP
命令才会生效。
单片机芯片型号起始地址内置EEPROM 容量(每扇区512 字节)
程序。
ISP_CONTR=0x20? 则可以实现从ISP 程序区软件复位到用户应用程序区开始运行
熟悉stc89c5152rc的EEPROM操
这个代码脱离按键部分时,EEPROM的操作是对的,就是在主程序中对EEPROM操作有效,按键部分好像不能控制EEPROM的读擦写。
表现为:按键确认部分是正确的,但是按键按下以后好像一直处于按下状态,不能走后面的程序了。
代码是用T0一秒定时代替按键的防抖。
自己想不出问题出在什么地方了,请大家帮忙给看一下啊。
复制内容到剪贴板代码:
//====================================================================
//目的:熟悉stc89c51/52rc的EEPROM操作
//
//版本日期:09-03-04
sfr ISP_ADDRL = 0xE4; //定义EEPROM地址寄存器的低8位
sfr ISP_CMD = 0xE5; //定义ISP的命令寄存器地址
sfr ISP_TRIG = 0xE6; //定义ISP命令触发寄存器地址
sfr ISP_CONTR = 0xE7; //定义ISP控制寄存器地址
{
uchar Addrh,Addrl;
ISP_CONTR = ENABLE_ISP;
ISP_CMD = ISP_BYTE_PROGRAM;
Addrh = Address >> 8;
Addrl = Address & 0x00ff;
ISP_ADDRH = Addrh;
void IspErase(uint Address)
{
uchar Addrh,Addrl;
ISP_CONTR = ENABLE_ISP;
STC89C52单片机内部EEPROM驱动
}
void main()
{
Sector_erase(0x2000); //扇区擦除
Byte_program(0x2000,0x88); //写EEPROM
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
P0=Byte_read(0x2000); //读EEPROM
ISP_TRIG = 0x46; //送触发命令字0x46
ISP_TRIG = 0xB9; //送触发命令字0xB9
_nop_();
ISP_IAP_disable(); //关闭ISP&IAP功能
EA = 1; Biblioteka /开中断}/*********************扇区擦除*********************/
ISP_CMD = Prog_COM; //送字节编程命令字
ISP_ADDRH = (uchar)(byte_addr >> 8);//送地址高字节
ISP_ADDRL = (uchar)(byte_addr & 0x00ff); //送地址低字节
ISP_DATA = isp_iap_data; //送数据进ISP_DATA
#define Prog_COM 0x02 //字节编程数据命令
#define Erase_COM 0x03 //扇区擦除数据命令
#define En_Wait_TIME 0x81 //设置等待时间,并使能ISP/IAP
#define Start_ADDRH 0x20 //扇区地址高位
#define Start_ADDRL 0x00 //扇区地址低位
stc89c52中EEPROM使用方法
单片机STC89C52RC 内部EEPROM单片机运行时的数据都存在于RAM(随机存储器)中,在掉电后RAM 中的数据是无法保留的,那么怎样使数据在掉电后不丢失呢?这就需要使用EEPROM 或FLASHROM 等存储器来实现。
在传统的单片机系统中,一般是在片外扩展存储器,单片机与存储器之间通过IIC 或SPI 等接口来进行数据通信。
这样不光会增加开发成本,同时在程序开发上也要花更多的心思。
在STC 单片机中内置了EEPROM(其实是采用ISP/IAP 技术读写内部FLASH 来实现EEPROM),这样就节省了片外资源,使用起来也更加方便。
下面就详细介绍STC 单片机内置EEPROM 及其使用方法STC 各型号单片机内置的EEPROM 的容量最小有2K,最大有16K,基本上很好地满足项目的需要,更方便之处就是节省了周边的EEPROM 器件,达到节省成本的目的,而且内部EEPROM 的速度比外部的EEPROM 的速度快很多。
STC 各型号单片机内置的EEPROM 是以512 字节为一个扇区,EEPROM 的起始地址=FALSH 容量值+1,那么STC89C52RC 的起始地址为0x2000,第一扇区的起始地址和结束地址0x2000~0x21FF,第二扇区的起始地址和结束地址0x2200~0x23FF,其他扇区如此类推。
深入重点:�传统的EEPROM 是电可擦可编程只读存储一种掉电后数据不丢失的存储芯片。
�STC89C52RC 的EEPROM 是通过ISP/IAP 技术读写内部FLASH 来实现EEPROM。
�STC89C52RC 的EEPROM 起始地址为0x2000,以512 字节为一个扇区,EERPOM 的大小为2K 字节。
STC89C52RC 与EEPORM 实现的寄存器有6 个,分别是ISP_DATA、ISP_ADDRH、ISP_ADDRLISP_TRIG、ISP_CMD、ISP_CONTR。
STC89C52RC内部EEPROM应用
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
voidclose_isp_iap()
{
ISP_CONTR = 0;//关闭IAP功能
ISP_CMD = 0;//待机模式,无ISP操作
ISP_TRIG = 0;//关闭IAP功能,清与ISP有关的特殊功能寄存器
STC89C52RC内部EEPROM应用
【源码】
/************************************
功能:STC89C52RC EEPROM保存关电前LED的亮灭状况
单片机:STC89C52RC
晶振:11.0592MHz
编译环境:Keil uVision4 V9.00
************************************/
LED1 = 1;
LED2 = 0;//亮第二个灯
}
while(1)
{
if(!K1)
{
while(!K1);
eraser(0x2000);//擦除第1个扇区(2000h~21FFh)
write(0x2002, 1);//对EEPROM区2002h写入1
LED1 = 0;
LED2 = 1;
}
if(!K2)
ISP_ADDRL =addr;
ISP_ADDRH =addr>> 8;
EA = 0;
ISP_TRIG = 0x46;
ISP_TRIG = 0xB9;
_nop_();
dat = ISP_DATA;//取出数据
close_isp_iap();//关闭ISP/IAP
returndat;
stc89c52内部EEPROM连续写入并识别成功
}
void init() //初始化,每次操作EEPROM都要做
{
delay(200); //开始不知道为什么不能读取和写入,后来查书说初始化的时候加200ms延时就好。果然
EA=0;
ISP_CONTR=0X81;
}
void shengxiao()//程序生效。每次程序执行前都要运行
{
ISP_CMD=0X03;
ISP_ADDRL=addr;
ISP_ADDRH=addr>>8;
}
void write(uint addr,uchar dat)//把一个字节数据写入某地址
{
ISP_CMD=0X02;
ISP_ADDRL=addr;
ISP_ADDRH=addr>>8;
shengxiao();
quit();
}
void read(uint addr)//读取某地址的一个字节数据
{
ISP_CMD=0X01;
ISP_ADDRL=addr;
ISP_ADDRH=addr>>8;
shengxiao();
_nop_();
dat=ISP_DATA;
write(table1[t],table2[t]);
shengxiao();
quit();
}
while(1); */
init();
read(0x2003);
shengxiao();
quit();
}
ISP_DATA=dat; //没想到一直没办法写入会是这里的原因我原来为什么非得要ISP_DATA&dat呢?没道理呀!成功!原来第二次写入的时候里面的数变成第一次写入的数了,然后第二次写入的数与第一次写入的数相与,全为0.如第一次写入00000001第二次写入00000010,那么相与就成了00000000.这就是为什么会是全0的原因。
stc89le52rc内部EEPROM的C51读写程序
stc89le52rc内部EEPROM的C51读写程序/*stc89le52rc内部EEPROM的C51读写程序串口命令(9600)1.0x35可以写eeprom第一个字节数据0x0c2.0x34可以使用检查eeprom第一个字节的数据,正确就会反馈一串字符3.0x33可以读取eeprom前256个字节数据*/#include<math.h>#include<stdio.h>#include<reg52.h>#include <intrins.h>#define NOP5 _nop_();_nop_();_nop_(); _nop_();_nop_();#define uchar unsigned char#define uint unsigned intsfr AUXR = 0x8e;sfr AUXR1 = 0xa2;sfr P4 = 0xe8;sfr XICON = 0xc0;sfr IPH = 0xb7;sfr WDT_CONTR = 0xe1;sfr ISP_DATA = 0xe2;sfr ISP_ADDRH = 0xe3;sfr ISP_ADDRL = 0xe4;sfr ISP_CMD = 0xe5;sfr ISP_TRIG = 0xe6;sfr ISP_CONTR = 0xe7;#define ENABLE_ISP 0x81 //小于20MHZ使用#define DATA_FLASH_START_ADDR 0x2000//stc89le52rc eeprom起始地址#define TEST_CODE 0x34uchar code start_string[]={"EEPROM first data correct!\n"}; uint i=0,k;uchar EEPROM_READ(uint flash_addres);void IAP_disable();void EEPROM_FORMAT(uint flash_addres);void EEPROM_WRITE(uint flash_addres, isp_data);void test_read();void send_byte(uchar bt);void send_string(uchar *ptr, uchar len);void read_string(uint start_addr,uint num);void read_string(uint start_addr, uint num)static uint j,temp;for(j=0;j<num;j++){temp=EEPROM_READ(start_addr+j);NOP5;send_byte(temp);}}void send_string(uchar * ptr, uchar len) {static uint j;for(j=0;j<len;j++){send_byte(*(ptr+j));}}void send_byte(uchar by){SBUF=by;while(!TI);TI=0;void IAP_disable(){ISP_CONTR=0;ISP_CMD=0;ISP_TRIG=0;}uchar EEPROM_READ(uint flash_addres) //读取数据{uchar read;ISP_ADDRH=flash_addres>>8;ISP_ADDRL=flash_addres;ISP_CONTR=ENABLE_ISP;ISP_CMD=0x01 ;EA=0;ISP_TRIG=0x46;ISP_TRIG=0xb9 ;NOP5;read=ISP_DATA;IAP_disable();EA=1;return(ISP_DATA);void EEPROM_WRITE(uint flash_addres,isp_data) //写入数据{ISP_ADDRH=flash_addres>>8;ISP_ADDRL=flash_addres;ISP_CONTR=ENABLE_ISP;ISP_CMD=0x02 ;EA=0;ISP_DATA=isp_data;ISP_TRIG=0x46;ISP_TRIG=0xb9;IAP_disable();EA=1;}void EEPROM_FORMAT(uint flash_addres) //擦除{ISP_ADDRH=flash_addres>>8;ISP_ADDRL=flash_addres;ISP_CONTR=ENABLE_ISP;ISP_CMD=0x03;EA=0;ISP_TRIG=0x46;ISP_TRIG=0xb9;IAP_disable();EA=1;}void test_read(){if(RI){RI=0;switch(SBUF){case 0x34:k=EEPROM_READ(DATA_FLASH_START_ADDR);NOP5;if(0x0c==k){send_string(start_string,sizeof(start_string));}send_byte(k);k=0;break;case 0x33:read_string(DATA_FLASH_START_ADDR, 256);break;case 0x35:EEPROM_FORMAT(DATA_FLASH_START_ADDR); //写已经有数据的扇区前要写擦除NOP5;NOP5;NOP5; //可以适当增减延时NOP5;NOP5;NOP5;NOP5;EEPROM_WRITE(DATA_FLASH_START_ADDR,TEST_CO DE);//写一个0x0cbreak;default:if(0xff==i){i=0;}k=EEPROM_READ(DATA_FLASH_START_ADDR+(i++));send_byte(DATA_FLASH_START_ADDR+i);send_byte(k);k=0;break;}}}void init(){TMOD=0x20;SCON=0x50;TL1=0xfd;TH1=0xfd;TR1=1;ET1=1;ES=1;}void main(){init();while(1){test_read();}}。
STC89C52内部EEPROM
单片机运行时的数据都存在于RAM(随机存储器)中,在掉电后RAM 中的数据是无法保留的,那么怎样使数据在掉电后不丢失呢?这就需要使用EEPROM 或FLASHROM 等存储器来实现。
在传统的单片机系统中,一般是在片外扩展存储器,单片机与存储器之间通过IIC 或SPI 等接口来进行数据通信。
这样不光会增加开发成本,同时在程序开发上也要花更多的心思。
在STC 单片机中内置了EEPROM(其实是采用IAP 技术读写内部FLASH 来实现EEPROM),这样就节省了片外资源,使用起来也更加方便。
下面就详细介绍STC 单片机内置EEPROM 及其使用方法。
STC 各型号单片机内置的EEPROM 的容量各有不同,见下表:(内部EEPROM 可以擦写100000 次以上)上面提到了IAP,它的意思是“在应用编程”,即在程序运行时程序存储器可由程序自身进行擦写。
正是是因为有了IAP,从而可以使单片机可以将数据写入到程序存储器中,使得数据如同烧入的程序一样,掉电不丢失。
当然写入数据的区域与程序存储区要分开来,以使程序不会遭到破坏。
要使用IAP 功能,与以下几个特殊功能寄存器相关:ISP_DATA:ISP/IAP 操作时的数据寄存器。
ISP/IAP 从Flash 读出的数据放在此处,向Flash 写的数据也需放在此处ISP_ADDRH:ISP/IAP 操作时的地址寄存器高八位。
ISP_ADDRL:ISP/IAP 操作时的地址寄存器低八位。
ISP_CMD:ISP/IAP 操作时的命令模式寄存器,须命令触发寄存器触发方可生效。
ISP_TRIG:ISP/IAP 操作时的命令触发寄存器。
当ISPEN(ISP_CONTR.7)=1 时,对ISP_TRIG 先写入0x46,再写入0xb9,ISP/IAP 命令才会生效。
单片机芯片型号起始地址内置EEPROM 容量(每扇区512 字节)STC89C51RC,STC89LE51RC 0x2000 共八个扇区STC89C52RC,STC89LE52RC 0x2000 共八个扇区STC89C54RD+,STC89LE54RD+ 0x8000 共五十八个扇区STC89C55RD+,STC89LE55RD+ 0x8000 共五十八个扇区STC89C58RD+,STC89LE58RD+ 0x8000 共五十八个扇区寄存器标识地址名称7 6 5 4 3 2 1 0 初始值ISP_DATA 0xE2 ISP/IAP闪存数据寄存器11111111ISP_ADDRH 0xE3 ISP/IAP 闪存地址高位00000000ISP_ADDRL 0xE4 ISP/IAP 闪存地址低位00000000ISP_CMD 0xE5 ISP/IAP闪存命令寄存器MS2MS1 MS0 xxxxx000ISP_TRIG 0xE6 ISP/IAP 闪存命令触发xxxxxxxxISP_CONTR 0xE7 ISP/IAP 控制寄存器ISPEN SWBS SWRST WT2WT1 WT0 00xx000B7 B6 B5 B4 B3 B2 B1 B0 命令/操作模式选择保留命令选择-----0 0 0 待机模式,无ISP/IAP 操作-----0 0 1 对用户的应用程序Flash 区及数据Flash 区字节读-----0 1 0 对用户的应用程序Flash 区及数据Flash 区字节编程-----0 1 1 对用户的应用程序Flash 区及数据Flash 区扇区擦除ISP_CONTR:ISP/IAP 控制寄存器。
stc89c52单片机技术资料
stc89c52单片机技术资料STC89C52RC单片机是一款由XXX推出的新一代高速、低功耗、超强抗干扰单片机。
该单片机的指令代码完全兼容传统的8051单片机,同时12时钟/机器周期和6时钟/机器周期可以任意选择。
主要特性包括:增强型8051单片机,指令代码完全兼容传统8051,6时钟/机器周期和12时钟/机器周期可以任意选择。
工作电压范围为5.5V~3.3V(5V单片机)/3.8V~2.0V(3V单片机),工作频率范围为~40MHz,实际工作频率可达48MHz。
用户应用程序空间为8K字节,片上集成512字节RAM,通用I/O口有32个。
具有ISP(在系统可编程)/IAP(在应用可编程)功能,无需专用编程器和仿真器,可通过串口直接下载用户程序。
具有EEPROM功能和看门狗功能,共3个16位定时器/计数器,外部中断4路。
通用异步串行口(UART),还可用定时器软件实现多个UART。
工作温度范围为-40~+85℃(工业级)/0~75℃(商业级),PDIP封装。
STC89C52RC单片机的工作模式包括掉电模式、空闲模式和正常工作模式。
其中,掉电模式的典型功耗小于0.1μA,可由外部中断唤醒,中断返回后继续执行原程序。
空闲模式的典型功耗为2mA,正常工作模式的典型功耗为4Ma~7mA。
掉电模式适用于水表、气表等电池供电系统和便携设备。
STC89C52RC单片机引脚图如下所示,其中VCC为电源电压,VSS为接地,P0端口为一个漏极开路的8位双向I/O 口,可作为输出端口和复用总线。
在Flash ROM编程时,P0端口接收指令字节。
除了定时器/计数器和定时器/计数器1,STC89C52RC还新增了定时器/计数器2.定时器/计数器2的控制和状态位位于T2CON表格中。
定时器2是一个16位定时/计数器,可以通过特殊功能寄存器T2CON中的C/T2位设置为定时器或计数器。
定时器2有三种操作模式:捕获、自动重新装载(递增或递减计数)和波特率发生器,这三种模式由T2CON中的位进行选择。
stc89c52rc单片机结构
stc89c52rc单片机结构STC89C52RC单片机是一种高性能、低功耗的8位单片机,它是由STC公司推出的一款单片机。
其特点是有ISP(In-System Programming)在线编程功能,可以不用拆下芯片,就能使用ISP编程器进行在线编程,提高了单片机的使用效率。
下面就分步骤来阐述STC89C52RC单片机的结构。
第一步,CPU结构STC89C52RC单片机的CPU结构是基于哈佛结构的,其中包括AUC (程序地址计数器)、程序存储器ROM、数据存储器RAM、存储器控制器、总线控制器等部分。
其中AUC具有16位地址,可以寻址的最大空间是64K字节,程序存储器ROM和数据存储器RAM都可以扩展。
第二步,I/O口结构该单片机的I/O口结构包括32个外部I/O口和8个内部I/O口,其中外部I/O口可以连接外部LED、晶振、按键等外设,内部I/O口是可复用的,可以连接CMOS输出器等。
第三步,时钟和定时器的结构STC89C52RC单片机采用了12MHz的晶振,提供了三个定时器,其中Timer0和Timer1是16位定时器/计数器。
Timer2是8位的定时器/计数器,同时还有一个定时器0的16位增量计数器TMOD。
第四步,中断系统结构STC89C52RC单片机的中断系统结构采用了可编程中断控制器(PIC)。
理论最大的中断来源可以达到32个。
同时,该单片机还有5个中断优先级,可以分别分配不同的优先级,以便按照用户优先级来控制中断服务。
第五步,ISP编程结构该单片机的ISP编程结构采用了串行通讯口SI0,除了可以进行在线编程外,还可以通过ISP编程器实现单片机的测试和校验。
综上所述,STC89C52RC单片机结构包括CPU结构、I/O口结构、时钟和定时器的结构、中断系统结构和ISP编程结构。
其具有低功耗、高性能、编程效率高等特点,被广泛应用于计算机辅助设计、智能控制、电子电路自动化等领域。
连续读写STC89C52RC内部EEPROM存储器
STC单片机的内部EEPROM是用DATAFLASH模拟出来的,不是真正的EEPROM存储器,不能用普通的方法来操作下面是一些注意点:1.字节写之前要先将这个字节所在扇区的其它有效数据读取到RAM暂存(这步不是必须的)2.暂存完之后再对整个扇区(512字节)进行擦除操作,擦拭完后,整个扇区每个地址中数据都变成0xFF3.将欲写入的N个字节数据,用字节写函数写入EEPROM4.将暂存到RAM的其它有用的EEPROM值再用字节写函数写回EEPROM5.STC用FLASH模拟出来的EEPROM的字节写功能只能将1变成0,而不能将0变成1,只有扇区擦除后数据才是全1,例如:在地址0x21f0处第1次写11010110,第2次写111010,读出结果是这2个值的相与10010所以如果一个地址处的值不是0xff时写入新的数据是不对的,要先执行扇区擦除,变为0xff,对于单个字节的写入,我们可以先检查该地址处的数据是否为0xff,是的话就不用擦除扇区了----------------------------------------------------------------------STC89C52单片机内部EEPROM 的读写过程1 配置ISP_CONTR寄存器,使能第7位ISPEN,让ISP_IAP功能生效,并配置低3位的等待时间2 写指令: 读/写/擦除扇区这3个命令3 赋值: ISP_ADDRH和ISP_ADDRL的地址值4 关闭总中断EA,因为下面要写的2个触发指令必须是连续操作的,不能被中断5 执行公用的ISP_IAP 触发指令,触发后读写操作才能进行6 打开中断EA, 关闭ISP_IAP功能:清相关寄存器#include "my51.h"/******************定义命令字节******************/#define read_cmd 0x01 //字节读数据命令#define wirte_cmd 0x02 //字节编程数据命令#define erase_cmd 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;/*定义Flash 操作等待时间及允许IAP/ISP/EEPROM 操作的常数******************///#define enable_waitTime 0x80 //系统工作时钟<30MHz 时,对IAP_CONTR 寄存器设置此值//#define enable_waitTime 0x81 //系统工作时钟<24MHz 时,对IAP_CONTR 寄存器设置此值//#define enable_waitTime 0x82 //系统工作时钟<20MHz 时,对IAP_CONTR 寄存器设置此值#define enable_waitTime 0x83 //系统工作时钟<12MHz 时,对IAP_CONTR 寄存器设置此值//#define enable_waitTime 0x84 //系统工作时钟<6MHz 时,对IAP_CONTR 寄存器设置此值void ISP_IAP_disable(void) //关闭ISP_IAP{EA=1; //恢复中断ISP_CONTR = 0x00;ISP_CMD = 0x00;ISP_TRIG = 0x00;}void ISP_IAP_trigger() //触发{EA=0; //下面的2条指令必须连续执行,故关中断ISP_TRIG = 0x46; //送触发命令字0x46ISP_TRIG = 0xB9; //送触发命令字0xB9}void ISP_IAP_readData(u16 beginAddr, u8* pBuf, u16 dataSize) //读取数据{ISP_DATA=0; //清零,不清也可以ISP_CMD = read_cmd; //指令:读取ISP_CONTR = enable_waitTime; //开启ISP_IAP,并送等待时间while(dataSize--) //循环读取{ISP_ADDRH = (u8)(beginAddr >> 8); //送地址高字节ISP_ADDRL = (u8)(beginAddr & 0x00ff); //送地址低字节ISP_IAP_trigger(); //触发beginAddr++; //地址++*pBuf++ = ISP_DATA; //将数据保存到接收缓冲区}ISP_IAP_disable(); //关闭ISP_IAP功能}void ISP_IAP_writeData(u16 beginAddr,u8* pDat,u16 dataSize) //写数据{ISP_CONTR = enable_waitTime; //开启ISP_IAP,并送等待时间ISP_CMD = wirte_cmd; //送字节编程命令字while(dataSize--){ISP_ADDRH = (u8)(beginAddr >> 8); //送地址高字节ISP_ADDRL = (u8)(beginAddr & 0x00ff); //送地址低字节ISP_DATA = *pDat++; //送数据beginAddr++;ISP_IAP_trigger(); //触发}ISP_IAP_disable(); //关闭}void ISP_IAP_sectorErase(u16 sectorAddr) //扇区擦除{ISP_CONTR = enable_waitTime; //开启ISP_IAP;并送等待时间ISP_CMD = erase_cmd; //送扇区擦除命令字ISP_ADDRH = (u8)(sectorAddr >> 8); //送地址高字节ISP_ADDRL = (u8)(sectorAddr & 0X00FF); //送地址低字节ISP_IAP_trigger(); //触发ISP_IAP_disable(); //关闭ISP_IAP功能}void main() //测试{u8 buf[3]={0}; //接收数据缓冲区u8 dat[5]={b(111010),b(1001),b(1),b(1011),b(1110)};//我写成二进制是为观察led灯ISP_IAP_sectorErase(0x2000); //扇区擦除,一块512字节ISP_IAP_writeData(0x21f0,dat,sizeof(dat)); //写EEPROMISP_IAP_readData(0x21f0,buf,sizeof(buf)); //读取P1=buf[2];//在地址0x21f0处第1次写11010110,第2次写111010,读出结果是这2个值的相与10010while(1); //所以如果一个地址处的值不是0xff时写入新的数据是不对的,要先擦除为0xff }#ifndef _MY51_H#define _MY51_H#include <reg52.h>//#include <math.h>#include <intrins.h>#include <stdio.h>#include "mytype.h"/*************二进制输入宏****************************/ #ifndef _LongToBin_#define _LongToBin_#define LongToBin(n) \( \((n >> 21) & 0x80) | \((n >> 18) & 0x40) | \((n >> 15) & 0x20) | \((n >> 12) & 0x10) | \((n >> 9) & 0x08) | \((n >> 6) & 0x04) | \((n >> 3) & 0x02) | \((n ) & 0x01) \)#define bin(n) LongToBin(0x##n##l)#define BIN(n) bin(n)#define B(n) bin(n)#define b(n) bin(n)#endif/*************单个数据位的置位宏*********************/ #ifndef _BIT_#define _BIT_#define BIT(n) (1<<n)#define bit(n) BIT(n)#endif#define high 1 //高电平#define low 0 //低电平#define led P1 //灯总线控制sbit led0=P1^0; //8个led灯,阴极送低电平点亮sbit led1=P1^1;sbit led2=P1^2;sbit led3=P1^3;sbit led4=P1^4;sbit led5=P1^5;sbit led6=P1^6;sbit led7=P1^7;sbit ledLock=P2^5; //led锁存的状态,0锁定,1不锁定sbit beep=P2^3; //蜂鸣器void delayms(u16 ms);//void delayXus(u8 us); //函数执行(8+6x)个机器周期, 即t=(8+6x)*1.085 /////////////////////////////////////////////////////////////////////////////#endif。
stc89le52rc内部EEPROM的C51读写程序
stc89le52rc内部EEPROM的C51读写程序/*stc89le52rc内部EEPROM的C51读写程序串口命令(9600)1.0x35可以写eeprom第一个字节数据0x0c2.0x34可以使用检查eeprom第一个字节的数据,正确就会反馈一串字符3.0x33可以读取eeprom前256个字节数据*/#include<math.h>#include<stdio.h>#include<reg52.h>#include <intrins.h>#define NOP5 _nop_();_nop_();_nop_(); _nop_();_nop_();#define uchar unsigned char#define uint unsigned intsfr AUXR = 0x8e;sfr AUXR1 = 0xa2;sfr P4 = 0xe8;sfr XICON = 0xc0;sfr IPH = 0xb7;sfr WDT_CONTR = 0xe1;sfr ISP_DATA = 0xe2;sfr ISP_ADDRH = 0xe3;sfr ISP_ADDRL = 0xe4;sfr ISP_CMD = 0xe5;sfr ISP_TRIG = 0xe6;sfr ISP_CONTR = 0xe7;#define ENABLE_ISP 0x81 //小于20MHZ使用#define DATA_FLASH_START_ADDR 0x2000//stc89le52rc eeprom起始地址#define TEST_CODE 0x34uchar code start_string[]={"EEPROM first data correct!\n"};uint i=0,k;uchar EEPROM_READ(uint flash_addres);void IAP_disable();void EEPROM_FORMAT(uint flash_addres);void EEPROM_WRITE(uint flash_addres, isp_data);void test_read();void send_byte(uchar bt);void send_string(uchar *ptr, uchar len);void read_string(uint start_addr,uint num);void read_string(uint start_addr, uint num){static uint j,temp;for(j=0;j<num;j++){temp=EEPROM_READ(start_addr+j);NOP5;send_byte(temp);}}void send_string(uchar * ptr, uchar len){static uint j;for(j=0;j<len;j++){send_byte(*(ptr+j));}void send_byte(uchar by){SBUF=by;while(!TI);TI=0;}void IAP_disable(){ISP_CONTR=0;ISP_CMD=0;ISP_TRIG=0;}uchar EEPROM_READ(uint flash_addres) //读取数据{uchar read;ISP_ADDRH=flash_addres>>8;ISP_ADDRL=flash_addres;ISP_CONTR=ENABLE_ISP;ISP_CMD=0x01 ;EA=0;ISP_TRIG=0x46;ISP_TRIG=0xb9 ;NOP5;read=ISP_DATA;IAP_disable();EA=1;return(ISP_DATA);}void EEPROM_WRITE(uint flash_addres,isp_data) //写入数据ISP_ADDRH=flash_addres>>8;ISP_ADDRL=flash_addres;ISP_CONTR=ENABLE_ISP;ISP_CMD=0x02 ;EA=0;ISP_DATA=isp_data;ISP_TRIG=0x46;ISP_TRIG=0xb9;IAP_disable();EA=1;}void EEPROM_FORMAT(uint flash_addres) //擦除{ISP_ADDRH=flash_addres>>8;ISP_ADDRL=flash_addres;ISP_CONTR=ENABLE_ISP;ISP_CMD=0x03;EA=0;ISP_TRIG=0x46;ISP_TRIG=0xb9;IAP_disable();EA=1;}void test_read(){if(RI){RI=0;switch(SBUF)case 0x34:k=EEPROM_READ(DATA_FLASH_START_ADDR);NOP5;if(0x0c==k){send_string(start_string,sizeof(start_string));}send_byte(k);k=0;break;case 0x33:read_string(DATA_FLASH_START_ADDR, 256);break;case 0x35:EEPROM_FORMAT(DATA_FLASH_START_ADDR); //写已经有数据的扇区前要写擦除NOP5;NOP5;NOP5; //可以适当增减延时NOP5;NOP5;NOP5;NOP5;EEPROM_WRITE(DATA_FLASH_START_ADDR,TEST_CODE);//写一个0x0cbreak;default:if(0xff==i)i=0;}k=EEPROM_READ(DATA_FLASH_START_ADDR+(i++)); send_byte(DATA_FLASH_START_ADDR+i);send_byte(k);k=0;break;}}}void init(){TMOD=0x20;SCON=0x50;TL1=0xfd;TH1=0xfd;TR1=1;ET1=1;ES=1;}void main(){init();while(1){test_read();}}。
STC89C52内部EEPROM
STC89C52内部EEPROM单片机运行时的数据都存在于RAM(随机存储器)中,在掉电后RAM 中的数据是无法保留的,那么怎样使数据在掉电后不丢失呢?这就需要使用EEPROM 或FLASHROM 等存储器来实现。
在传统的单片机系统中,一般是在片外扩展存储器,单片机与存储器之间通过IIC 或SPI 等接口来进行数据通信。
这样不光会增加开发成本,同时在程序开发上也要花更多的心思。
在STC 单片机中内置了EEPROM(其实是采用IAP 技术读写内部FLASH 来实现EEPROM),这样就节省了片外资源,使用起来也更加方便。
下面就详细介绍STC 单片机内置EEPROM 及其使用方法。
STC 各型号单片机内置的EEPROM 的容量各有不同,见下表:(内部EEPROM 可以擦写100000 次以上)上面提到了IAP,它的意思是“在应用编程”,即在程序运行时程序存储器可由程序自身进行擦写。
正是是因为有了IAP,从而可以使单片机可以将数据写入到程序存储器中,使得数据如同烧入的程序一样,掉电不丢失。
当然写入数据的区域与程序存储区要分开来,以使程序不会遭到破坏。
要使用IAP 功能,与以下几个特殊功能寄存器相关:ISP_DA T A:ISP/IAP 操作时的数据寄存器。
ISP/IAP 从Flash 读出的数据放在此处,向Flash 写的数据也需放在此处ISP_ADDRH:ISP/IAP 操作时的地址寄存器高八位。
ISP_ADDRL:ISP/IAP 操作时的地址寄存器低八位。
ISP_CMD:ISP/IAP 操作时的命令模式寄存器,须命令触发寄存器触发方可生效。
ISP_TRIG:ISP/IAP 操作时的命令触发寄存器。
当ISPEN(ISP_CONTR.7)=1 时,对ISP_TRIG先写入0x46,再写入0xb9,ISP/IAP 命令才会生效。
单片机芯片型号起始地址内置EEPROM 容量(每扇区512 字节)STC89C51RC,STC89LE51RC 0x2000 共八个扇区STC89C52RC,STC89LE52RC 0x2000 共八个扇区STC89C54RD+,STC89LE54RD+ 0x8000 共五十八个扇区STC89C55RD+,STC89LE55RD+ 0x8000 共五十八个扇区STC89C58RD+,STC89LE58RD+ 0x8000 共五十八个扇区寄存器标识地址名称7 6 5 4 3 2 1 0 初始值ISP_DA TA 0xE2 ISP/IAP闪存数据寄存器11111111ISP_ADDRH 0xE3 ISP/IAP 闪存地址高位00000000ISP_ADDRL 0xE4 ISP/IAP 闪存地址低位00000000ISP_CMD 0xE5 ISP/IAP闪存命令寄存器MS2MS1 MS0 xxxxx000ISP_TRIG 0xE6 ISP/IAP 闪存命令触发xxxxxxxxISP_CONTR 0xE7 ISP/IAP 控制寄存器ISPEN SWBS SWRST WT2WT1 WT0 00xx000B7 B6 B5 B4 B3 B2 B1 B0 命令/操作模式选择保留命令选择-----0 0 0 待机模式,无ISP/IAP 操作-----0 0 1 对用户的应用程序Flash 区及数据Flash 区字节读-----0 1 0 对用户的应用程序Flash 区及数据Flash 区字节编程-----0 1 1 对用户的应用程序Flash 区及数据Flash 区扇区擦除ISP_CONTR:ISP/IAP 控制寄存器。
STC89C52单片机内部EEPROM保存数据的应用例子程序
STC89C52单片机内部EEPROM保存数据的应用例子程序STC89C51、52内部都自带有2K字节的EEPROM,54、55和58都自带有16K字节的EEPROM,STC单片机是利用IAP技术实现的EEPROM,内部Flash擦写次数可达100,000 次以上,先来介绍下ISP与IAP的区别和特点。
知识点:ISP与IAP介绍ISP:In System Programable 是指在系统编程,通俗的讲,就是片子已经焊板子上,不用取下,就可以简单而方便地对其进行编程。
比如我们通过电脑给STC单片机下载程序,或给AT89S51单片机下载程序,这就是利用了ISP技术。
IAP:In Application Programable 是指在应用编程,就是片子提供一系列的机制(硬件/软件上的)当片子在运行程序的时候可以提供一种改变flash数据的方法。
通俗点讲,也就是说程序自己可以往程序存储器里写数据或修改程序。
这种方式的典型应用就是用一小段代码来实现程序的下载,实际上单片机的ISP功能就是通过IAP技术来实现的,即片子在出厂前就已经有一段小的boot程序在里面,片子上电后,开始运行这段程序,当检测到上位机有下载要求时,便和上位机通信,然后下载数据到存储区。
大家要注意千万不要尝试去擦除这段ISP引导程序,否则恐怕以后再也下载不了程序了。
STC单片机内部有几个专门的特殊功能寄存器负责管理ISP/IAP功能的,见表1。
每个扇区为512字节,建议大家在写程序时,将同一次修改的数据放在同一个扇区,方便修改,因为在执行擦除命令时,一次最少要擦除一个扇区的数据,每次在更新数据前都必须要擦除原数据方可重新写入新数据,不能直接在原来数据基础上更新内容。
下面通过一个例子来讲解STC系列单片机EEPROM的具体用法。
【例】:在TX-1C实验板上实现如下描述,操作STC单片机自带的EEPROM,存储一组按秒递增的二位数据,并且将数据实时显示在数码管上,数据每变化一次就往EEPROM中写入一次,当关闭实验板电源,再次开启电源时,从EEPROM中读取先前存储的数据,接着递增显示。
STC89C52内部EEPROM
则另外不需要修改的数据须先读出放在STC单片机的RAM当中,然后
擦除整个扇区,再
将需要保留的数据一并写回该扇区中。这时每个扇区使用的字节数据越少
越方便。
EEPROMStart(); //EEPROM启动
DelayNus(10);//读取一个字节要10us
EEPROMDisable(); //禁止EEPROM
return (ISP_DATA); //返回读取到的数据
}
void EEPROMWriteByte(UINT16 addr,UINT8 byte)
STC89C52内部EEPROM
STC89C52RC 2KEEPROM
传统的EEPROM是电可擦可编程只读存储一种掉电后数据不丢失的存储
芯片。
STC89C52RC的EEPROM是通过ISP/IAP技术读写内部FLASH来实现
EEPROM。
STC89C52RC的EEPROM起始地址为0x2000,以512字节为一个扇
typedef char INT8;
typedef int INT16;
typedef long INT32;
#define NOP() _nop_()
#define EEPROM_START_ADDRESS 0x2000
#define LED_PORTP2
void DelayNus(UINT16 t)
void EEPROMDisable(void)
{
ISP_CONTR=0x00; //禁止EEPROM
ISP_CMD=0x00; //无ISP操作
ISP_TRIG=0x00; //清零
ISP_ADDRH=0x00; //清零
ISP_ADDRL=0x00; //清零
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
单片机STC89C52RC 内部EEPROM
2011-09-06 12:15
单片机运行时的数据都存在于R A M(随机存储器)中,在掉电后R A M 中的数据是
无法保留的,那么怎
样使数据在掉电后不丢失呢?这就需要使用EEP R O M 或FL A S HR O M 等存储器来实现。
在传统的单片机系统中,一般是在片外扩展存储器,单片机与存储器之间通过I I C或S P I等接口来进行数据通信
这样不光会增加开发成本,同时在程序开发上也要花更多的心思。
在S T C单片机中内置了E E P R O M(其实是采用I S P/I A P技术读写内部F L A S H来实现E E P R O M),这样就节省了片外资源,使用起来也更加方便。
下面
就详细介绍S T C单片机内置E E P R O M及其使用方法
S T C各型号单片机内置的E E P R O M的容量最小有2K,最大有16K,基本上很好地满足项目的需要,更
方便之处就是节省了周边的E E P R O M器件,达到节省成本的目的,而且内部E E P R O M的速度比外部的
E E P R O M的速度快很多。
S T C各型号单片机内置的E E P R O M是以512字节为一个扇区,E E P R O M的起始地址=F A L S H容量值+1,
那么S T C89C52R C的起始地址为0x2000,第一扇区的起始地址和结束地址0x2000~0x21F F,第二扇区
的起始地址和结束地址0x2200~0x23F F,其他扇区如此类推。
深入重点:
�传统的E E P R O M是电可擦可编程只读存储一种掉电后数据不丢失的存储芯片。
�S T C89C52R C的E E P R O M是通过I S P/I A P技术读写内部F L A S H来实现E E P R O M。
�S T C89C52R C的E E P R O M起始地址为0x2000,以512字节为一个扇区,E E R P O M的大小为2K字节STC89C52RC 与EEPORM 实现的寄存器有6 个,分别是ISP_D AT A、
ISP_ADDRH、ISP_ADDRL
ISP_TRIG、ISP_CMD、ISP_CONTR。
1. ISP_DATA 寄存器
I S P_D A T A寄存器:I S P/I A P操作时的数据寄存器。
I S P/I A P从F l a s h的数据在此处,向F l a s h写的数据也须放在此处。
示例1:读单个字节
U I N T8E E P R O M R e a d(U I N T16a d d r)
{
……
r e t u r n I S P_D A T A;
}
示例2:写单个字节
v o i d E E P R O M W r i t e(U I N T8b y t e)
{
……
I S P_D A T A=b y t e;
}
2.ISP_ADDRH、ISP_ADDRL 寄存器
I S P_A D D R H:I S P/I A P操作时的地址寄存器高八位
I S P_A D D R L:I S P/I A P操作时的地址寄存器低八位
示例1:设置地址
v o i d E E P R O M S e t A d d r e s s(U I N T16A d d r)
{
……
I S P_A D D R H=(U I N T8)(A d d r>>8);
I S P_A D D R L=(U I N T8)A d d r;
}
3.ISP_CMD 寄存器
I S P_C M D:I S P/I A P操作时的命令模式寄存器,需要通过I S P_T R I G命令触发寄存器才能生效。
4.ISP_TRIG 寄存器
I S P/I A P命令要生效即I S P_C M D设置的命令要生效,必须通过I S P_T R I G命令触发寄存器进行触发。
触发过程很特别,只需要连续二次对I S P_T R I G寄存器赋值就可以的了,对I S P_T R I G寄存器先写入
0x46,再写入0x B9就完成命令触发的过程。
示例1:命令触发
v o i d E E P R O M C m d T r i g(v o i d)
{
……
I S P_T R I G=0x46;
I S P_T R I G=0x B9;
}
5.ISP_CONTR 寄存器
I S P_C O N T R:I S P/I A P控制寄存器
I S P E N:I S P/I A P功能允许位。
0:禁止I S P/I A P编程改变F l a s h。
S W B S:0:软件选择从用户主程序区启动1:I S P程序区启动
S W R S T:0:不操作1:产生软件系统复位,硬件自动清零
W T2、W T1、W T0:设置等待时间
假如S T C89C52R C的工作频率为12M H z,那么机器周期为1u s,参照表12-,E E P R O M的读单个字
节、写单个字节、扇区擦除的所需要的时间大致如下:
读单字节:11*1u s=11u s
写单字节:60*1u s=60u s
扇区擦除:10942*1u s=10.942m s
无论单片机运行在什么工作频率下,E E P R O M的读、写、擦除操作的所需要的时间分别约为10u s、60u s、10m s。
深入重点:
�S T C89C52R C与E E P O R M实现的寄存器有6个,分别是I S P_D A T A、I S P_A D D R H、
I S P_A D D R L I S P_T R I G、I S P_C M D、I S P_C O N T R。
�E E P R O M的命令触发必须对I S P_T R I G寄存器先写入0x46,再写入0x B9。
�无论单片机运行在什么工作频率下,E E P R O M的读、写、擦除操作的所需要的时间分别约为10u s、60u s、10m s,因而要对I S P_C O N T R设置好等待时间,否则数据容易出现问题。