www.pudn.com > at89c51pro.rar > AT89C51PRO.C


/////////////////////////////////////////////////////////////////////////////////////////////////// 
//FID=00:AT89C51系列编程器 
//实现编程的读,写,擦等细节 
/////////////////////////////////////////////////////////////////////////////////////////////////// 
 
#include  
 
#define MCU_RST		P1_0 
#define MCU_OECtrl	P3_3 
#define MCU_PSEN	P2_1 
 
unsigned char PrepareType; 
bit Is12Vpp; 
 
void SetLAddrData(BYTE DataByte)//转换并设置P1口的数据 
{ 
	B=DataByte; 
	P1_1=B_1; 
	P1_2=B_2; 
	P1_3=B_3; 
	P1_4=B_4; 
	P1_5=B_5; 
	P1_6=B_6; 
	P1_7=B_7; 
	if(B_0) 
		SetP10Vpp5V(); 
	else 
		SetP10Vpp0V(); 
} 
 
void SetHAddrData(BYTE DataByte)//转换并设置P2口的数据 
{ 
	P2_0=0; 
	B=DataByte; 
	P2_5=B_7;//P3.5 
	P2_0=1; 
	P2_0=0; 
	P2_5=B_6;//P3.4 
	P2_0=1; 
	P2_0=0; 
	P2_5=1;//P3.2 
	P2_0=1; 
	P2_0=0; 
	P2_5=1;//P3.1 
	P2_0=1; 
	P2_0=0; 
	P2_5=B_1;//P2.1 
	P2_0=1; 
	P2_0=0; 
	P2_5=B_2;//P2.2 
	P2_0=1; 
	P2_0=0; 
	P2_5=B_3;//P2.3 
	P2_0=1; 
	P2_0=0; 
	P2_5=B_4;//P2.4 
	P2_0=1; 
	P2_0=B_0;//P2.0 
	P2_5=B_5;//P2.5 
} 
 
DeiveInit03() 
{ 
	Delay_ms(1); 
	MCU_PSEN = 0; 
	Delay_ms(1); 
	P2_6=0; 
	P2_7=0; 
	P3_7=0; 
	P3_6=0; 
	Delay_ms(1); 
	nAddress=0x0030; 
	SetLAddrData(((BYTE*)(&nAddress))[1]);//低地址 
	SetHAddrData(((BYTE*)(&nAddress))[0]);//高地址 
	nAddress=0x0000; 
	P0=0xff; 
} 
 
void InitPro00()//编程前的准备工作 
{ 
	SetVpp5V(); 
	SetP10Vpp5V(); 
	MCU_OECtrl = 1; 
	P0=0xff; 
	P1=0xff; 
	P2=0xff; 
//	MCU_PSEN = 0; 
	SetHAddrData(0xff); 
	MCU_RST=1;//p3.5接RST 
	P3_2=1;//p3.2接PROG 
	P2_6=0;//先置成读模式 
	P2_7=0; 
	P3_6=1; 
	P3_7=1; 
	MCU_PSEN = 0; 
	nAddress=0x0000; 
	SetLAddrData(0xff); 
	SetHAddrData(0xff); 
} 
 
void ProOver00()//编程结束后的工作,设置合适的引脚电平 
{ 
	SetVpp5V(); 
	SetP10Vpp5V(); 
	MCU_OECtrl = 1; 
	P0=0xff; 
	P1=0xff; 
	P2=0x3f; 
	MCU_PSEN = 0; 
	SetHAddrData(0xff); 
	P2_6=0; 
	P2_7=0; 
	P3_6=1; 
	P3_7=1; 
	MCU_RST=0;//RST=0; 
	P3_2=0;//PROG=0 
	SetLAddrData(0xff); 
	SetHAddrData(0xff); 
	MCU_PSEN = 1; 
	P0=0xff; 
} 
 
