stc89c52EEPROM读写
stc单片机eeprom读写程序
stc单片机eeprom读写程序以下是STC单片机使用EEPROM进行读写的示例程序:#include <reg52.h>#include <intrins.h>#define EEPROM_ADDR 0xA0 // EEPROM的I2C地址sbit SDA = P2^0; // I2C的数据线sbit SCL = P2^1; // I2C的时钟线// I2C开始信号void I2C_Start(){SDA = 1;_nop_(); // 延时一段时间SCL = 1;_nop_(); // 延时一段时间SDA = 0;_nop_(); // 延时一段时间SCL = 0;_nop_(); // 延时一段时间}// I2C停止信号void I2C_Stop(){SDA = 0;_nop_(); // 延时一段时间SCL = 1;_nop_(); // 延时一段时间SDA = 1;_nop_(); // 延时一段时间}// I2C发送一个字节的数据void I2C_SendByte(unsigned char dat){unsigned char i;for (i = 0; i < 8; i++){SDA = dat & 0x80; // 获取最高位dat <<= 1;_nop_(); // 延时一段时间SCL = 1;_nop_(); // 延时一段时间SCL = 0;_nop_(); // 延时一段时间}SDA = 1;_nop_(); // 延时一段时间SCL = 1;_nop_(); // 延时一段时间SCL = 0;_nop_(); // 延时一段时间}// I2C接收一个字节的数据unsigned char I2C_ReceiveByte(){unsigned char i, dat = 0;SDA = 1;for (i = 0; i < 8; i++){_nop_(); // 延时一段时间SCL = 1;_nop_(); // 延时一段时间dat <<= 1;dat |= SDA;SCL = 0;}return dat;}// 在EEPROM中写入一个字节的数据void EEPROM_WriteByte(unsigned char addr, unsigned char dat) {I2C_Start();I2C_SendByte(EEPROM_ADDR | 0); // 发送写入指令I2C_SendByte(addr); // 发送地址I2C_SendByte(dat); // 发送数据I2C_Stop();}// 从EEPROM中读取一个字节的数据unsigned char EEPROM_ReadByte(unsigned char addr){unsigned char dat;I2C_Start();I2C_SendByte(EEPROM_ADDR | 0); // 发送写入指令 I2C_SendByte(addr); // 发送地址I2C_Start();I2C_SendByte(EEPROM_ADDR | 1); // 发送读取指令 dat = I2C_ReceiveByte(); // 读取数据I2C_Stop();return dat;}。
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 程序区软件复位到用户应用程序区开始运行
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; //清零
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芯片烧写说明
STC89C52单片机各方面的性能都兼容AT89S52,并且具备更多的功能,特别是具备ISP 在线下载程序功能,结合我们517开发的实验开发板,可以很好地进行编程实验,单片机初学者可以不用购买昂贵的编程器就能学习单片机技术。
首先安装运行光盘里附带的stc 下载软件
使用方法:
先关闭实验板电源
1。
将串口线连接好,
2。
在编程软件界面中选择对应的单片机芯片型号,如STC89C52RC 3。
点击“OPEN FILE”选择合适的烧写文件,例如H:\TEST.HEX
5。
点击“下载”按钮,然后接通单片机实验板的电源
6。
3秒左右,就能完成程序下载,并运行。
熟悉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;
STC单片机EEPROM读写程序
STC单片机EEPROM读写程序在单片机中,EEPROM(Electrically Erasable Programmable Read-Only Memory)是一种非易失性存储器,可以用于存储数据,即使在断电情况下,数据也会被保留。
因此,掌握STC单片机的EEPROM读写程序对于开发嵌入式系统非常重要。
一、EEPROM简介EEPROM是一种可重复擦写的存储器,可用于存储小量数据。
与Flash存储器相比,EEPROM具有更快的写入和擦除速度。
在STC单片机中,EEPROM的存储容量通常较小,一般在几个字节到几千字节之间。
二、EEPROM读操作在STC单片机中,进行EEPROM读操作需要按照以下步骤进行:1. 初始化I2C总线:STC单片机使用I2C总线进行EEPROM读写操作,因此需要先初始化I2C总线。
通过设置相关寄存器,设置I2C 总线的速度和地址。
2. 发送设备地址:确定要读取的EEPROM设备的地址,并发送到I2C总线。
3. 发送寄存器地址:确定要读取的EEPROM寄存器地址,并将其发送到I2C总线。
4. 发送读命令:向EEPROM发送读命令,以启动读操作。
5. 读取数据:从EEPROM中读取数据,并保存到变量中。
6. 结束读操作:完成读操作后,关闭I2C总线。
三、EEPROM写操作类似于读操作,进行EEPROM写操作也需要按照一定的步骤进行:1. 初始化I2C总线:同样地,首先需要初始化I2C总线。
2. 发送设备地址:确定要写入的EEPROM设备的地址,并发送到I2C总线。
3. 发送寄存器地址:确定要写入的EEPROM寄存器地址,并将其发送到I2C总线。
4. 发送写命令:向EEPROM发送写命令,以启动写操作。
5. 写入数据:将要写入EEPROM的数据发送到I2C总线。
6. 结束写操作:完成写操作后,关闭I2C总线。
四、注意事项在进行EEPROM读写操作时,需要注意以下几点:1. 确保正确的设备地址:要与EEPROM的地址匹配,否则无法进行有效的读写操作。
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。
STC89C52的RAM说明
STC89C52系列单片机RAM说明1、工作寄存器区工作寄存器区位于片内数据存储器中的00H~1FH单元,共32字节,分成四组。
每组8个字节,分别记为R0~R7。
通过配置程序状态字(PSW)中的两个位(RS1,RS0)来决定你所操作的Rn是哪一个区的Rn。
程序默认在工作寄存器A组存放中间运算数据。
当进入中断程序时,中断数据工作寄存器组由组切换到其它区域。
2、可位寻址区可位寻址区位于片内存储器中的20H~2FH区间。
共计16个Byte,128个bit。
每个字节的每个位都拥有单独的地址,即字节地址.位地址,如:SETB 020H.1,就是令020字节的第2个位置位。
3、数据缓冲区(又叫用户RAM区)该区位于片内寄存器的30H~7FH区间。
共计80Byte。
其实整个通用RAM区都拥有同样的寻址规则,因此理论上整个通用RAM区(00H~7FH)都可以算作用户RAM区,只不过,唉,尼玛怎么感觉这么墨迹呢???擦!无力吐槽!4、堆栈其实都不应该单独给丫分个名分,这部分用途根本就是打游击的,哪里有地儿,就往哪钻。
不过基本上它只在80H~FFH这块活动,可以算是和数据缓冲区共用这片区域吧。
5、SFR(特殊用途寄存器)它们是大爷,内部寄存器中的高128个Byte区域内,它们基本就是横行霸道的主。
东一榔头西一棒子的,到处都是占坑不拉屎的节奏。
6、内部RAM残余在片内RAM高字节区被SFR祸害之后剩下的地盘,也可以拿来用用。
7、片外RAM如STC89C52,标称512Byte,那么片内用了256,剩下的256就是这儿了。
说这部分是片外,其实挺冤的,撑死了算是计划外超生的孩子吧,这部分还是在单片机内部,但待遇有点不一样。
首先寻址规则就变了,变成了16位寻址,地址码也成了int格式了。
读写这片区域的内容,需要用MOVX。
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烧写说明!!!!
STC芯片烧写说明书
一.首先打开软件,在MUC Type项选择所以烧写的芯片,这里我们选择
STC89C52RC.
二.接下来打开所要烧写的文件目录,OPER FILE/打开文件, 选择后缀
名为.HEX文件,即为我们要烧写的文件.
三.选择好串口,USB串口线使用到哪个串口就选择哪个串口,可以在
电脑桌面----我的电脑----右键属性----硬件的设备管理器中找到使用的串行口,如下图所示,使用的是COM4
所以我们这里我们选择COM4,波特率按默认设置的115200, 其它的选项都按默认设置就好了,全部设置如图所示:
四.先关掉开发板电源,POWER开关为开发板的电源控制开关,此时电源指示灯灭,然后点击Download/下载,接着再按下开发板电源POWER开关接通电源,电源指示灯亮,开始链接,这时出现正在烧写程序的进程如图所示:。
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的原因。
STC89C52是一种带8K字节闪烁可编程可檫除只读存储器(FPEROM
STC89C52是一种带8K字节闪烁可编程可檫除只读存储器(FPEROM-Flash Programable and Erasable Read Only Memory )的低电压,高性能COMOS8的微处理器,俗称单片机。
该器件采用ATMEL搞密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
单片机总控制电路如下图4—1:图4—1单片机总控制电路1.时钟电路STC89C52内部有一个用于构成振荡器的高增益反相放大器,引脚RXD 和TXD分别是此放大器的输入端和输出端。
时钟可以由内部方式产生或外部方式产生。
内部方式的时钟电路如图4—2(a) 所示,在RXD和TXD引脚上外接定时元件,内部振荡器就产生自激振荡。
定时元件通常采用石英晶体和电容组成的并联谐振回路。
晶体振荡频率可以在1.2~12MHz之间选择,电容值在5~30pF之间选择,电容值的大小可对频率起微调的作用。
外部方式的时钟电路如图4—2(b)所示,RXD接地,TXD接外部振荡器。
对外部振荡信号无特殊要求,只要求保证脉冲宽度,一般采用频率低于12MHz 的方波信号。
片内时钟发生器把振荡频率两分频,产生一个两相时钟P1和P2,供单片机使用。
示,RXD接地,TXD接外部振荡器。
对外部振荡信号无特殊要求,只要求保证脉冲宽度,一般采用频率低于12MHz的方波信号。
片内时钟发生器把振荡频率两分频,产生一个两相时钟P1和P2,供单片机使用。
RXD接地,TXD接外部振荡器。
对外部振荡信号无特殊要求,只要求保证脉冲宽度,一般采用频率低于12MHz的方波信号。
片内时钟发生器把振荡频率两分频,产生一个两相时钟P1和P2,供单片机使用。
(a)内部方式时钟电路(b)外部方式时钟电路图4—2时钟电路2.复位及复位电路(1)复位操作复位是单片机的初始化操作。
其主要功能是把PC初始化为0000H,使单片机从0000H单元开始执行程序。
除了进入系统的正常初始化之外,当由于程序运行出错或操作错误使系统处于死锁状态时,为摆脱困境,也需按复位键重新启动。
51单片机读写内部EEPROM详解
/*LCD1602写入8位命令子函数*/
void LcdWriteCom(uchar com);
/*LCD1602写入8位数据子函数*/
void LcdWriteData(uchar dat);
/*LCD1602初始化子程序*/
{
uchar V;
V = dcx(0x2002);//开机读取EEPROM区2002h数据,还原关电前LED的亮灭状况
if(V == 2){LED1=0;LED2=1;}
else if(V == 6){LED1=0;LED2=0;}
while(1)
{
if(!K1)
{
while(!K1);
LED1=0;LED2=1;址
出口:dat =读出的数据
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
uchar dcx(uint addr)
{
uchar dat;
ISP_CONTR = 0x81;
ISP_CMD = 0x01; //用户可以对"Data Flash/EEPROM区"进行字节读
sbit K1 = P3^2;//按钮1
sbit K2 = P3^3;//按钮2
void cc(uint addr);
void xcx(uint addr,uchar dat);
uchar dcx(uint addr);
void Q0();
#ifndef uchar
#define uchar unsigned char
sfr ISP_DATA = 0xe2;
sfr ISP_ADDRH = 0xe3;
51单片机读写内部EEPROM详解
#define uchar unsigned char
#define uint unsigned int
特殊功能寄存器声明****************
sfr ISP_DATA=0xe2;
sfr ISP_ADDRH=0xe3;
sfr ISP_ADDRL=0xe4;
uchar dat;
ISP_CONTR=0x81;
ISP_CMD= 0x01;/用户可以对"Data Flash/EEPROM区"进行字节读ISP_ADDRL = addr;
ISP_ADDRH=addr>>8;
EA= 0;
ISP_TRIG=0x46;
ISP_TRIG=0xB9;
_nop_();
dat=ISP_DATA;
uchar dcx(uint addr);
voidQ0();
/*
*/
/*
void main(void)
uchar V;
V = dcx(0x2002);//开机读取EEPROM区2002h数据,还原关电前LED的亮灭 状况
if(V==2){LED1=0;LED2=1;}
else if(V==6){LED1=0;LED2=0;}
验证第二、第三个程序时需按程序内主程序中的操作说明进行烧录单片
机,以验证是否成功操作单片机内部EEPROM。
程序1:
/***************************************************************
作品:EEP ROM实验,开机还原关电前LED的亮灭状况
ISP_ADDRH=addr>>8;
连续读写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。
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。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
STC89CXX_EEPROM_Char_Write(0x20,0x02,0x22);
STC89CXX_EEPROM_Char_Write(0x20,0x03,0x33);
STC89CXX_EEPROM_Char_Write(0x20,0x04,0x44);
sfr isp_addrl = 0xE4;
sfr isp_cmd = 0xE5;
sfr isp_trig = 0xE6;
sfr isp_contr = 0xE7;
/*****************************************/
/***************STC89CXX_EEPROM扇区擦除程序*************************/
{
unsigned char temp;
Delay1ms(10); //开机延时
STC89CXX_EEPROM_Erase(0x20); //擦除整个扇区
STC89CXX_EEPROM_Char_Write(0x20,0x00,0x00); //指定EEPROM地址写数据
/*模块名 :STC89C52RC 的EEPROM测试 **/
/*创建人 :郑 文(ClimberWin) **/
具体电路我不上传了,很简单,就STC89C52RC+个串口通信,晶振选用的是11.0592M。以下是我编写的源程序,方便实用。与大家分享!
/**************************************************************************************/
temp=STC89CXX_EEPROM_Char_Read(0x20,0x00);
SBUF=temp; //串口发送EEPROM的数据
Delay1ms(1000);
temp=STC89CXX_EEPROM_Char_Read(0x20,0x01);
SBUF=temp; //串口发送EEPROM的数据
#include "STC89C51RC_EEPROM.h" //调用STC89C51RC的EEPROM读写头文件
/*********串口初始化**************/
void init_rs232()
{
SCON=0x50;
PCON=0x00;
TH1=0xF4; //单片机晶振:11.0592M 波特率2400
{
isp_data = Write_data;
isp_addrh = Write_addr_h; //送地址高位
isp_addrl = Write_addr_l; //地址低位
EA = 0; /* 关中断 */
TL1=0XF4;
TMOD=0X20;
TR1=1;
}
/***********************************/
/*********毫秒延时程序**************/
void Delay1ms(unsigned int count)
{
unsigned int i,j;
isp_contr = 0;
isp_cmd = 0;
isp_trig = 0;
isp_addrh = 0;
isp_addrl = 0;
EA = 1; /* 开中断 */
{
unsigned char Read_isp_data;
isp_addrh = Read_addr_h; //送地址高字节
isp_addrl = Read_addr_l; //送地址低字节(从0开始到num-1为止)
EA = 0; /* 关中断 */
isp_contr = 0x81; /*20M,是0x80 orl 1 */
isp_cmd = 1; // 1表示字节读
for(i=0;i<count;i++)
for(j=0;j<120;j++);
}
/***********************************/
/*******************主程序************************/
void main (void)
isp_contr = 0x81;
isp_cmd = 3; //扇区擦除,要某字节为空,必须擦除1个扇区
isp_trig = 0x46; //先送0x46再送 0xb9 ISP/IAP 触发寄存器,每次都需要如此
isp_trig = 0xb9即被触发启动
/*******************************************************/
/*****STC89C51RC特殊功能寄存器定义********/
sfr isp_wdt = 0xE1;
sfr isp_data = 0xE2;
sfr isp_addrh = 0xE3;
/*****File Function : STC89C51RC_EEPROM Read and Write *****/
/*****Program Author : ZhengWen(ClimberWin) *****/
/*****Compile Date : 2008/2/14 *****/
#ifndef __STC89C51RC_EEPROM_CLIMBERWIN__
#define __STC89C51RC_EEPROM_CLIMBERWIN__
#define uchar unsigned char
#define uint unsigned int
#include <intrins.h>
void STC89CXX_EEPROM_Erase(unsigned char t_addr)
{
isp_addrh = t_addr; //可以不要 扇区里任意一个字节的地址都是扇区地址,无需求首地址,单片机会自己处理
isp_addrl = 0;
EA = 0; //关中断
}
/***********************************************/
/***************STC89CXX_EEPROM字节写程序*************************/
void STC89CXX_EEPROM_Char_Write(unsigned char Write_addr_h,unsigned char Write_addr_l ,unsigned char Write_data)
isp_contr = 0x81;
isp_cmd = 2; //送扇区命令
isp_trig = 0x46;
isp_trig = 0xb9;
_nop_();
_nop_();
/*功能描述:读写内部的EEPROM 并且通过串口发送读出来的数据 **/
/*创建日期:2008-2-14 **/
/*版本 :V1.0 **/
STC89C52RC内部EEPROM的读写
2008-02-24 18:46:53| 分类: 默认分类 |举报|字号 订阅
这个寒假学的东西不是很多,但是花了一两天的时间熟悉了下STC89C52RC内部EEPROM的读写,并且不断的改进能够通过串口来显示EEPROM地址空间的数据。我是用C语言编写的,把STC89C52RC内部EEPROM的读写编写成为了一个头文件“STC89C51RC_EEPROM.h”方便以后的应用。
Delay1ms(1000);
temp=STC89CXX_EEPROM_Char_Read(0x20,0x02);
SBUF=temp; //串口发送EEPROM的数据
Delay1ms(1000);
}
}
/*************************************************************/
}
/**************************************************************/
/***************STC89CXX_EEPROM字节读程序*************************/
STC89CXX_EEPROM_Char_Read(unsigned char Read_addr_h,unsigned char Read_addr_l)
/*****Edition Info : V1.0 *****/
/*****Amend Date : *****/
/*************************************************************/
/********************************************************************/
/*实现功能:EPROM地址的读写,数据从串口中显示出来 08.2.14 **/
#include <reg52.h> //调用52头文件
STC89CXX_EEPROM_Char_Write(0x20,0x05,0x55);
STC89CXX_EEPROM_Char_Write(0x20,0x06,0x66);
Delay1ms(100); //延时
while(1)