www.pudn.com > at89c2051pro.rar > AT89C2051PRO.C


/////////////////////////////////////////////////////////////////////////////////////////////////// 
//FID=01:AT89C2051系列编程器 
//实现编程的读,写,擦等细节 
//AT89C2051的特殊处:给XTAL一个脉冲,地址计数加1;P1的引脚排列与AT89C51相反,需要用函数转换 
/////////////////////////////////////////////////////////////////////////////////////////////////// 
#include  
#include  
 
#define C2051_P3_7	P2_3 
#define C2051_RSTL	P3_3 
#define C2051_RSTH	P3_4 
 
#define C2051_P1	P0//注意引脚排列相反 
#define C2051_P3_0 	P1_1 
#define C2051_P3_1	P1_2 
#define C2051_XTAL	P1_4 
#define C2051_P3_2	P1_5 
#define C2051_P3_3	P1_6 
#define C2051_P3_4	P1_7 
#define C2051_P3_5	P1_0 
 
#define C2051_GND	P2_4 
 
extern bit Is12Vpp; 
 
void InitPro01()//编程前的准备工作 
{ 
	SetP10Vpp0V(); 
	SetVpp5V(); 
	P0=0xff; 
	P1=0xff; 
	C2051_P3_5=1; 
	C2051_XTAL=0; 
	Delay_ms(20); 
	nAddress=0x0000; 
	SetP10Vpp5V(); 
} 
 
void ProOver01()//编程结束后的工作,设置合适的引脚电平 
{ 
	SetP10Vpp5V(); 
	P0=0xff; 
	P1=0xff; 
	C2051_P3_5=1; 
	C2051_XTAL=1; 
} 
 
BYTE GetData()//从P0口获得数据 
{ 
	B_0=P0_7; 
	B_1=P0_6; 
	B_2=P0_5; 
	B_3=P0_4; 
	B_4=P0_3; 
	B_5=P0_2; 
	B_6=P0_1; 
	B_7=P0_0; 
	return B; 
} 
 
void SetData(BYTE DataByte)//转换并设置P0口的数据 
{ 
	B=DataByte; 
	P0_0=B_7; 
	P0_1=B_6; 
	P0_2=B_5; 
	P0_3=B_4; 
	P0_4=B_3; 
	P0_5=B_2; 
	P0_6=B_1; 
	P0_7=B_0; 
} 
 
void ReadSign01()//读特征字 
{ 
	InitPro01(); 
	Delay_ms(1); 
//----------------------------------------------------------------------------- 
	//根据器件的DataSheet,设置相应的编程控制信号 
	C2051_P3_3=0; 
	C2051_P3_4=0; 
	C2051_P3_5=0; 
	C2051_P3_7=0; 
	Delay_ms(20); 
	ComBuf[2]=GetData(); 
	C2051_XTAL=1; 
	C2051_XTAL=0; 
	Delay_us(20); 
	ComBuf[3]=GetData(); 
	ComBuf[4]=0xff; 
//----------------------------------------------------------------------------- 
	ProOver01(); 
} 
 
void Erase01()//擦除器件 
{ 
	InitPro01(); 
//----------------------------------------------------------------------------- 
	//根据器件的DataSheet,设置相应的编程控制信号 
	C2051_P3_3=1; 
	C2051_P3_4=0; 
	C2051_P3_5=0; 
	C2051_P3_7=0; 
	Delay_ms(1); 
	SetP10Vpp12V(); 
	Delay_ms(1); 
	C2051_P3_2=0; 
	Delay_ms(10); 
	C2051_P3_2=1; 
	Delay_ms(1); 
//----------------------------------------------------------------------------- 
	ProOver01(); 
} 
 
BOOL Write01(BYTE Data)//写器件 
{ 
//----------------------------------------------------------------------------- 
	//根据器件的DataSheet,设置相应的编程控制信号 
	//写一个单元 
	C2051_P3_3=0; 
	C2051_P3_4=1; 
	C2051_P3_5=1; 
	C2051_P3_7=1; 
	SetData(Data); 
	SetP10Vpp12V(); 
	Delay_us(40); 
	C2051_P3_2=0; 
	Delay_us(40); 
	C2051_P3_2=1; 
	Delay_us(40); 
	SetP10Vpp5V(); 
	Delay_us(40); 
	C2051_P3_4=0; 
	Delay_ms(4); 
	nTimeOut=0; 
	P0=0xff; 
	nTimeOut=0; 
	while(!GetData()==Data)//效验:循环读,直到读出与写入的数相同 
	{ 
		nTimeOut++; 
		if(nTimeOut>2000)//超时了 
		{ 
			return 0; 
		} 
	} 
	C2051_XTAL=1; 
	_nop_(); 
	C2051_XTAL=0;//一个脉冲指向下一个单元 
	_nop_(); 
//----------------------------------------------------------------------------- 
	return 1; 
} 
 
BYTE Read01()//读器件 
{ 
	BYTE Data; 
//----------------------------------------------------------------------------- 
	//根据器件的DataSheet,设置相应的编程控制信号 
	//读一个单元 
	C2051_P3_3=0; 
	C2051_P3_4=0; 
	C2051_P3_5=1; 
	C2051_P3_7=1; 
	Data=GetData(); 
	C2051_XTAL=1; 
	C2051_XTAL=0;//一个脉冲指向下一个单元 
//----------------------------------------------------------------------------- 
	return Data; 
} 
 
void Lock01()//写锁定位 
{ 
	InitPro01();//先设置成编程状态 
//----------------------------------------------------------------------------- 
	//根据器件的DataSheet,设置相应的编程控制信号 
	if(ComBuf[2]>=1)//ComBuf[2]为锁定位 
	{ 
		C2051_P3_3=1; 
		C2051_P3_4=1; 
		C2051_P3_5=1; 
		C2051_P3_7=1; 
		Delay_us(20); 
		SetP10Vpp12V(); 
		Delay_us(20); 
		C2051_P3_2=0; 
		Delay_us(20); 
		C2051_P3_2=1; 
		Delay_us(20); 
		SetP10Vpp5V(); 
	} 
	if(ComBuf[2]>=2) 
	{ 
		C2051_P3_3=1; 
		C2051_P3_4=1; 
		C2051_P3_5=0; 
		C2051_P3_7=0; 
		Delay_us(20); 
		SetP10Vpp12V(); 
		Delay_us(20); 
		C2051_P3_2=0; 
		Delay_us(20); 
		C2051_P3_2=1; 
		Delay_us(20); 
		SetP10Vpp5V(); 
	} 
//----------------------------------------------------------------------------- 
	ProOver01(); 
} 
 
void PreparePro01() 
{ 
	pw.fpSetAddress=0x00; 
	pw.fpInitPro=InitPro01; 
	pw.fpReadSign=ReadSign01; 
	pw.fpErase=Erase01; 
	pw.fpWrite=Write01; 
	pw.fpRead=Read01; 
	pw.fpLock=Lock01; 
	pw.fpProOver=ProOver01; 
}