编程器程序.docx
《编程器程序.docx》由会员分享,可在线阅读,更多相关《编程器程序.docx(22页珍藏版)》请在冰点文库上搜索。
编程器程序
#include<>
typedefunsignedintUINT;
typedefunsignedlongULONG;
typedefunsignedcharBYTE;
typedefbitBOOL;
sbitP3_2=P3^2;
sbitP3_5=P3^5;
sbitP3_6=P3^6;
sbitP3_7=P3^7;
sbitP1_5=P1^5;
sbitP1_6=P1^6;
sbitP1_7=P1^7;
sbitA_0=ACC^0;//方便位操作
sbitA_1=ACC^1;
sbitA_2=ACC^2;
sbitA_3=ACC^3;
sbitA_4=ACC^4;
sbitA_5=ACC^5;
sbitA_6=ACC^6;
sbitA_7=ACC^7;
sbitB_0=B^0;//方便位操作
sbitB_1=B^1;
sbitB_2=B^2;
sbitB_3=B^3;
sbitB_4=B^4;
sbitB_5=B^5;
sbitB_6=B^6;
sbitB_7=B^7;
struct_prowork//概念编程器的一般操作,具体器件的编程器实现下列函数
{
void(*fpInitPro)();//编程前的预备工作
void(*fpReadSign)();//读特征字
void(*fpErase)();//擦除器件
BOOL(*fpWrite)(BYTE);//写器件
BYTE(*fpRead)();//读器件
void(*fpLock)();//写锁定位
void(*fpProOver)();//编程结束后的工作
};
typedefstruct_proworkProWork;
BYTEComBuf[18];//串口通信数据缓存,发送和接收都利用
UINTnAddress;//ROM中地址计数
UINTnTimeOut;//超时计数
ProWorkpw;//编程器一般操作
voidDelay_us(BYTEnUs)//微秒级延时<255us
TH0=0;
TL0=0;
TR0=1;
while(TL0{}TR0=0;}voidDelay_ms(UINTnMs)//豪秒级的延时<65535ms{UINTn=0;TR0=1;while(n{TH0=0;TL0=20;while(TH0<4){}n++;}TR0=0;}BOOLWaitComm()//等待上位机的命令,18字节{BYTEn=0;RI=0;while(!RI){}//等待第一个字节ComBuf[n]=SBUF;RI=0;n++;for(n;n<=17;n++){nTimeOut=0;while(!RI){nTimeOut++;if(nTimeOut>10000)//后17个字节都有超时限制return0;}ComBuf[n]=SBUF;RI=0;}return1;}BOOLWaitResp()//等待上位机回应,1字节,有超时限制{nTimeOut=0;RI=0;while(!RI){nTimeOut++;if(nTimeOut>50000){return0;}}RI=0;ComBuf[0]=SBUF;return1;}BOOLWaitData()//写器件时等待上位机数据,18字节,有超时限制{BYTEn;RI=0;for(n=0;n<=17;n++){nTimeOut=0;while(!RI){nTimeOut++;if(nTimeOut>10000){return0;}}RI=0;ComBuf[n]=SBUF;}return1;}voidSendData()//发送数据或回应操作完成,18字节{BYTEn=0;for(n;n<=17;n++){TI=0;SBUF=ComBuf[n];while(!TI){}TI=0;}}voidSendResp()//回应上位机1个字节,在写器件函数中利用{TI=0;SBUF=ComBuf[0];while(!TI){}TI=0;}/*voidSetVpp5V()//设置Vpp为5v{P3_4=0;P3_3=0;}voidSetVpp0V()//设置Vpp为0v{P3_3=0;P3_4=1;}voidSetVpp12V()//设置Vpp为12v{P3_4=0;P3_3=1;}*/voidRstPro()//编程器复位{();//直接编程结束SendData();//通知上位机,表示编程器就绪,能够直接用此函数因为协议号(ComBuf[0])还没被修改,下同}voidReadSign()//读特征字{();SendData();//通知上位机,送出读出器件特征字}voidErase()//擦除器件{();SendData();//通知上位机,擦除器件}voidWrite()//写器件{BYTEn;();//编程前的预备工作SendData();//回应上位机表示进入写器件状态,能够发来数据while(1){if(WaitData())//若是等待数据成功{if(ComBuf[0]==0x07)//判断是不是继续写{for(n=2;n<=17;n++)//ComBuf[2~17]为待写入数据块{if(!(ComBuf[n]))//<<<<<<<<<<<<<<<<<<<挪用写该器件一个单元的函数{();//犯错了就结束编程ComBuf[0]=0xff;SendResp();//回应上位机一个字节,表示写数据犯错了WaitData();//等待上位机的回应后就结束return;}nAddress++;//下一个单元}ComBuf[0]=1;//回应上位机一个字节,表示数据块顺利完成,请求继续SendResp();}elseif(ComBuf[0]==0x00)//写器件结束break;else//可能是通信犯错了{();return;}}else//等待数据失败{();return;}}();//编程结束后的工作Delay_ms(50);//延时等待上位机写线程结束ComBuf[0]=0;//通知上位机编程器进入就绪状态SendData();}voidRead()//读器件{BYTEn;();//先设置成编程状态SendData();//回应上位机表示进入读状态while(1){if(WaitResp())//等待上位机回应1个字节{if(ComBuf[0]==0)//ComBuf[0]==0表示读结束{break;}elseif(ComBuf[0]==0xff)//0xff表示重发{nAddress=nAddress-0x0010;}for(n=2;n<=17;n++)//ComBuf[2~17]保留读出的数据块{ComBuf[n]=();//<<<<<<<<<<<<<<<<<<<挪用写该器件一个单元的函数nAddress++;//下一个单元}ComBuf[0]=6;//向上位机发送读出的数据块SendData();}elsebreak;//等待回应失败}();//操作结束设置为运行状态ComBuf[0]=0;//通知上位机编程器进入就绪状态SendData();}voidLock()//写锁定位{();SendData();}///////////////////////////////////////////////////////////////////所支持的FID,请在这里继续添加///////////////////////////////////////////////////////////////externvoidPreparePro00();//FID=00:AT89C51编程器externvoidPreparePro01();//FID=01:AT89C2051编程器externvoidPreparePro02();//FID=02:AT89S51编程器voidmain(){SP=0x60;//SetVpp5V();//先初始化Vpp为5vSCON=0x00;TCON=0x00;//PCON=0x00;//波特率*2IE=0x00;//TMOD:GATE|C/!T|M1|M0|GATE|C/!T|M1|M0//00100001TMOD=0x21;//T0用于延时程序TH1=0xff;TL1=0xff;//波特率28800*2,注意PCON//SCON:SM0|SM1|SM2|REN|TB8|RB8|TI|RI//01010000SCON=0x50;TR1=1;Delay_ms(1000);//延时1秒后编程器自举ComBuf[0]=0;SendData();while(1)//串口通讯采用查询方式{if(!WaitComm())//若是超时,通信犯错{Delay_ms(500);ComBuf[0]=0;//让编程器复位,使编程器就绪}switch(ComBuf[1])//按照FID设置(ProWork)pw中的函数指针{case0://at89c51编程器PreparePro00();break;case1://at89c2051编程器PreparePro01();break;case2://at89s51编程器PreparePro02();break;//case3:支持新器件时,请继续向下添加//break;//case4://break;default:ComBuf[0]=0xff;ComBuf[1]=0xff;//表示无效的操作break;}switch(ComBuf[0])//按照操作ID跳到不同的操作函数{case0x00:RstPro();//编程器复位break;case0x01:ReadSign();//读特征字break;case0x02:Erase();//擦除器件break;case0x03:Write();//写器件break;case0x04:Read();//读器件break;case0x05:Lock();//写锁定位break;default:SendData();break;}}}/////////////////////////////////////////////////////////////////////FID=02:AT89S51系列编程器//实现编程的读,写,擦等细节//特殊处:采用ISP编程方式,只需对,,,RST引脚控制;用MOSI串行发送死令的同时用MISO接收相关数据//SCK输出同步时钟脉冲///////////////////////////////////////////////////////////////////#include<>#defineMOSIP1_5#defineMISOP1_6#defineSCKP1_7BYTEOutBuf[4];//发送死令缓冲BYTEInBuf[4];//接收缓冲/*下面这一段是我Copy的*//*voidDelay_ms(UINTnMs)//豪秒级的延时<65535ms{UINTn=0;TR0=1;while(n{TH0=0;TL0=20;while(TH0<4){}n++;}TR0=0;}*/voidSendInstrc(BYTEnByte)//用MOSI串行发送死令的同时用MISO接收相关数据{BYTEn;for(n=0;n{ACC=OutBuf[n];SCK=0;MOSI=A_7;//低电平时输出一名SCK=1;B_7=MISO;//高电平时接收一名SCK=0;MOSI=A_6;SCK=1;B_6=MISO;SCK=0;MOSI=A_5;SCK=1;B_5=MISO;SCK=0;MOSI=A_4;SCK=1;B_4=MISO;SCK=0;MOSI=A_3;SCK=1;B_3=MISO;SCK=0;MOSI=A_2;SCK=1;B_2=MISO;SCK=0;MOSI=A_1;SCK=1;B_1=MISO;SCK=0;MOSI=A_0;SCK=1;B_0=MISO;SCK=0;InBuf[n]=B;}}voidInitPro02()//编程前的预备工作{//SetVpp5V();P3_5=0;//接RSTP3_2=1;//接PROGP0=0xff;P1=0xff;P2=0xff;Delay_ms(10);MOSI=0;MISO=1;SCK=1;P3_5=1;Delay_ms(10);nAddress=0x0000;OutBuf[0]=0xac;//正好在这里能够安排DataSheet上所规定的OutBuf[1]=0x53;//EanableProgramming命令OutBuf[2]=0;OutBuf[3]=0;SendInstrc(4);}voidProOver02()//编程结束后的工作,设置适合的引脚电平{//SetVpp5V();//P0=0xff;P1=0xff;//P2=0xff;P3_6=1;P3_7=1;P3_5=0;//RST=0;//P3_2=2;//PROG=0这时有问题}BYTERead02(){OutBuf[0]=0x20;OutBuf[1]=((BYTE*)&nAddress)[0];OutBuf[2]=((BYTE*)&nAddress)[1];SendInstrc(4);returnInBuf[3];}voidReadSign02()//读特征字{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();}voidErase02()//擦除器件{InitPro02();//-----------------------------------------------------//按照器件的DataSheet,设置相应的编程控制信号OutBuf[0]=0xac;OutBuf[1]=0x80;SendInstrc(4);Delay_ms(500);//-----------------------------------------------------ProOver02();}BOOLWrite02(BYTEData)//写器件{//-----------------------------------------------------//按照器件的DataSheet,设置相应的编程控制信号//写一个单元OutBuf[0]=0x40;OutBuf[1]=((BYTE*)&nAddress)[0];OutBuf[2]=((BYTE*)&nAddress)[1];OutBuf[3]=Data;SendInstrc(4);nTimeOut=0;while(Read02()!=Data)//效验:循环读,直到读出与写入的数相同{nTimeOut++;if(nTimeOut>1000)//超时了{return0;}}//-----------------------------------------------------return1;}voidLock02()//写锁定位{//------------------------------------------------//按照器件的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();}voidPreparePro02()//设置pw中的函数指针,让主程序能够挪用上面的函数{=InitPro02;=ReadSign02;=Erase02;=Write02;=Read02;=Lock02;=ProOver02;}
}
TR0=0;
voidDelay_ms(UINTnMs)//豪秒级的延时<65535ms
UINTn=0;
while(n{TH0=0;TL0=20;while(TH0<4){}n++;}TR0=0;}BOOLWaitComm()//等待上位机的命令,18字节{BYTEn=0;RI=0;while(!RI){}//等待第一个字节ComBuf[n]=SBUF;RI=0;n++;for(n;n<=17;n++){nTimeOut=0;while(!RI){nTimeOut++;if(nTimeOut>10000)//后17个字节都有超时限制return0;}ComBuf[n]=SBUF;RI=0;}return1;}BOOLWaitResp()//等待上位机回应,1字节,有超时限制{nTimeOut=0;RI=0;while(!RI){nTimeOut++;if(nTimeOut>50000){return0;}}RI=0;ComBuf[0]=SBUF;return1;}BOOLWaitData()//写器件时等待上位机数据,18字节,有超时限制{BYTEn;RI=0;for(n=0;n<=17;n++){nTimeOut=0;while(!RI){nTimeOut++;if(nTimeOut>10000){return0;}}RI=0;ComBuf[n]=SBUF;}return1;}voidSendData()//发送数据或回应操作完成,18字节{BYTEn=0;for(n;n<=17;n++){TI=0;SBUF=ComBuf[n];while(!TI){}TI=0;}}voidSendResp()//回应上位机1个字节,在写器件函数中利用{TI=0;SBUF=ComBuf[0];while(!TI){}TI=0;}/*voidSetVpp5V()//设置Vpp为5v{P3_4=0;P3_3=0;}voidSetVpp0V()//设置Vpp为0v{P3_3=0;P3_4=1;}voidSetVpp12V()//设置Vpp为12v{P3_4=0;P3_3=1;}*/voidRstPro()//编程器复位{();//直接编程结束SendData();//通知上位机,表示编程器就绪,能够直接用此函数因为协议号(ComBuf[0])还没被修改,下同}voidReadSign()//读特征字{();SendData();//通知上位机,送出读出器件特征字}voidErase()//擦除器件{();SendData();//通知上位机,擦除器件}voidWrite()//写器件{BYTEn;();//编程前的预备工作SendData();//回应上位机表示进入写器件状态,能够发来数据while(1){if(WaitData())//若是等待数据成功{if(ComBuf[0]==0x07)//判断是不是继续写{for(n=2;n<=17;n++)//ComBuf[2~17]为待写入数据块{if(!(ComBuf[n]))//<<<<<<<<<<<<<<<<<<<挪用写该器件一个单元的函数{();//犯错了就结束编程ComBuf[0]=0xff;SendResp();//回应上位机一个字节,表示写数据犯错了WaitData();//等待上位机的回应后就结束return;}nAddress++;//下一个单元}ComBuf[0]=1;//回应上位机一个字节,表示数据块顺利完成,请求继续SendResp();}elseif(ComBuf[0]==0x00)//写器件结束break;else//可能是通信犯错了{();return;}}else//等待数据失败{();return;}}();//编程结束后的工作Delay_ms(50);//延时等待上位机写线程结束ComBuf[0]=0;//通知上位机编程器进入就绪状态SendData();}voidRead()//读器件{BYTEn;();//先设置成编程状态SendData();//回应上位机表示进入读状态while(1){if(WaitResp())//等待上位机回应1个字节{if(ComBuf[0]==0)//ComBuf[0]==0表示读结束{break;}elseif(ComBuf[0]==0xff)//0xff表示重发{nAddress=nAddress-0x0010;}for(n=2;n<=17;n++)//ComBuf[2~17]保留读出的数据块{ComBuf[n]=();//<<<<<<<<<<<<<<<<<<<挪用写该器件一个单元的函数nAddress++;//下一个单元}ComBuf[0]=6;//向上位机发送读出的数据块SendData();}elsebreak;//等待回应失败}();//操作结束设置为运行状态ComBuf[0]=0;//通知上位机编程器进入就绪状态SendData();}voidLock()//写锁定位{();SendData();}///////////////////////////////////////////////////////////////////所支持的FID,请在这里继续添加///////////////////////////////////////////////////////////////externvoidPreparePro00();//FID=00:AT89C51编程器externvoidPreparePro01();//FID=01:AT89C2051编程器externvoidPreparePro02();//FID=02:AT89S51编程器voidmain(){SP=0x60;//SetVpp5V();//先初始化Vpp为5vSCON=0x00;TCON=0x00;//PCON=0x00;//波特率*2IE=0x00;//TMOD:GATE|C/!T|M1|M0|GATE|C/!T|M1|M0//00100001TMOD=0x21;//T0用于延时程序TH1=0xff;TL1=0xff;//波特率28800*2,注意PCON//SCON:SM0|SM1|SM2|REN|TB8|RB8|TI|RI//01010000SCON=0x50;TR1=1;Delay_ms(1000);//延时1秒后编程器自举ComBuf[0]=0;SendData();while(1)//串口通讯采用查询方式{if(!WaitComm())//若是超时,通信犯错{Delay_ms(500);ComBuf[0]=0;//让编程器复位,使编程器就绪}switch(ComBuf[1])//按照FID设置(ProWork)pw中的函数指针{case0://at89c51编程器PreparePro00();break;case1://at89c2051编程器PreparePro01();break;case2://at89s51编程器PreparePro02();break;//case3:支持新器件时,请继续向下添加//break;//case4://break;default:ComBuf[0]=0xff;ComBuf[1]=0xff;//表示无效的操作break;}switch(ComBuf[0])//按照操作ID跳到不同的操作函数{case0x00:RstPro();//编程器复位break;case0x01:ReadSign();//读特征字break;case0x02:Erase();//擦除器件break;case0x03:Write();//写器件break;case0x04:Read();//读器件break;case0x05:Lock();//写锁定位break;default:SendData();break;}}}/////////////////////////////////////////////////////////////////////FID=02:AT89S51系列编程器//实现编程的读,写,擦等细节//特殊处:采用ISP编程方式,只需对,,,RST引脚控制;用MOSI串行发送死令的同时用MISO接收相关数据//SCK输出同步时钟脉冲///////////////////////////////////////////////////////////////////#include<>#defineMOSIP1_5#defineMISOP1_6#defineSCKP1_7BYTEOutBuf[4];//发送死令缓冲BYTEInBuf[4];//接收缓冲/*下面这一段是我Copy的*//*voidDelay_ms(UINTnMs)//豪秒级的延时<65535ms{UINTn=0;TR0=1;while(n{TH0=0;TL0=20;while(TH0<4){}n++;}TR0=0;}*/voidSendInstrc(BYTEnByte)//用MOSI串行发送死令的同时用MISO接收相关数据{BYTEn;for(n=0;n{ACC=OutBuf[n];SCK=0;MOSI=A_7;//低电平时输出一名SCK=1;B_7=MISO;//高电平时接收一名SCK=0;MOSI=A_6;SCK=1;B_6=MISO;SCK=0;MOSI=A_5;SCK=1;B_5=MISO;SCK=0;MOSI=A_4;SCK=1;B_4=MISO;SCK=0;MOSI=A_3;SCK=1;B_3=MISO;SCK=0;MOSI=A_2;SCK=1;B_2=MISO;SCK=0;MOSI=A_1;SCK=1;B_1=MISO;SCK=0;MOSI=A_0;SCK=1;B_0=MISO;SCK=0;InBuf[n]=B;}}voidInitPro02()//编程前的预备工作{//SetVpp5V();P3_5=0;//接RSTP3_2=1;//接PROGP0=0xff;P1=0xff;P2=0xff;Delay_ms(10);MOSI=0;MISO=1;SCK=1;P3_5=1;Delay_ms(10);nAddress=0x0000;OutBuf[0]=0xac;//正好在这里能够安排DataSheet上所规定的OutBuf[1]=0x53;//EanableProgramming命令OutBuf[2]=0;OutBuf[3]=0;SendInstrc(4);}voidProOver02()//编程结束后的工作,设置适合的引脚电平{//SetVpp5V();//P0=0xff;P1=0xff;//P2=0xff;P3_6=1;P3_7=1;P3_5=0;//RST=0;//P3_2=2;//PROG=0这时有问题}BYTERead02(){OutBuf[0]=0x20;OutBuf[1]=((BYTE*)&nAddress)[0];OutBuf[2]=((BYTE*)&nAddress)[1];SendInstrc(4);returnInBuf[3];}voidReadSign02()//读特征字{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();}voidErase02()//擦除器件{InitPro02();//-----------------------------------------------------//按照器件的DataSheet,设置相应的编程控制信号OutBuf[0]=0xac;OutBuf[1]=0x80;SendInstrc(4);Delay_ms(500);//-----------------------------------------------------ProOver02();}BOOLWrite02(BYTEData)//写器件{//-----------------------------------------------------//按照器件的DataSheet,设置相应的编程控制信号//写一个单元OutBuf[0]=0x40;OutBuf[1]=((BYTE*)&nAddress)[0];OutBuf[2]=((BYTE*)&nAddress)[1];OutBuf[3]=Data;SendInstrc(4);nTimeOut=0;while(Read02()!=Data)//效验:循环读,直到读出与写入的数相同{nTimeOut++;if(nTimeOut>1000)//超时了{return0;}}//-----------------------------------------------------return1;}voidLock02()//写锁定位{//------------------------------------------------//按照器件的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();}voidPreparePro02()//设置pw中的函数指针,让主程序能够挪用上面的函数{=InitPro02;=ReadSign02;=Erase02;=Write02;=Read02;=Lock02;=ProOver02;}
TL0=20;
while(TH0<4)
n++;
BOOLWaitComm()//等待上位机的命令,18字节
BYTEn=0;
RI=0;
while(!
RI){}//等待第一个字节
ComBuf[n]=SBUF;
for(n;n<=17;n++)
nTimeOut=0;
RI)
nTimeOut++;
if(nTimeOut>10000)//后17个字节都有超时限制
return0;
return1;
BOOLWaitResp()//等待上位机回应,1字节,有超时限制
if(nTimeOut>50000)
ComBuf[0]=SBUF;
BOOLWaitData()//写器件时等待上位机数据,18字节,有超时限制
BYTEn;
for(n=0;n<=17;n++)
if(nTimeOut>10000)
voidSendData()//发送数据或回应操作完成,18字节
TI=0;
SBUF=ComBuf[n];
TI){}
voidSendResp()//回应上位机1个字节,在写器件函数中利用
SBUF=ComBuf[0];
/*voidSetVpp5V()//设置Vpp为5v
P3_4=0;
P3_3=0;
voidSetVpp0V()//设置Vpp为0v
P3_4=1;
voidSetVpp12V()//设置Vpp为12v
P3_3=1;
*/
voidRstPro()//编程器复位
();//直接编程结束
SendData();//通知上位机,表示编程器就绪,能够直接用此函数因为协议号(ComBuf[0])还没被修改,下同
voidReadSign()//读特征字
();
SendData();//通知上位机,送出读出器件特征字
voidErase()//擦除器件
SendData();//通知上位机,擦除器件
voidWrite()//写器件
();//编程前的预备工作
SendData();//回应上位机表示进入写器件状态,能够发来数据
while
(1)
if(WaitData())//若是等待数据成功
if(ComBuf[0]==0x07)//判断是不是继续写
for(n=2;n<=17;n++)//ComBuf[2~17]为待写入数据块
if(!
(ComBuf[n]))//<<<<<<<<<<<<<<<<<<<挪用写该器件一个单元的函数
();//犯错了就结束编程
ComBuf[0]=0xff;
SendResp();//回应上位机一个字节,表示写数据犯错了
WaitData();//等待上位机的回应后就结束
return;
nAddress++;//下一个单元
ComBuf[0]=1;//回应上位机一个字节,表示数据块顺利完成,请求继续
SendResp();
elseif(ComBuf[0]==0x00)//写器件结束
break;
else//可能是通信犯错了
else//等待数据失败
();//编程结束后的工作
Delay_ms(50);//延时等待上位机写线程结束
ComBuf[0]=0;//通知上位机编程器进入就绪状态
SendData();
voidRead()//读器件
();//先设置成编程状态
SendData();//回应上位机表示进入读状态
if(WaitResp())//等待上位机回应1个字节
if(ComBuf[0]==0)//ComBuf[0]==0表示读结束
elseif(ComBuf[0]==0xff)//0xff表示重发
nAddress=nAddress-0x0010;
for(n=2;n<=17;n++)//ComBuf[2~17]保留读出的数据块
ComBuf[n]=();//<<<<<<<<<<<<<<<<<<<挪用写该器件一个单元的函数
ComBuf[0]=6;//向上位机发送读出的数据块
else
break;//等待回应失败
();//操作结束设置为运行状态
voidLock()//写锁定位
/////////////////////////////////////////////////////////////////
//所支持的FID,请在这里继续添加
///////////////////////////////////////////////////////////////
externvoidPreparePro00();//FID=00:
AT89C51编程器
externvoidPreparePro01();//FID=01:
AT89C2051编程器
externvoidPreparePro02();//FID=02:
AT89S51编程器
voidmain()
SP=0x60;
//SetVpp5V();//先初始化Vpp为5v
SCON=0x00;
TCON=0x00;
//PCON=0x00;//波特率*2
IE=0x00;
//TMOD:
GATE|C/!
T|M1|M0|GATE|C/!
T|M1|M0
//00100001
TMOD=0x21;//T0用于延时程序
TH1=0xff;
TL1=0xff;//波特率28800*2,注意PCON
//SCON:
SM0|SM1|SM2|REN|TB8|RB8|TI|RI
//01010000
SCON=0x50;
TR1=1;
Delay_ms(1000);//延时1秒后编程器自举
ComBuf[0]=0;
(1)//串口通讯采用查询方式
WaitComm())//若是超时,通信犯错
Delay_ms(500);
ComBuf[0]=0;//让编程器复位,使编程器就绪
switch(ComBuf[1])//按照FID设置(ProWork)pw中的函数指针
case0:
//at89c51编程器
PreparePro00();
case1:
//at89c2051编程器
PreparePro01();
case2:
//at89s51编程器
PreparePro02();
//case3:
支持新器件时,请继续向下添加
//break;
//case4:
default:
ComBuf[1]=0xff;//表示无效的操作
switch(ComBuf[0])//按照操作ID跳到不同的操作函数
case0x00:
RstPro();//编程器复位
case0x01:
ReadSign();//读特征字
case0x02:
Erase();//擦除器件
case0x03:
Write();//写器件
case0x04:
Read();//读器件
case0x05:
Lock();//写锁定位
///////////////////////////////////////////////////////////////////
//FID=02:
AT89S51系列编程器
//实现编程的读,写,擦等细节
//特殊处:
采用ISP编程方式,只需对,,,RST引脚控制;用MOSI串行发送死令的同时用MISO接收相关数据
//SCK输出同步时钟脉冲
//#include<>
#defineMOSIP1_5
#defineMISOP1_6
#defineSCKP1_7
BYTEOutBuf[4];//发送死令缓冲
BYTEInBuf[4];//接收缓冲
/*下面这一段是我Copy的*/
/*voidDelay_ms(UINTnMs)//豪秒级的延时<65535ms
while(n{TH0=0;TL0=20;while(TH0<4){}n++;}TR0=0;}*/voidSendInstrc(BYTEnByte)//用MOSI串行发送死令的同时用MISO接收相关数据{BYTEn;for(n=0;n{ACC=OutBuf[n];SCK=0;MOSI=A_7;//低电平时输出一名SCK=1;B_7=MISO;//高电平时接收一名SCK=0;MOSI=A_6;SCK=1;B_6=MISO;SCK=0;MOSI=A_5;SCK=1;B_5=MISO;SCK=0;MOSI=A_4;SCK=1;B_4=MISO;SCK=0;MOSI=A_3;SCK=1;B_3=MISO;SCK=0;MOSI=A_2;SCK=1;B_2=MISO;SCK=0;MOSI=A_1;SCK=1;B_1=MISO;SCK=0;MOSI=A_0;SCK=1;B_0=MISO;SCK=0;InBuf[n]=B;}}voidInitPro02()//编程前的预备工作{//SetVpp5V();P3_5=0;//接RSTP3_2=1;//接PROGP0=0xff;P1=0xff;P2=0xff;Delay_ms(10);MOSI=0;MISO=1;SCK=1;P3_5=1;Delay_ms(10);nAddress=0x0000;OutBuf[0]=0xac;//正好在这里能够安排DataSheet上所规定的OutBuf[1]=0x53;//EanableProgramming命令OutBuf[2]=0;OutBuf[3]=0;SendInstrc(4);}voidProOver02()//编程结束后的工作,设置适合的引脚电平{//SetVpp5V();//P0=0xff;P1=0xff;//P2=0xff;P3_6=1;P3_7=1;P3_5=0;//RST=0;//P3_2=2;//PROG=0这时有问题}BYTERead02(){OutBuf[0]=0x20;OutBuf[1]=((BYTE*)&nAddress)[0];OutBuf[2]=((BYTE*)&nAddress)[1];SendInstrc(4);returnInBuf[3];}voidReadSign02()//读特征字{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();}voidErase02()//擦除器件{InitPro02();//-----------------------------------------------------//按照器件的DataSheet,设置相应的编程控制信号OutBuf[0]=0xac;OutBuf[1]=0x80;SendInstrc(4);Delay_ms(500);//-----------------------------------------------------ProOver02();}BOOLWrite02(BYTEData)//写器件{//-----------------------------------------------------//按照器件的DataSheet,设置相应的编程控制信号//写一个单元OutBuf[0]=0x40;OutBuf[1]=((BYTE*)&nAddress)[0];OutBuf[2]=((BYTE*)&nAddress)[1];OutBuf[3]=Data;SendInstrc(4);nTimeOut=0;while(Read02()!=Data)//效验:循环读,直到读出与写入的数相同{nTimeOut++;if(nTimeOut>1000)//超时了{return0;}}//-----------------------------------------------------return1;}voidLock02()//写锁定位{//------------------------------------------------//按照器件的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();}voidPreparePro02()//设置pw中的函数指针,让主程序能够挪用上面的函数{=InitPro02;=ReadSign02;=Erase02;=Write02;=Read02;=Lock02;=ProOver02;}
voidSendInstrc(BYTEnByte)//用MOSI串行发送死令的同时用MISO接收相关数据
for(n=0;n{ACC=OutBuf[n];SCK=0;MOSI=A_7;//低电平时输出一名SCK=1;B_7=MISO;//高电平时接收一名SCK=0;MOSI=A_6;SCK=1;B_6=MISO;SCK=0;MOSI=A_5;SCK=1;B_5=MISO;SCK=0;MOSI=A_4;SCK=1;B_4=MISO;SCK=0;MOSI=A_3;SCK=1;B_3=MISO;SCK=0;MOSI=A_2;SCK=1;B_2=MISO;SCK=0;MOSI=A_1;SCK=1;B_1=MISO;SCK=0;MOSI=A_0;SCK=1;B_0=MISO;SCK=0;InBuf[n]=B;}}voidInitPro02()//编程前的预备工作{//SetVpp5V();P3_5=0;//接RSTP3_2=1;//接PROGP0=0xff;P1=0xff;P2=0xff;Delay_ms(10);MOSI=0;MISO=1;SCK=1;P3_5=1;Delay_ms(10);nAddress=0x0000;OutBuf[0]=0xac;//正好在这里能够安排DataSheet上所规定的OutBuf[1]=0x53;//EanableProgramming命令OutBuf[2]=0;OutBuf[3]=0;SendInstrc(4);}voidProOver02()//编程结束后的工作,设置适合的引脚电平{//SetVpp5V();//P0=0xff;P1=0xff;//P2=0xff;P3_6=1;P3_7=1;P3_5=0;//RST=0;//P3_2=2;//PROG=0这时有问题}BYTERead02(){OutBuf[0]=0x20;OutBuf[1]=((BYTE*)&nAddress)[0];OutBuf[2]=((BYTE*)&nAddress)[1];SendInstrc(4);returnInBuf[3];}voidReadSign02()//读特征字{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();}voidErase02()//擦除器件{InitPro02();//-----------------------------------------------------//按照器件的DataSheet,设置相应的编程控制信号OutBuf[0]=0xac;OutBuf[1]=0x80;SendInstrc(4);Delay_ms(500);//-----------------------------------------------------ProOver02();}BOOLWrite02(BYTEData)//写器件{//-----------------------------------------------------//按照器件的DataSheet,设置相应的编程控制信号//写一个单元OutBuf[0]=0x40;OutBuf[1]=((BYTE*)&nAddress)[0];OutBuf[2]=((BYTE*)&nAddress)[1];OutBuf[3]=Data;SendInstrc(4);nTimeOut=0;while(Read02()!=Data)//效验:循环读,直到读出与写入的数相同{nTimeOut++;if(nTimeOut>1000)//超时了{return0;}}//-----------------------------------------------------return1;}voidLock02()//写锁定位{//------------------------------------------------//按照器件的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();}voidPreparePro02()//设置pw中的函数指针,让主程序能够挪用上面的函数{=InitPro02;=ReadSign02;=Erase02;=Write02;=Read02;=Lock02;=ProOver02;}
ACC=OutBuf[n];
SCK=0;
MOSI=A_7;//低电平时输出一名
SCK=1;
B_7=MISO;//高电平时接收一名
MOSI=A_6;
B_6=MISO;
MOSI=A_5;
B_5=MISO;
MOSI=A_4;
B_4=MISO;
MOSI=A_3;
B_3=MISO;
MOSI=A_2;
B_2=MISO;
MOSI=A_1;
B_1=MISO;
MOSI=A_0;
B_0=MISO;
InBuf[n]=B;
voidInitPro02()//编程前的预备工作
//SetVpp5V();
P3_5=0;//接RST
P3_2=1;//接PROG
P0=0xff;
P1=0xff;
P2=0xff;
Delay_ms(10);
MOSI=0;
MISO=1;
P3_5=1;
nAddress=0x0000;
OutBuf[0]=0xac;//正好在这里能够安排DataSheet上所规定的
OutBuf[1]=0x53;//EanableProgramming命令
OutBuf[2]=0;
OutBuf[3]=0;
SendInstrc(4);
voidProOver02()//编程结束后的工作,设置适合的引脚电平
//P0=0xff;
//P2=0xff;
P3_6=1;
P3_7=1;
P3_5=0;//RST=0;
//P3_2=2;//PROG=0这时有问题
BYTERead02()
OutBuf[0]=0x20;
OutBuf[1]=((BYTE*)&nAddress)[0];
OutBuf[2]=((BYTE*)&nAddress)[1];
returnInBuf[3];
voidReadSign02()//读特征字
InitPro02();//先设置成编程状态
//----------------------------------------------------
//按照器件的DataSheet,设置相应的编程控制信号
OutBuf[0]=0x28;
OutBuf[1]=0x00;
OutBuf[2]=0x00;
OutBuf[3]=0x00;
ComBuf[2]=InBuf[3];
OutBuf[1]=0x01;
ComBuf[3]=InBuf[3];
OutBuf[1]=0x02;
ComBuf[4]=InBuf[3];
//------------------------------------------------------
ProOver02();
voidErase02()//擦除器件
InitPro02();
//-----------------------------------------------------
OutBuf[0]=0xac;
OutBuf[1]=0x80;
BOOLWrite02(BYTEData)//写器件
//写一个单元
OutBuf[0]=0x40;
OutBuf[3]=Data;
while(Read02()!
=Data)//效验:
循环读,直到读出与写入的数相同
if(nTimeOut>1000)//超时了
voidLock02()//写锁定位
//------------------------------------------------
if(ComBuf[2]>=1)//ComBuf[2]为锁定位
OutBuf[1]=0xe1;
Delay_ms
(1);
if(ComBuf[2]>=2)
OutBuf[1]=0xe2;
if(ComBuf[2]==3)
OutBuf[1]=0xe3;
//-------------------------------------------------
voidPreparePro02()//设置pw中的函数指针,让主程序能够挪用上面的函数
=InitPro02;
=ReadSign02;
=Erase02;
=Write02;
=Read02;
=Lock02;
=ProOver02;
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2