void ReadSign00()//读特征字 
{ 
	InitPro00();//先设置成编程状态 
	Delay_ms(1); 
//----------------------------------------------------------------------------- 
	//根据器件的DataSheet,设置相应的编程控制信号 
	P2_6=0; 
	P2_7=0; 
	P3_7=0;/// 
	P3_6=0; 
	nAddress=0x0030; 
	SetLAddrData(((BYTE*)(&nAddress))[1]);//低地址 
	SetHAddrData(((BYTE*)(&nAddress))[0]);//高地址 
	P0=0xff; 
	ComBuf[2]=P0;//读第1个特征字 
	nAddress=0x0031; 
	SetLAddrData(((BYTE*)(&nAddress))[1]); 
	SetHAddrData(((BYTE*)(&nAddress))[0]); 
	ComBuf[3]=P0;//读第2个特征字 
	nAddress=0x0032; 
	SetLAddrData(((BYTE*)(&nAddress))[1]); 
	SetHAddrData(((BYTE*)(&nAddress))[0]); 
	P0=0xff; 
	ComBuf[4]=P0;//读第3个特征字 
//----------------------------------------------------------------------------- 
	ProOver00();//操作结束设置为运行状态 
} 
 
void ReadSign04()//读特征字 
{ 
	InitPro00();//先设置成编程状态 
	if(PrepareType == 0x04) 
		MCU_OECtrl = 0; 
	Delay_ms(1); 
//----------------------------------------------------------------------------- 
	//根据器件的DataSheet,设置相应的编程控制信号 
	P2_6=0; 
	P2_7=0; 
	P3_7=0; 
	P3_6=0; 
	nAddress=0x0000; 
	SetLAddrData(((BYTE*)(&nAddress))[1]);//低地址 
	SetHAddrData(((BYTE*)(&nAddress))[0]);//高地址 
	ComBuf[2]=P0;//读第1个特征字 
	nAddress=0x0100; 
	SetLAddrData(((BYTE*)(&nAddress))[1]); 
	SetHAddrData(((BYTE*)(&nAddress))[0]); 
	ComBuf[3]=P0;//读第2个特征字 
	nAddress=0x0200; 
	SetLAddrData(((BYTE*)(&nAddress))[1]); 
	SetHAddrData(((BYTE*)(&nAddress))[0]); 
	ComBuf[4]=P0;//读第3个特征字 
//----------------------------------------------------------------------------- 
	ProOver00();//操作结束设置为运行状态 
} 
 
void Erase00()//擦除器件 
{ 
	InitPro00(); 
	if(PrepareType == 0x03) 
	{ 
		DeiveInit03(); 
		Delay_ms(1); 
	} 
	//根据器件的DataSheet,设置相应的编程控制信号 
	P2_6=1; 
	P2_7=0; 
	P3_6=0; 
	P3_7=0; 
	Delay_ms(1); 
	if(Is12Vpp) 
		SetVpp12V(); 
	else 
		SetVpp5V(); 
	Delay_ms(1); 
	P3_2=0; 
	Delay_ms(10); 
	P3_2=1; 
	Delay_ms(1); 
//----------------------------------------------------------------------------- 
	ProOver00(); 
} 
 
BOOL Write00(BYTE Data)//向器件写一个字节 
{ 
	if(PrepareType == 0x03) 
		if(nAddress == 0) 
			DeiveInit03(); 
	if(Data != 0xff) 
	{ 
		//根据器件的DataSheet,设置相应的编程控制信号 
		//写一个单元 
		SetHAddrData(((BYTE*)(&nAddress))[0]);//高地址 
		SetLAddrData(((BYTE*)(&nAddress))[1]);//低地址 
		P2_6=0; 
		P2_7=1; 
		P3_6=1; 
		P3_7=1; 
		P3_2=1;//ALE 
		P0=Data; 
		if(Is12Vpp) 
			SetVpp12V(); 
		else 
			SetVpp5V(); 
		Delay_us(20); 
		P3_2=0;//ALE 
		Delay_us(20); 
		P3_2=1;//ALE 
		Delay_us(20); 
		SetVpp5V(); 
		Delay_us(20); 
		P2_7=0; 
		Delay_ms(2); 
		nTimeOut=0; 
		P0=0xff; 
		nTimeOut=0; 
		while(P0!=Data)//效验:循环读,直到读出与写入的数相同 
		{ 
			nTimeOut++; 
			if(nTimeOut>1000)//超时了,写失败 
			{ 
				return 0; 
			} 
					 
		} 
	} 
	return 1; 
//----------------------------------------------------------------------------- 
} 
 
