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

📄 s51.c

📁 笔者的《用M8L制作的89S51单片机 USB下载线》在无线电2007年第9期已刊登过
💻 C
字号:
///////////////////////////////////////////////////////////////////////////////////////////////////
//FID=02:AT89S51系列编程器 
//实现编程的读,写,擦等细节
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <iom8v.h>
#include <macros.h>
#include<signal.h>
#include<e51pro.h>
#define uchar unsigned char 
BYTE OutBuf[4];//发送命令缓冲
BYTE InBuf[4];//接收缓冲
void SendInstrc(uchar nByte)//用MOSI串行发送命令的同时用MISO接收相关数据
{
uchar n=0;
DDRB=(1<<PB5)|(1<<PB3)|(1<<PB2);
SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0);//SCK时钟为fosc/16
for (n=0;n<nByte;n++)
{
SPDR=OutBuf[n];
while (!(SPSR&(1<<SPIF)))
;
InBuf[n]=SPDR;
}
}
void InitPro02()//编程前的准备工作
{
DDRB=0xff;
PORTB&=~BIT(PB2);
Delay_ms(10);
PORTB|=BIT(PB2);
PORTC|=BIT(PB1);
PORTC&=~BIT(PB0);
Delay_ms(10);
nAddress=0x0000;
OutBuf[0]=0xac;//正好在这里可以安排DataSheet上所规定的
OutBuf[1]=0x53;//Eanable Programming命令
OutBuf[2]=0;
OutBuf[3]=0;
SendInstrc(4);
}

void ProOver02()//编程结束后的工作,设置合适的引脚电平
{
PORTC|=BIT(PB0);
PORTC&=~BIT(PB1);
DDRB=0x00;
}
uchar ComBuf[18];
uchar Read02()
{
OutBuf[0]=0x20;
OutBuf[1]=((uchar*)&nAddress)[1];
OutBuf[2]=((uchar*)&nAddress)[0];
SendInstrc(4);
return InBuf[3];
}

void ReadSign02()//读特征字
{
	InitPro02();//先设置成编程状态
//-----------------------------------------------------------------------------
	//根据器件的DataSheet,设置相应的编程控制信号
	OutBuf[0]=0x28;
	OutBuf[1]=0x00;
	OutBuf[2]=0x00;
	OutBuf[3]=0x00;
	SendInstrc(4);
	ComBuf[2]=InBuf[3];
	OutBuf[1]=0x01;
	SendInstrc(4);
	ComBuf[3]=InBuf[3];
	OutBuf[1]=0x02;
	SendInstrc(4);
	ComBuf[4]=InBuf[3];
//-----------------------------------------------------------------------------
	ProOver02();
}

void Erase02()//擦除器件
{
	InitPro02();
//-----------------------------------------------------------------------------
	//根据器件的DataSheet,设置相应的编程控制信号
	OutBuf[0]=0xac;
	OutBuf[1]=0x80;
	SendInstrc(4);
	Delay_ms(50);	
//-----------------------------------------------------------------------------
	ProOver02();
}

BOOL Write02(BYTE Data)//写器件
{

//-----------------------------------------------------------------------------
	//根据器件的DataSheet,设置相应的编程控制信号
	//写一个单元
	OutBuf[0]=0x40;
	OutBuf[1]=((BYTE*)&nAddress)[1];
	OutBuf[2]=((BYTE*)&nAddress)[0];
	OutBuf[3]=Data;
	SendInstrc(4);
	nTimeOut=0;
	while(Read02()!=Data)//效验:循环读,直到读出与写入的数相同
	{
		nTimeOut++;
		if(nTimeOut>1000)//超时了
		{
			return  0;
		}
				
	}
//-----------------------------------------------------------------------------
	return 1;
}
void Lock02()//写锁定位
{
//-----------------------------------------------------------------------------
	//根据器件的DataSheet,设置相应的编程控制信号
	if(ComBuf[2]>=1)//ComBuf[2]为锁定位
	{
		InitPro02();
		OutBuf[0]=0xac;
		OutBuf[1]=0xe1;
		SendInstrc(4);
		Delay_ms(1);
	}
	if(ComBuf[2]>=2)
	{
		InitPro02();
		OutBuf[0]=0xac;
		OutBuf[1]=0xe2;
		SendInstrc(4);
		Delay_ms(1);
	}
	if(ComBuf[2]==3)
	{
		InitPro02();
		OutBuf[0]=0xac;
		OutBuf[1]=0xe3;
		SendInstrc(4);
		Delay_ms(1);
	}
//-----------------------------------------------------------------------------
	ProOver02();
}
void PreparePro02()//设置pw中的函数指针,让主程序可以调用上面的函数
{
	pw.fpInitPro=InitPro02;
	pw.fpReadSign=ReadSign02;
	pw.fpErase=Erase02;
	pw.fpWrite=Write02;
	pw.fpRead=Read02;
	pw.fpLock=Lock02;
	pw.fpProOver=ProOver02;
}

⌨️ 快捷键说明

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