STC单片机EEPROM的应用和程序
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;}。
STC系列单片机EEPROM程序设计{修}
#include<reg52.h>#include<absacc.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//--------------------#define DataPort P0 //LCD数据口DB0--DB7sbit RS=P2^4;sbit RW=P2^5;sbit EN=P2^6;uint count; //定义计数、整型//-------------------------sbit cs=P1^0; //测试用sbit start_stop=P3^0;//启动、停止复合键sbit clear=P3^1; //显示清零键sbit moto=P2^0; //马达控制sbit warning=P2^3; //计数满//----------------------------uchar code tab0[]={"model:xy900"};uchar code tab1[]={"model:xy900"};uchar code tab2[]={"model:xy900"};uchar code tab3[]={"model:xy900"};uchar code tab4[]={"model:xy900"};uchar code tab5[]={"model:xy900"};//--------------------定义操作命令-----------#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_Order=0xe5;sfr ISP_TRIG=0xe6;sfr ISP_CONTR=0xe7;//---------------打开ISP,IAP功能---------void ISP_IAP_enable(void){EA=0;ISP_CONTR=ISP_CONTR&0x18; //ISP_COUNT的B4,B3位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=0ISP_TRIG=0x00;EA=1; //开中断}//--------------公共触发代码---------void ISPgoon(void){ISP_IAP_enable(); //打开ISP,IAP功能ISP_TRIG=0x46; //触发ISP_IAP命令字节1ISP_TRIG=0xb9; //触发ISP_IAP命令字节2_nop_();}//------------字节读--------------unsigned char byte_read(uint byte_addr){ISP_ADDRH=(uchar)(byte_addr>>8); //地址赋值ISP_ADDRL=(uchar)(byte_addr&0x00ff);ISP_Order=ISP_Order&0xf8; //清除低三位ISP_Order=ISP_Order|RdCommand; //写入命令ISPgoon(); //触发执行ISP_IAP_disable(); //关闭ISP,IAP功能return(ISP_DA TA); //返回读到的数据}//-------------EEPROM操作-------------/*************扇区擦除****************/void SectorErase(uint sector_addr){uint iSectorAddr;iSectorAddr=(sector_addr&0xfe00); //取扇区地址ISP_ADDRH=(uchar)(iSectorAddr>>8);ISP_ADDRL=0x00;ISP_Order=ISP_Order&0xf8; //清空低3位ISP_Order=ISP_Order|EraseCommand; //擦除命令3ISPgoon(); //触发执行ISP_IAP_disable(); //关闭ISP,IAP功能}/*************写字节****************/void byte_write(uint byte_addr,uchar original_data)ISP_ADDRH=(uchar)(byte_addr>>8); //取地址ISP_ADDRL=(uchar)(byte_addr&0x00ff);ISP_Order=ISP_Order&0xf8;ISP_Order=ISP_Order|PrgCommand; //写命令2 ISP_DATA =original_data; //写入数据准备ISPgoon(); //触发执行ISP_IAP_disable(); //关闭IAP功能}//--------------LCD操作函数---------------//--------LCD检测忙碌信号------------void WaitEnable(void){DataPort=0xff;RS=0;RW=1;_nop_();EN=1;_nop_();_nop_();while(DataPort&0x80);EN=0;}//------------写命令到LCD------------void WriteCommand(uchar Order,uchar Attribc){if(Attribc)WaitEnable();RS=0;RW=0;_nop_();DataPort=Order;_nop_();EN=1;_nop_();_nop_();EN=0;}//----------------LCD写数据-----------------void WriteData(uchar dataW){WaitEnable();RS=1;RW=0;_nop_();DataPort=dataW;_nop_();EN=1;_nop_();_nop_();EN=0;}//-----------LCD初始化--------------void InitLcd(){WriteCommand(0x38,1); //显示为16*2WriteCommand(0x08,1);WriteCommand(0x01,1);WriteCommand(0x06,1);WriteCommand(0x0c,1);}//--------------显示指定坐标的一个字符----------- void DisplayOne(uchar x,uchar y,uchar DData){y&=1;x&=15;if(y)x|=0x40;x|=0x80;WriteCommand(x,0);WriteData(DData);}//--------------显示指定坐标的一串字符------------- void DisplayList(uchar x,uchar y,uchar code*DData) {uchar ListLength=0;y&=0x1;x&=0xf;while(x<=15){DisplayOne(x,y,DData[ListLength]);ListLength++;x++;}}//-------------T0和INT0初始化中断函数--------- void Inittime(void){TMOD=0x05; //T0为工作方式1,16位计数TH0=0;TL0=0; //最大计数65536IE=0;EX0=1; //启用INT0中断ET0=1; //启用TF0中断IT0=0; //INT0低电平触发EA=1;}//-------------LCD显示函数-------------void display(){uchar w,q,b,s,g;w=count/10000+0x30; //万位数q=count/1000%10+0x30;b=count/100%10+0x30;s=count/10%10+0x30;g=count%10+0x30;DisplayOne(4,1,w); //显示万位DisplayOne(5,1,q);DisplayOne(6,1,b);DisplayOne(7,1,s);DisplayOne(8,1,g);}//-----------延时函数------------void delay(uint i){uchar j;while(i--)for(j=0;j<205;j++);}//-----------主函数------------void main(void){uchar i;delay(500);InitLcd();InitTime();for(i=15;i>=0;i--){DisplayList(i,0,tab0); //显示第一行DisplayList(i,1,tab1);delay(100);}delay(2000);for(i=16;i>=0;i--){DisplayList(i,0,tab2);DisplayList(i,1,tab3);}TL0=byte_read(0x2000);TH0=byte_read(0x2200); //读回掉电时的数据delay(100);//-------以下程序在正常计数时不会执行EEPROM擦写操作------- while(1){if(start_stop!=1) //如果启动、停止复合键被按下{delay(10);while(start_stop!=1);if(moto!=0){moto=0;TR0=1;for(i=16;i>=0;i--){DisplayList(i,1,tab4);}}else //在按下停止键时执行写操作(防突然掉电){moto=1;TR0=0;for(i=16;i>0;i--){DisplayList(i,1,tab3);}SectorErase(0x2000);SectorErase(0x2200);byte_write(0x2000,TL0); //写入临时数据byte_write(0x2200,TH0);}}//--------------开关操作2-------if(clear==0) //如果清零键被按下{TL0=TH0=0;}if(count==10000){SectorErase(0x2000);SectorErase(0x2200);byte_write(0x2000,TL0);byte_write(0x2200,TH0); //写入临时数据moto=1;TR0=0;count=TL0=TH0=0; //马达停止、计数器清零for(i=16;i>=0;i--){DisplayList(i,1,tab5);}warning=0;while(start_stop!=0);{delay(10);while(start_stop!=1);}warning=1;delay(100);}count=TH0*256+TL0;display();}}//掉电或关机触发INT0中断写入EEPROM------------ void INT_0(void)interrupt 0{SectorErase(0x2000);SectorErase(0x2200);byte_write(0x2000,TL0);byte_write(0x2200,TH0);while(1);}。
STC单片机EEPROM的应用和程序
STC单片机EEPROM的应用和程序STC单片机EEPROM的应用和程序(2009-04-22 21:58:34)转载▼标签:杂谈分类:Program最近,由于工作的需要,用STC89C52来开发新产品,要用天STC的Eeprom的功能,上网也找了一点资料,得到很大帮助,真的非常感谢。
程序是我在网上摘录的,调试通过了,不过我产品在用动态扫描显示的,由于在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 操作时的地址寄存器低八位。
STC单片机AD转换及EEPROM使用
STC单片机AD转换及EEPROM使用STC单片机AD转换及EEPROM使用随着各种电子设备的普及,信号处理的重要性日益凸显。
而一款好的ADC (Analog to Digital Convertor) 和一个高效的存储平台EEPROM (Electrically Erasable Programmable Read-Only Memory) 就成为建立可靠稳定的信号处理系统的重要组成部分。
本文将讨论STC单片机如何进行AD转换及EEPROM的使用。
首先,AD转换是将模拟信号转换成数字量的过程,是建立信号处理系统的关键步骤之一。
STC单片机内置了一个12位的AD转换器,也就是说,它可以将模拟信号转换成一个12位的数字信号,这是非常精确的。
下面我们来看看如何在代码中使用AD转换。
AD转换的原理很简单,即将待转换的模拟信号输入到AD口,接着启动AD转换。
当转换结束后,检测转换结束标志位,然后将转换结果读出。
这里具体介绍一下代码的实现方法。
首先,需要定义AD口的引脚、参考电压及转换效率等参数。
代码如下:#define ADC_PIN 0x01 //定义AD口所连接的引脚为P1.1#define ADC_REF 0x80 //定义参考电压为内部参考电压#define ADC_MODE 0xC0 //定义转换效率为最快接着,需要配置AD口所连接的引脚,使其成为输入口。
代码如下:P1ASF = 0x02; //定义P1.1为AD口输入接下来,启动AD转换,等待转换结束标志位的出现。
代码如下:ADC_CONTR = ADC_REF | ADC_MODE | ADC_PIN; //配置AD口ADC_CONTR |= 0x08; //启动AD转换while (!(ADC_CONTR & 0x20)); //等待转换结束标志位最后,将AD转换结果读出。
代码如下:uint16_t value;value = ADC_RES;value |= ADC_RESL << 8;我们可以看到,在STC单片机中使用AD转换非常方便,只需要简单的几行代码就可以完成。
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的地址匹配,否则无法进行有效的读写操作。
关于STC单片机EEPROM的应用总结
关于STC单片机EEPROM的应用总结关于STC单片机EEPROM的应用总结当在程序运行的过程中你希望修改某个变量并且此变量的值在掉电以后不丢失,那么你就可以采用将变量数据写入EEPROM的方式来实现。
什么是EEPROM,即Electrically Erasable ProgrammableRead_Only Memory首先它是一种存储器,并且可以通过高电压来进行反复擦写的存储器。
具有掉电数据不丢失的特点。
比如常用的24C系列,93C系列的器件。
一般这种器件采用I2C的方式与单片机进行通讯,对于这种通讯方式及器件的应用另作总结。
这里主要总结一下,STC12C5204AD芯片内部包含的EEPROM的应用方法。
STC12C5201AD系列单片机内部集成了EEPROM是与程序空间分开的,利用ISP/IAP技术可将内部data flash当EEPROM,擦写10万次以上。
EEPROM可分为若干个扇区,每个扇区包含512字节。
使用时建议同一次修改的数据放在同一个扇区,不是同一次修改的数据放在不同的扇区,不一定要用满。
数据存储器的擦除操作是按扇区进行的。
在程序中可对EEPROM进行字节读写/字节编程/扇区擦除操作。
在工作电压Vcc偏低时,建议不要进行EEPROM/IAP操作。
以免发生数据错误。
应用的步骤1、声明与EEPROM相关的寄存器2、编写EEPROM初始化函数3、编写字节擦除函数4、编写字节编程函数5、编写字节读取函数6、在需要读取EEPROM字节内容时直接调用字节读取函7、在需要进行写EEPROM字节时,先调用字节擦除函数,将字节内容擦除成FFH后,在调用字节编程函数,将数据写入到EEPROM的地址单元中。
与EEPROM应用相关的寄存器符号描述地址位地址及符号复位值IAP_DATAISP/IAP flash data register1111 1111BIAP_ADDRHISP/IAP flash address highC3H0000 0000BIAP_ADDRLISP/IAP flash address lowC4HIAP_CMDISP/IAP flash command register C5HMS1MS0IAP_TRIGISP/IAP flash command trigger C6HxxxxxxxxxBIAP_CONTRISP/IAP control registerC7HSWRSTCMD_FAILWT2WT1WT00000X000BPCONPower control87HSOMDSMOD0LVDFPOFGF1GF0PDIDL00110000B1、IAP_DATA:ISP/IAP数据寄存器ISP/IAP操作时的数据寄存器。
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。
STC51单片机 内部EEPROM操作
#include<reg52.h>#include<intrins.h>typedef unsigned char BYTE;typedef unsigned int WORD;//声明SFR IAP联系在一起的sfr IAP_DATA=0xE2; // flash data registersfr IAP_ADDRH=0xE3; //flash address highsfr IAP_ADDRL=0xe4; //falsh address lowsfr IAP_CMD=0Xe5; //FALSH COMMAND TRGGERsfr IAP_TRIG=0xE6; //flash command triggersfr IAP_CONTR=0xE7; //flash control register//定义ISP/IAP/EEPROM 命令#define CMD_IDIE 0 //stand-by#define CMD_READ 1 //BYTE - READ#define CMD_PROGRAM 2 // BYTE- PROGRAM#define CMD_ERASE 3 //SECTOR --ERASE//define ISP/IAP/EEPROM operation const for IAP_CONTR//#define ENABLE_IAP 0X80 //SYSCLK<40MHZ#define ENABLE_IAP 0X81 // SYSCLK<20MHZ//#define ENABLE_IAP 0x82 //SYSCLK<10MHZ//#define ENABLE_IAP 0X83 //SYSCLK<5MHZ//Start addtess for STC89C58 eeprom#define IAP_ADDRESS 0x08000void Delay(BYTE n);void IapIdle();BYTE IapReadByte(WORD addr);void IapProgramByte(WORD addr,BYTE dat);void IapEraseSector(WORD addr);void main(){WORD i;P1=0xfe; //1111,1110 system reset okDelay(5);IapEraseSector(IAP_ADDRESS); //ERASE CURRENT SECTOR for(i=0;i<512;i++) //check whether all sector data is ff {if(IapReadByte(IAP_ADDRESS+i)!=0xff)goto Error; //if error ,break}P1=0xfc; //1111,1100 erase successfulDelay(5);for(i=0;i<256;i++) //program 512 bytes data into data flash{IapProgramByte(IAP_ADDRESS+i,(BYTE)i);}P1=0XF8; //1111,1000 program successfulDelay(5);for(i=0;i<256;i++) //verify 512 bytes data{if(IapReadByte(IAP_ADDRESS+i)!=(BYTE)i)goto Error;}P1=0xf0; //1111,0000 verify successfulwhile(1);Error:P1&=0x7f; //oxxx,xxxx IAP operation failwhile(1);}// software delay functionvoid Delay(BYTE n){WORD x;while(n--){x=0;while(++x);}}//disable ISP/IAP/EEPROM function MAKE MCU in a safe state void IapIdle(){IAP_CONTR=0; //CLOSE IAP FUNCTIONIAP_CMD=0; //CLEAR COMMAND TO STANDBYIAP_TRIG=0; //CLEAR TRIGGER REGISTERIAP_ADDRH=0X80; //DATA PTR POINT TO NON-EEPROM AREA IAP_ADDRL=0; //CLEAR IAP ADDRESS TO PREVENT MISUSE }//Read one byte from ISP/IAP/EEPROM area//Input:addr (ISP/IAP/EEPROM address//Output: flash adataBYTE IapReadByte(WORD addr){BYTE dat;IAP_CONTR=ENABLE_IAP; //OPEN IAP FUNCTION ,AND SET WAIT TIMEIAP_CMD=CMD_READ; //SET ISP/IAP/EEPROM READ COMMANDIAP_ADDRL=addr; //SET ISP/IAP/EEPROM address lowIAP_ADDRH=addr>>8; //SET ISP//IAP//EEPROM address HIGHIAP_TRIG=0X46; //SEND TRIGGER COMMAND1 OX46IAP_TRIG=0XB9; //SEND TRIGGER COMMAND2 0XB9_nop_();dat=IAP_DATA; //read ISP/IAP/EEPROM dataIapIdle(); // close ISP/IAP/EEPROM FUNCITONreturn dat; //RETURN FLAH DATA}//Program one byte to ISP/IAP/EEPROM area//INPUT :addr (ISP/IAP/EEPROM address)//dat(ISP/IAP/EEPROM data)//Output:-void IapProgramByte(WORD addr, BYTE dat){IAP_CONTR=ENABLE_IAP; //OPEN IAP FUNTION AND SET WAIT TIMEIAP_CMD=CMD_PROGRAM; //SET ISP/IAP/EEPROM PROGRAM COMMAND IAP_ADDRL=addr; //set ISP/IAP/EEPROM ADDRESS LOWIAP_ADDRH=addr>>8; //set ISP/IAP/EEPROM address highIAP_DATA=dat; // WRITE ISP/IAP/EEPROM dataIAP_TRIG=0X46;IAP_TRIG=0XB9;_nop_();IapIdle();}void IapEraseSector(WORD addr){IAP_CONTR=ENABLE_IAP;IAP_CMD=CMD_ERASE;IAP_ADDRL=addr;IAP_ADDRH=addr>>8;IAP_TRIG=0X46;IAP_TRIG=0XB9;_nop_();IapIdle();}。
STC内部EEPROM应用函数
STC内部EEPROM应用函数作者:pc63 来源:单片机学习网编辑导读:STC12C5410AD系列头文件|stc单片机AD和EEPROM的驱动C程序|STC89C51RC/RD+系列头文件|STC12C5404AD 单片机控制74LS164子程序|SST89C54/58简介|STC12C5A60S2系列双串口1T 8051单片机头文件|STC11F60XE高速总线系列1T 8051单片机头文件|利用宏晶科技的IAP单片机开发自己的ISP程序|STC89C58RD+ 内部EEPROM 放数据FLASH-ISP-IAP|STC单片机选型指南正文:STC12C5410系列单片机内带2K EEPROM,分成4个扇区,每个扇区512byte。
使用时注意以下几点:1、有三个基本命令:字节读,字节写,扇区擦除2、没有字节擦除,只有扇区擦除。
如果要改变扇区中de某个字节,保留其它字节内容不变,必须先把其它字节读出来保存,然后擦除整个扇区,再把改动de字节内容和保存de其它字节内容写入扇区。
3、扇区读写de时间短,擦除de时间比较长,要注意扇区擦除函数de调用位置,比如最好不要放在定时中断中。
4、每个扇区用de越少越方便。
以下shi应用函数:#include <functi title="东哥电子商城,提供单片机学习开发板,实验板,编程器,仿真器,无线发射接收模块,各种电子元器件.">单片机deEEPROM 测试起始地址void iap_disable () {ISP_ADDRL = 0xff;ISP_ADDRH = 0xff;ISP_CONTR = 0; //关闭 IAP 功能ISP_CMD = 0; //清命令寄存器,使命令寄存器无命令,此句可不用ISP_TRIG = 0; //清命令触发寄存器,使命令触发寄存器无触发,此句可不用}uchar byte_read (uint address){uchar i;ISP_ADDRL = address; //设置目标单元地址ISP_ADDRH = address >> 8;ISP_CONTR = ENABLE_ISP; //打开 IAP 功能, 设置 Flash 操作等待时间 ISP_CMD = ISP_IAP_BYTE_READ; //设置为IAP/ISP/EEPROM 字节读模式命令 //EA=0;ISP_TRIG = 0x46;ISP_TRIG = 0xb9; //先送46h,再送B9h 到ISP/IAP 触发寄存器,每次都需如此,送完B9h 后,ISP/IAP 命令立即被触发起动for (i = 0;i < 30;i++);//EA=1;iap_disable (); //;关闭 IAP 功能, 清相关de特殊功能寄存器,使CPU 处于安全状态,一次连续deIAP 操作完成之后建议关闭IAP 功能,不需要每次都关i = ISP_DATA; //读出de数据在ISP_DATA 单元中,送入累加器Areturn i;}void byte_program (uint address,uchar wr_data) {uchar i;ISP_ADDRL = address; //设置目标单元地址ISP_ADDRH = address >> 8;ISP_DATA = wr_data; //要编程de数据先送进ISP_DATA 寄存器ISP_CONTR = ENABLE_ISP; //打开 IAP 功能, 设置 Flash 操作等待时间 ISP_CMD = ISP_IAP_BYTE_PROGRAM; //设置为IAP/ISP/EEPROM 字节编程模式命令//EA=0;ISP_TRIG = 0x46;ISP_TRIG = 0xb9; //先送46h,再送B9h 到ISP/IAP 触发寄存器,每次都需如此,送完B9h 后,ISP/IAP 命令立即被触发起动for (i = 0;i < 30;i++);//EA=1;iap_disable (); //;关闭 IAP 功能, 清相关de特殊功能寄存器,使CPU 处于安全状态}void sector_erase (uint address) {uchar i;ISP_ADDRL = address; //设置目标单元地址ISP_ADDRH = address >> 8;ISP_CONTR = ENABLE_ISP; //打开 IAP 功能, 设置 Flash 操作等待时间 ISP_CMD = ISP_IAP_SECTOR_ERASE; //设置为IAP/ISP/EEPROM 扇区擦除模式命令//EA=0;ISP_TRIG = 0x46;ISP_TRIG = 0xb9; //先送46h,再送B9h 到ISP/IAP 触发寄存器,每次都需如此,送完B9h 后,ISP/IAP 命令立即被触发起动for (i = 0;i < 30;i++);//EA=1;iap_disable ();。
STC单片机内部EEPROM使用程序
END
;定义Flash 操作等待时间及允许IAP/ISP/EEPROM操作的常数
;ENABLE_IAP EQU 80H ;系统工作时钟<30MHz时,对IAP_CONTR寄存器设置此值
ENABLE_IAP EQU 81H ;系统工作时钟<24MHz时,对IAP_CONTR寄存器设置此值
MOV IAP_ADDRL, DPL ;设置目标单元地址的低8位地址
CLR EA
MOV IAP_TRIG, #46H ;先送5Ah,再送A5h到ISP/IAP触发寄存器,每次都需如此
MOV IAP_TRIG, #0B9H ;送完A5h后,ISP/IAP命令立即被触发起动
NOP
MOV A, IAP_DATA ;读出的数据在IAP_DATA单元中,送入累加器A
ACALL IAP_Disable ;关闭 IAP 功能, 清相关的特殊功能寄存器,使CPU处于安全状态,
;一次连续的IAP操作完成之后建议关闭IAP功能,不需要每次都关
CLR EA
MOV IAP_TRIG, #46H ;先送5Ah,再送A5h到ISP/IAP触发寄存器,每次都需如此
MOV IAP_TRIG, #0B9H ;送完A5h后,ISP/IAP命令立即被触发起动
NOP
MOV IAP_TRIG, #0 ;清命令触发寄存器,使命令触发寄存器无触发,此句可不用
MOV IAP_ADDRH, #0FFH ;送地址高字节单元为00,指向非EEPROM区
MOV IAP_ADDRL, #0FFH ;送地址低字节单元为00,防止误操作
ACALL IAP_Disable ;关闭 IAP 功能, 清相关的特殊功能寄存器,使CPU处于安全状态,
stc系列单片机eeprom操作
stc系列单片机eeprom操作前言: stc单片机在中国大陆在中低端市场中占有大半壁江山.片内EEPROM是掉电保存数据的最理想选择.stc单片机的片内eeprom以扇区为单位,每个扇区大小是512 字节.以下是我亲自编写的对stc单片机(89系列除外)操作子函数,可以模块化使用,欢迎电子爱好者与我多多交流.本人QQ704157083 tel :186******** .工作地点:深圳..南山区. 从事软件和电子这行,爱好交朋友,一起开发有创意的产品.过目请留言!----------------------------------------------------------------------------------------------------------------------//增加寄存器sfr IAP_CONTR =0xC7; // ;软复位寄存器sfr IAP_DATA =0xC2 ; //数据寄存器;寄存器的地址不能改sfr IAP_adrRH =0xC3; // 地址高8位寄存器sfr IAP_adrRL = 0xC4; //命令触发器sfr IAP_CMD=0xC5; //;命令寄存器sfr IAP_TRIG=0xC6; //;命令触发器//************************************************************* **************** ****//增加通用函数.//(1) eeprom 函数写一个数据eg1: rom_writearea(1,100,0x99,12); 在片区1 地址100 中写入0x99 晶振12M// 读一个数据: eg2: rom_readarea(1,100,12); 在片区1 地址100 中读出数据晶振12M// 写一个数组:eg3: rom_write_array(1,100,a,10,12); 在片区1,起始地址100, 写入数组a ,数组大小10,晶振12Mxdata char xram[512] ; // 定义一个备份片区的数组.rom_readbyte(unsigned int adr,unsigned char fso);rom_readarea(unsigned int area,unsigned int adr_toread,unsigned char fso);void rom_writebyte(unsigned int adr,unsigned char dat,unsigned char fso);void rom_clear(unsigned int adr,unsigned char fso) ;void iap_disable();void rom_writearea(unsigned int area,unsigned int adr,unsigned char dat,unsigned char fso); // 写之前备份,扇区地址,字节地址,数据内容void rom_write_array(unsigned int area,unsigned int adr_towrite,unsigned char *p,unsigned int num,unsigned char fso);choose_area(unsigned char area); //选择片区//^^^^^^^^^^^^^^^^^^^^^^^^rom_readbyte(unsigned int adr,unsigned char fso){DPH=adr>>8; //取高字节DPL=adr; //取低字节if(fso==6){IAP_CONTR=0X84 ;}else if(fso==12){IAP_CONTR=0X8B; //;,<=12m晶振固定写法允许改变rom <=6M IAP_CONTR=0X84}IAP_CMD=0X01; //;01h为读取命令IAP_adrRH=DPH; //获取指针高八位IAP_adrRL=DPL; //获取指针低八位//EA=0;IAP_TRIG=0X5A; //两条触发命令,使命令执行IAP_TRIG=0XA5;// a=IAP_DATA; //;获取数据iap_disable();return(IAP_DATA);}//^^^^^^^^^^^^^^^^^^^^^^^^rom_readarea(unsigned int area,unsigned int adr_toread,unsigned char fso){unsigned int adr ; //扇区首地址adr=choose_area(area);IAP_DATA= rom_readbyte(adr+adr_toread,fso);//读取数据return(IAP_DATA);}//^^^^^^^^^^^^^^^^^^^^^^^^void rom_writebyte(unsigned int adr,unsigned char dat,unsigned char fso){DPH=adr>>8; //取高字节DPL=adr; //取低字节if(fso==6){IAP_CONTR=0X84 ;}else if(fso==12){IAP_CONTR=0X8B; //;,<=12m晶振固定写法允许改变rom <=6M IAP_CONTR=0X84}IAP_CMD=0X02; //;02h为写入命令IAP_adrRH=DPH; //获取指针高八位IAP_adrRL=DPL; //获取指针低八位IAP_DATA=dat; //把数据放入数据寄存器中,用于写//EA=0;IAP_TRIG=0X5A; //两条触发命令,使命令执行IAP_TRIG=0XA5;iap_disable();}//^^^^^^^^^^^^^^^^^^^^^^^^void rom_writearea(unsigned int area,unsigned int adr_towrite,unsigned char dat,unsigned char fso){unsigned int i,j ; //循环变量unsigned int adr ; //扇区首地址adr=choose_area(area);for (i=0;i<512;i++) //读扇区的所有数据,进行备份.{xram[i]=rom_readbyte(adr+i,fso);}rom_clear(area,fso); //清除要写入的扇区xram[adr_towrite]=dat ; //要写入的数据先放到数组中来for (j=0;j<512;j++) //将数组中的数据写入扇区中..{rom_writebyte(adr+j,xram[j],fso);}}//^^^^^^^^^^^^^^^^^^^^^^^^void rom_write_array(unsigned int area,unsigned int adr_towrite,unsigned char *p,unsigned int num,unsigned char fso){unsigned int i,j ; //循环变量unsigned int adr ; //扇区首地址adr=choose_area(area);for (i=0;i<512;i++) //读扇区的所有数据,进行备份.xram[i]=rom_readbyte(adr+i,fso);}rom_clear(area,fso); //清除要写入的扇区for(i=0;i<num;i++)< p="">{xram[adr_towrite+i]=*(p+i); //将数组的内容写入备份数组XRAM中}for (j=0;j<512;j++) //将数组中的数据写入扇区中..{rom_writebyte(adr+j,xram[j],fso);}}//^^^^^^^^^^^^^^^^^^^^^^^^void rom_clear(unsigned int area,unsigned char fso) //清除一片扇区{unsigned int adr ; //扇区首地址adr=choose_area(area);DPH=adr>>8; //取高字节DPL=adr; //取低字节if(fso==6){IAP_CONTR=0X84 ;}else if(fso==12){IAP_CONTR=0X8B; //;,<=12m晶振固定写法允许改变rom <=6M IAP_CONTR=0X84}IAP_CMD=0X03; //;03h为擦除命令IAP_adrRH=DPH; //获取指针高八位IAP_adrRL=DPL; //获取指针低八位//EA=0;IAP_TRIG=0X5A; //两条触发命令,使命令执行IAP_TRIG=0XA5;iap_disable();}//^^^^^^^^^^^^^^^^^^^^^^^^void iap_disable() // 关闭iap编程{IAP_CONTR=0X00; //关闭rom控制器命令IAP_CMD=0X00; //清除读写擦命令choose_area(unsigned char area){unsigned int adr;switch (area) //扇区编号从1开始到16扇区. {case 1: adr=0x0000;break;case 2: adr=0x0200;break;case 3: adr=0x0400;break;case 4: adr=0x0600;break;case 5: adr=0x0800;break;case 6: adr=0x0A00;break;case 7: adr=0x0C00;break;case 8: adr=0x0E00;break;case 9: adr=0x1000;break;case 10: adr=0x1200;break;case 11: adr=0x1400;break;case 12: adr=0x1600;break;case 13: adr=0x1800;break;case 14: adr=0x1A00;break;case 15: adr=0x1C00;break;case 16: adr=0x1E00;break;}return (adr);}//**********************************************************en d</num;i++)<>。
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 控制寄存器。
51单片机STC单片机IAP(EEPROM)的使用
#include<stc12c5410ad.h>//到宏晶网站下载头文件或自己在现有的头文件上加上相应的寄存器定义即可。
#include<intrins.h>#define uchar unsigned char#define uint unsigned int/****************uart init***********/void UART_inti(void){AUXR=0x40;//定时器1速度是普通8051的12倍,不分频TMOD=0x20;//定时器1工作在方式2,用来产生波特率SCON=0x50;//串口工作在方式1,允许接收TL1=0xF7;//波特率为38400;FB为115200TH1=0xF7;PCON=0x00;//SMOD=0TR1=1; //产生波特率}void ISP_write(uint ISP_addr,uchar ISP_data)//stc12c5404启始地址2800h ;IAP_CMD 1读,2写,3擦除{ISP_DATA=ISP_data; //送数据ISP_ADDRL=ISP_addr%256;ISP_ADDRH=ISP_addr/256;//送高低地址ISP_CONTR=0x83;//IAP ENABLE ,SET CPU WAIT TIME ISP_CMD=2;//写字节模式ISP_TRIG=0x46;ISP_TRIG=0xB9;//触发启动ISP_nop_();//等待写入ISP_CONTR=0x00;//禁止ISP/IAp操作ISP_CMD=0;ISP_TRIG=0x00;}uchar ISP_read(uint ISP_addr)//stc12c5404启始地址2800h ;IAP_CMD 1读,2写,3擦除{uchar recivedata;ISP_ADDRL=ISP_addr%256;ISP_ADDRH=ISP_addr/256;//送高低地址ISP_CONTR=0x83;//IAP ENABLE ,SET CPU WAIT TIME ISP_CMD=1;//写字节模式ISP_TRIG=0x46;ISP_TRIG=0xB9;//触发启动ISP_nop_();//等待读recivedata=ISP_DATA;ISP_CONTR=0x00;//禁止ISP/IAp操作ISP_CMD=0;ISP_TRIG=0x00;return recivedata;}void ISP_erase(uint ISP_addr)//stc12c5404启始地址2800h ;IAP_CMD 1读,2写,3擦除{ISP_ADDRL=ISP_addr%256;ISP_ADDRH=ISP_addr/256;//送高低地址ISP_CONTR=0x83;//IAP ENABLE ,SET CPU WAIT TIMEISP_CMD=3;//写字节模式ISP_TRIG=0x46;ISP_TRIG=0xB9;//触发启动ISP_nop_();//等待擦除ISP_CONTR=0x00;//禁止ISP/IAp操作ISP_CMD=0;ISP_TRIG=0x00;}//主程序只为测试时随意编写的,可以根据需要做相应的修改即可。
第10章-STC系列单片机片内EEPROM的应用
10.1 EEPROM模块所属特殊功能寄存器 10.2 EEPROM读、写、擦除
第10章STC系列单片机片内 EEPROM旳应用
• STC系列单片机内部不但集成了用于存储程序旳EEPROM, 还集成了用于存储数据旳EEPROM,不同旳型号容量不同 ,从1KB-45KB不等。
ORG 0000H LJMP MAIN ORG 0100H MAIN: MOV SP,#0BFH;初始化堆栈指针 START0: MOV DPTR,#SECTION_ADDR ;第一扇区旳首地址 送DPTR LCALL SECTION_ERASE;调用扇区擦除子程序 MOV A,IAP_CONTR ;读控制寄存控制器 JNB ACC.4,START;若此位为0,表达擦除成功,可进行编程 LJMP START0 ;若擦除失败,须重新进行擦除
EEPROM进行读、写、擦除操作 MOV IAP_CMD,#00000001B ;送字节读指令 MOV IAP_TRIG,#5AH ;开启内部读取工作
MOV IAP_TRIG,#0A5H NOP ;等待2个时钟周期旳时间
NOP MOV A,ISP_DATA ;将读出旳数据存入A寄存器
• 对STC10/10Fxx、STC12C5Axx等系列单片机 开启读、写、擦除工作时,先给IAP_TRIG寄 存器送立即数5AH,再送A5H作为触发信号; 而对STC12C56xx、STC12C54xx、 STC89/90C51xx等系列单片机需先送46H, 再送B9H作为触发信号。
MOV IAP_ADDRL,DPL ;送入地址旳低8位
MOV IAP_ADDRH,DPH ;送入地址旳高8位
MOV IAP_TRIG,#5AH;开启读操作
STC51单片机EEPROM的使用方法
STC51单片机EEPROM的使用方法STC51单片机有类似flash的功能EEPROM,可以掉电保存数据,不同型号的可以保存不同大小的数据,以12C5A60S2为例,EEPROM的大小为2K,分为两个扇区,掉电保存在很多地方需要。
首先寄存器的问题,不同系列的STC单片机的与EEPROM有关的寄存器不同,比如10/11/12系列的sfr ISP_DATA = 0xC2;sfr ISP_ADDRH = 0xC3;sfr ISP_ADDRL = 0xC4;sfr ISP_CMD = 0xC5;sfr ISP_TRIG = 0xC6;sfr ISP_CONTR = 0xC7;89/90系列的sfr ISP_DATA = 0xe2;sfr ISP_ADDRH = 0xe3;sfr ISP_ADDRL = 0xe4;sfr ISP_CMD = 0xe5;sfr ISP_TRIG = 0xe6;sfr ISP_CONTR = 0xe7;注意寄存器一定要按数据手册中的配置,ISP触发命令也不相同,详情请看下方代码其次是关于扇区问题,不同型号的MCU扇区个数不尽相同,详情请查询数据手册,在这里我以12C5A60S2为例,一共2扇区,每扇区512B,地址区间为0x0000~0x03FF,使用时请勿超出范围。
EEPROM使用时有三个功能,分别为读、写、和擦除,由ISP_CMD寄存器控制,分别对应1/2/3下面为此项内容的代码部分,分别为初始化、读、擦除和写,本程序为11.0592MHz晶振,STC12C5A60S2的MCU,以下程序测试可用EEPROM.cvoid DisableEEPROM(void){ISP_CONTR = 0;//禁止ISP/IAP操作ISP_CMD = 0;//去除ISP/IAP命令ISP_TRIG = 0;//防止ISP/IAP命令误触发ISP_ADDRH = 0xff;//指向非EEPROM区,防止误操作ISP_ADDRL = 0xff;//指向非EEPROM区,防止误操作。
STC单片机EEPROM的读写程序
STC单片机EEPROM的读写程序汇编语言写的,依据stc单片机官方提供的资料,测试ok,另外还有c语言的大家可到论坛去找。
stc的eeprom 功能还是不错的,可以简化我们的外围电路,但是缺点是是有就那就是写入速度太慢了,只能按扇区的写,不能字节写.下面是代码AUXR1 EQU 0A2HISPDATA EQU 0E2HISPADDRH EQU 0E3HISPADDRL EQU 0E4HISPCMD EQU 0E5HISPTRIG EQU 0E6HISPCONTR EQU 0E7HORG 0000HAJMP MAINORG 0030HMAIN:MOV AUXR1,#0INC AUXR1MOV DPTR,#2000H ACALL ERASEMOV A,#0FEH ACALL EEPROMW ACALL EEPROMR INC AUXR1AJMP MAIN ERASE:;擦除MOV ISPCONTR,#81H MOV ISPCMD,#03H MOV ISPADDRH,DPH MOV ISPADDRL,DPL CLR EAMOV ISPTRIG,#46H MOV ISPTRIG,#0B9H NOPSETB EAACALL ISPXXRET EEPROMW:;写MOV ISPCONTR,#81H MOV ISPCMD,#02HMOV ISPADDRH,DPH MOV ISPADDRL,DPL MOV ISPDATA,A CLR EAMOV ISPTRIG,#46H MOV ISPTRIG,#0B9H NOPSETB EAACALL ISPXXRET EEPROMR:;读MOV ISPCONTR,#81H MOV ISPCMD,#01H MOV ISPADDRH,DPH MOV ISPADDRL,DPL CLR EAMOV ISPTRIG,#46H MOV ISPTRIG,#0B9H NOPMOV A,ISPDATA SETB EAACALL ISPXXRETISPXX:MOV ISPCONTR,#0 MOV ISPCMD,#0 MOV ISPTRIG,#0 RETDEL:MOV R2,#0FFHD1:MOV R1,#0FFH DJNZ R1,$DJNZ R2,D1RETEND。
STC单片机内部EEPROM的应用
TX-1C开发板学习单片机内部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。
表1 ISP/IAP相关寄存器列表ISP/IAP从Flash读出的数据放在此处,向Flash写入的数据也需放在此处。
ISP_ADDRH:ISP/IAP操作时的地址寄存器高八位。
ISP_ADDRL:ISP/IAP操作时的地址寄存器低八位。
ISP_CMD:ISP/IAP操作时的命令模式寄存器,须命令触发寄存器触发方可生效。
命令模式如表2所示。
表2 ISP_CMD寄存器模式设置程序在系统ISP程序区时可以对用户应用程序区/数据Flash区(EEPROM)进行字节读/字节编程/扇区擦除;程序在用户应用程序区时,仅可以对数据Flash区(EEPROM)进行字节读/字节编程/扇区擦除。
STC_EEPROM延长使用寿命的大数据记录C程序详解
STC_EEPROM延长使用寿命的大数据记录C程序在我们华清士科技公司的产品研发中,使用很多远程传感器的记录方案,在单片机编程的时候,觉得以下程序切实提高了STC单片机的EEPROM使用灵活性和寿命。
特此分享出来,期待可以抛砖引玉。
原理是这样的:STC-eeprom一个字节的写入,只能将1的状态写成0。
这样一个字节就可以被写8次,记录8个状态(分别是0xFE 0XFB 0XF8 0XE0 0XB0 0X80 0X00)。
当然其实还有一个状态是0XFF ,这是扇区被整个擦写后的状态。
我们就每记录一个数据,就在检索区加写1/8个字节,作为记录次数标识。
这样一组数据(示例之中为6个字节)所占用的空间实际上是6+1/8字节。
以此我们可以根据STC单片机型号的不同,将策划好的扇区数填入程序函数里面,每一次加电重启,都有一个程序来读取检索区的记忆次数,顺便,记录区的地址,都会有了。
(EEPROM_start0-EEPROM_start1 作为次数记录区,总共记录EEPROM_mu_MAX组数据。
)(x_ready_ok,x_ready_out,x_eeprom_need为该示例eeprom的标志)这个程序我们已经上机演示调试成功。
类似的应用也在华清士公司的几种除湿模块产品上得到广泛使用。
效果良好。
写此文是希望为我们钟爱的STC单片机开发做一些支持。
希望也得到广大工程师的交流沟通,共同提高。
下面是该C语言的程序。
应该在STC公司的IAP型号上面都可以调试成功。
当然在别的型号上面,比如STC12F04XE等上面,程序之中的起始扇区当然是1了,因为eeprom记录地址是从0x00(第一个扇区)开始的。
20170504_STC_EEPROM连续存储示例.c//------------------------------------------------------------------// 程序开始宏定义硬件接口定义//------------------------------------------------- ----------------#include "STC15F2K60S2.h"#include "intrins.h"//#include "absacc.h"//#include "math.h"#define _Nop() _nop_()//STC15W413AS -TSSOP20 单片机封装//该程序为演示程序20170508 ——演示EEPROM 13k 空间的自动分配以及多次记录数据检索//原始目的:利用STC-eeprom读写规则,尽量减少擦写次数,以延长EEPROM使用寿命。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
STC单片机EEPROM的应用和程序(2009-04-22 21:58:34)转载▼标签:杂谈分类:Program最近,由于工作的需要,用STC89C52来开发新产品,要用天STC的Eeprom的功能,上网也找了一点资料,得到很大帮助,真的非常感谢。
程序是我在网上摘录的,调试通过了,不过我产品在用动态扫描显示的,由于在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 控制寄存器。
ISPEN:ISP/IAP 功能允许位。
0:禁止ISP/IAP 编程改变Flash,1:允许编程改变Flash SWBS:软件选择从用户主程序区启动(0),还是从ISP 程序区启动(1)。
SWRST:0:不操作,1:产生软件系统复位,硬件自动清零。
ISP_CONTR 中的SWBS 与SWRST 这两个功能位,可以实现单片机的软件启动,并启动到ISP 区或用户程序区,这在"STC 单片机自动下载"一节,亦有所应用。
如:ISP_CONTR=0x60? 则可以实现从用户应用程序区软件复位到ISP 程序区开始运行程序。
ISP_CONTR=0x20? 则可以实现从ISP 程序区软件复位到用户应用程序区开始运行程序。
用IAP 向Flash 中读写数据,是需要一定的读写时间的,读写数据命令发出后,要等待一段时间才可以读写成功。
这个等待时间就是由WT2、WT1、WT0 与晶体振荡器频率决定的。
(以上的建议时钟是(WT2、WT1、WT0)取不同的值时的标称时钟,用户系统中的时钟不要过高,否则可能使操作不稳定。
)#include "reg52.h"#include "eeprom.h"//****************** 关闭ISP,IAP 功能**************void ISP_IAP_Disable(void){ISP_CONTR = 0x00;ISP_CMD = 0X00;ISP_TRIG = 0x00;EA = 1; //开中断}//*******************字节读***************************uchar Byte_read(uint byte_addr){ISP_CONTR = En_Wait_TIME; //开启ISP/IAP;并送等待时间ISP_CMD = Read_COM; //送字节读命令字ISP_ADDRH = (uchar)(byte_addr >> 8); //送地址高字节ISP_ADDRL = (uchar)(byte_addr & 0X00FF); //送地址低字节EA = 0; //关中断ISP_TRIG = 0X46; //送触发命令字0X46、0XB9ISP_TRIG = 0XB9;_nop_();ISP_IAP_Disable(); //关闭ISP/IAP功能EA = 1; //开中断return ((unsigned char)ISP_DATA);}//********************字节编程*********************** void Byte_program(uint byte_addr, uchar isp_iap_data){ISP_CONTR = En_Wait_TIME; //开启ISP/IAP;并送等待时间ISP_CMD = Prog_COM; //送字节编程命令字ISP_ADDRH = (uchar)(byte_addr >> 8); //送地址高字节ISP_ADDRL = (uchar)(byte_addr & 0X00FF); //送地址低字节ISP_DATA = isp_iap_data; //送数据进ISP_DATAEA = 0; //关中断ISP_TRIG = 0X46; //送触发命令字0X46、0XB9ISP_TRIG = 0XB9;_nop_();ISP_IAP_Disable(); //关闭ISP/IAP功能EA = 1; //开中断}//********************* 扇区擦除********************* void Sector_erase(uint sector_addr){ISP_CONTR = En_Wait_TIME; //开启ISP/IAP;并送等待时间// ISP_CONTR=0xc1;ISP_CMD = Dele_COM; //送扇区擦除命令字ISP_ADDRH = (uchar)(sector_addr >> 8); //送地址高字节ISP_ADDRL = (uchar)(sector_addr & 0X00FF); //送地址低字节EA = 0; //关中断ISP_TRIG = 0X46; //送触发命令字0X46、0XB9ISP_TRIG = 0XB9;_nop_();ISP_IAP_Disable(); //关闭ISP/IAP功能EA = 1;}#ifndef _eeprom_h#define _eeprom_H//*********************EEPROM定义命令字节******************#define Read_COM 0X01 //字节读数据存储区#define Prog_COM 0X02 //字节编程数据存储区#define Dele_COM 0X03 //扇区擦除数据存储区#define En_Wait_TIME 0X81 //设置等待时间,并使能ISP/IAP//从用户区启动程序//0X00==40MHZ以下,0X01==20MHZ以下//0X02==10MHZ以下,0X03==5MHZ以下,现在设置了20MHZ以下的,//#define Start_ADDRH 0X20 //扇区地址高位,STC89C/LE52RC#define Start_ADDRL 0X00 //扇区地址低位#endif注意了,要写数据时,一定要对该扇区先擦除后写数据的,所以要写的数据尽量不要多,也可以对不同功能的数据存在不同的扇区里。
如:Sector_erase(0X2e00); //扇区擦除,第八个扇区Byte_program(0X2e00,Eeprom_ReadCode);//写EEPROM,保存可读命令要读数据时,就直接读就可以了。
ReadData=Byte_read(0X2002);//读取该地址的数据读一个字节、编程一个字节、擦除一个扇区分别用时10us、60us、10ms关于STC系列51单片机的片内EEPROM应用(转载自虚V界的博客eeworld)(2011-12-10 12:22:43)转载▼标签:stc内部eeprom杂谈分类:51EEPROM都知道,做单片机的都知道EEPROM是什么东西,或许一说到很多人都会想到24C02这片子,但这东西只有2K,而且与单片机分离的IC传输速度明显较慢。
另外很多初学者可能认为数据就这么传进EEPROM就算是完成任务了,但实际EEPROM并不是这么用着的,以一片EEPROM 资料称能存储10万次的算,假若程序设置的是一秒一次存储,3600S/h 30个小时就做了108000次存储,基本达到报废这EEPROM的条件了。