BYTE Read00()//从器件读一个字节 
{ 
	if(PrepareType == 0x03) 
	{ 
		if(nAddress == 0) 
		{ 
			DeiveInit03(); 
			P2_6=0; 
			P2_7=0; 
			P3_6=1; 
			P3_7=1; 
		}; 
	} 
	else 
	{ 
		if(PrepareType == 0x04) 
			MCU_OECtrl = 0; 
		P2_6=0; 
		P2_7=0; 
		P3_6=1; 
		P3_7=1; 
	} 
	SetLAddrData(((BYTE*)(&nAddress))[1]);//低地址 
	SetHAddrData(((BYTE*)(&nAddress))[0]);//高地址 
	P0= 0xff; 
	return P0; 
} 
 
void Lock00()//写锁定位 
{ 
	InitPro00(); 
	if(PrepareType == 0x03) 
		DeiveInit03(); 
	//根据器件的DataSheet,设置相应的编程控制信号 
	if(ComBuf[2]==1)//ComBuf[2]为锁定位 
	{//SB1,LB1 
		P2_6=1; 
		P2_7=1; 
		P3_6=1; 
		P3_7=1; 
		Delay_us(20); 
		if(Is12Vpp) 
			SetVpp12V(); 
		else 
			SetVpp5V(); 
		Delay_us(20); 
		P3_2=0; 
		Delay_us(20); 
		P3_2=1; 
		Delay_us(20); 
		SetVpp5V(); 
	} 
	if(ComBuf[2]==2) 
	{//SB2,LB2 
		P2_6=1; 
		P2_7=1; 
		P3_6=0; 
		P3_7=0; 
		Delay_us(20); 
		if(Is12Vpp) 
			SetVpp12V(); 
		else 
			SetVpp5V(); 
		Delay_us(20);  
		P3_2=0; 
		Delay_us(20); 
		P3_2=1; 
		Delay_us(20); 
		SetVpp5V(); 
	} 
	if(ComBuf[2]==3) 
	{//SB3,LB3 
		P2_6=1; 
		P2_7=0; 
		P3_6=1; 
		P3_7=0; 
		Delay_us(20); 
		if(Is12Vpp) 
			SetVpp12V(); 
		else 
			SetVpp5V(); 
		Delay_us(20); 
		P3_2=0; 
		Delay_us(20); 
		P3_2=1; 
		Delay_us(20); 
		SetVpp5V(); 
	} 
	if(ComBuf[2]==4) 
	{//RB0 
		P2_6=0; 
		P2_7=0; 
		P3_6=0; 
		P3_7=1; 
		Delay_us(20); 
		if(Is12Vpp) 
			SetVpp12V(); 
		else 
			SetVpp5V(); 
		Delay_us(20); 
		P3_2=0; 
		Delay_us(20); 
		P3_2=1; 
		Delay_us(20); 
		SetVpp5V(); 
	} 
	if(ComBuf[2]==5) 
	{//RB1 
		P2_6=1; 
		P2_7=0; 
		P3_6=0; 
		P3_7=1; 
		Delay_us(20); 
		if(Is12Vpp) 
			SetVpp12V(); 
		else 
			SetVpp5V(); 
		Delay_us(20); 
		P3_2=0; 
		Delay_us(20); 
		P3_2=1; 
		Delay_us(20); 
		SetVpp5V(); 
	} 
	ProOver00(); 
} 
 
void SetAddress00()//设置地址 
{ 
	((BYTE*)(&nAddress))[0] = ComBuf[2]; 
	((BYTE*)(&nAddress))[1] = ComBuf[3]; 
} 
 
void PreparePro00()//设置pw中的函数指针,让主程序可以调用上面的函数 
{ 
	pw.fpSetAddress=0x00; 
	Is12Vpp = 1; 
	PrepareType = 0; 
	pw.fpInitPro=InitPro00; 
	pw.fpReadSign=ReadSign00; 
	pw.fpErase=Erase00; 
	pw.fpWrite=Write00; 
	pw.fpRead=Read00; 
	pw.fpLock=Lock00; 
	pw.fpProOver=ProOver00; 
} 
 
void PreparePro03() 
{ 
	PreparePro00(); 
	pw.fpSetAddress=SetAddress00; 
	Is12Vpp = 0; 
	PrepareType = 3; 
} 
 
void PreparePro04() 
{ 
	PreparePro00(); 
//	Is12Vpp = 1; 
	PrepareType = 4; 
	pw.fpReadSign=ReadSign04; 
}