⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at89c51pro.c

📁 AT89s51 串行编程器源代码
💻 C
字号:
///////////////////////////////////////////////////////////////////////////////////////////////////
//FID=00:AT89C51系列编程器
//实现编程的读,写,擦等细节
///////////////////////////////////////////////////////////////////////////////////////////////////

#include <e51pro.h>

#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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -