毕业设计后记
M3板设计

关于STC系列51单片机的EEPROM应用

G-one posted @ 2010年6月22日 17:20 in program , 5443 阅读

EEPROM都知道,做单片机的都知道EEPROM是什么东西,或许一说到很多人都会想到24C02这片子,但这东西只有2K,而且与单片机分离的IC传输速度明显较慢。 另外很多初学者可能认为数据就这么传进EEPROM就算是完成任务了,但实际EEPROM并不是这么用着的,以一片EEPROM 资料称能存储10万次的算,假若程序设置的是一秒一次存储,3600S/h  30个小时就做了108000次存储,基本达到报废这EEPROM的条件了。所以EEPROM 一般是做存储的数据保存后,产品需要做断电存储的功能,这样才能实现再次启动产品后使用上一次状态中的数据。因此EEPROM的存储设定要有条件式的触发。

在我最近做的一个小项目中,客户要求希望产品能在断电后的再次上电后做断电前的动作,这样断电便成了这个存储的触发条件,断电后的供电模式有两种一种是电池式供电,一种采用大电容供电。存储数据量小的话当然是电容供电的更好啦。然而这又会出现断电后的一个低压工作问题,一般5V单片机最低工作电压能有3.8左右。但EEPROM通常需要4.1V以上,这样片外存储的时间很可能会跟不上。如今单片机很多都集成了片内存储的EEPROM,存储速度远远高于片外存储十几倍,电容放电的瞬间完全可以胜任。网上实在太少这方面的资料和例子了,琢磨了一番STC的几个单片机后发现同一品牌的单片机内部EEPROM存储模式打进相同。在这我就放出一个STC 单片机内部EEPROM的例子,童鞋们可以根据片内的寄存器与相应的控制位修改即可使用,强调这只能使用与STC的 一部分单片机,主要有STC11FXX 系列、STC10FXX系列、STC125AXX系列、STC89C5X系列....... 其他的没试过,但只要对比资料结构大体相同都可使用。

贴程序:

 我这是做成一个头文件方便使用的

ifndef __EEPROM_H__
#define __EEPROM_H__

#include<reg51.h>
#include <intrins.h>

#define uchar unsigned char  
#define uint unsigned int 

sfr ISP_DATA = 0XC2;
sfr	ISP_ADDH = 0XC3;
sfr ISP_ADDL = 0XC4;
sfr ISP_CMD  = 0XC5;
sfr ISP_TRIG = 0XC6;
sfr ISP_CONTR= 0XC7;

#define RED_ISP 0X01
#define WITE_ISP 0x02
#define ERASE_ISP 0X03

#define MCU_CLOCK_5MHz 0x04
#define MCU_CLOCK_12MHz 0x03
#define MCU_CLOCK_20MHz 0x02
#define MCU_CLOCK_24MHz 0x01



/****************************************
打开ISP
*****************************************/

extern void ISP_EN(void)
{
	EA=0;
	ISP_CONTR=ISP_CONTR&0x08;
	ISP_CONTR=ISP_CONTR|MCU_CLOCK_12MHz;
	ISP_CONTR=ISP_CONTR|0x80;

}
/****************************************
关闭ISP
*****************************************/
extern void ISP_DIS(void)
{
	ISP_CONTR=ISP_CONTR&0x07;
	ISP_TRIG=0X00;
}

/****************************************
读取一BYTE
*****************************************/
extern uchar  Read_ISP(uint bite_addr)
{
	uchar DATA;
	ISP_ADDH=(uchar)(bite_addr>>8);
	ISP_ADDL=(uchar)(bite_addr&0x00ff);

	ISP_CMD=ISP_CMD&0xF8;
	ISP_CMD=ISP_CMD|RED_ISP;

	ISP_EN();

	ISP_TRIG=0X5A;
	ISP_TRIG=0XA5;
	_nop_();
	_nop_();
	ISP_DIS();

	DATA=ISP_DATA;
	return DATA;

}

/****************************************
写入一BYTE
*****************************************/
extern void Write_ISP (uint bite_addr,uchar DATA)
{
	
	ISP_ADDH=(uchar)(bite_addr>>8);
	ISP_ADDL=(uchar)(bite_addr&0x00ff);

	ISP_CMD=ISP_CMD&0xF8;
	ISP_CMD=ISP_CMD|WITE_ISP;
	ISP_DATA=DATA;

	ISP_EN();

	ISP_TRIG=0X5A;
	ISP_TRIG=0XA5;
	_nop_();
	_nop_();
	ISP_DIS();
	
}

/****************************************
擦除扇区
*****************************************/
extern void ERASE(uint addr)
{
	ISP_ADDH=(uchar)(addr>>8);
	ISP_ADDL=0x00;

	ISP_CMD=ISP_CMD&0xF8;
	ISP_CMD=ISP_CMD|ERASE_ISP;

	ISP_EN();

	ISP_TRIG=0X5A;
	ISP_TRIG=0XA5;
	_nop_();
	_nop_();
	ISP_DIS();
	
	
}

/*****************************************
连续写入
******************************************/
extern void Write_FLASH(uint bit_addr,uchar count,uchar *dat)
{
	uchar i;
	uchar add;
	add=bit_addr;
	ERASE(bit_addr);
	for(i=0;i<count;i++)
	{
	 Write_ISP(add,*dat);
	 dat++;
	 add++;
	}

}

#endif 

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter