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

📄 at89c2051pro.c

📁 AT89系列单片机ISP在线编程的AT89C2051的源代码
💻 C
字号:
///////////////////////////////////////////////////////////////////////////////////////////////////
//FID=01:AT89C2051系列编程器
//实现编程的读,写,擦等细节
//AT89C2051的特殊处:给XTAL一个脉冲,地址计数加1;P1的引脚排列与AT89C51相反,需要用函数转换
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <e51pro.h>

#define C2051_P3_7	P1_0
#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	P3_5
 
void InitPro01()//编程前的准备工作
{
	SetVpp0V();
	P0=0xff;
	P1=0xff;
	C2051_P3_5=1;
	C2051_XTAL=0;
	Delay_ms(20);
	nAddress=0x0000;
	SetVpp5V();
}

void ProOver01()//编程结束后的工作,设置合适的引脚电平
{
	SetVpp5V();
	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);
	SetVpp12V();
	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);
	SetVpp12V();
	Delay_us(20);
	C2051_P3_2=0;
	Delay_us(20);
	C2051_P3_2=1;
	Delay_us(20);
	SetVpp5V();
	Delay_us(20);
	C2051_P3_4=0;
	Delay_ms(2);
	nTimeOut=0;
	P0=0xff;
	nTimeOut=0;
	while(!GetData()==Data)//效验:循环读,直到读出与写入的数相同
	{
		nTimeOut++;
		if(nTimeOut>1000)//超时了
		{
			return 0;
		}
	}
	C2051_XTAL=1;
	C2051_XTAL=0;//一个脉冲指向下一个单元
//-----------------------------------------------------------------------------
	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);
		SetVpp12V();
		Delay_us(20);
		C2051_P3_2=0;
		Delay_us(20);
		C2051_P3_2=1;
		Delay_us(20);
		SetVpp5V();
	}
	if(ComBuf[2]>=2)
	{
		C2051_P3_3=1;
		C2051_P3_4=1;
		C2051_P3_5=0;
		C2051_P3_7=0;
		Delay_us(20);
		SetVpp12V();
		Delay_us(20);
		C2051_P3_2=0;
		Delay_us(20);
		C2051_P3_2=1;
		Delay_us(20);
		SetVpp5V();
	}
//-----------------------------------------------------------------------------
	ProOver01();
}

void PreparePro01()//设置pw中的函数指针,让主程序可以调用上面的函数
{
	pw.fpInitPro=InitPro01;
	pw.fpReadSign=ReadSign01;
	pw.fpErase=Erase01;
	pw.fpWrite=Write01;
	pw.fpRead=Read01;
	pw.fpLock=Lock01;
	pw.fpProOver=ProOver01;
}

⌨️ 快捷键说明

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