编程器程序.docx
- 文档编号:24975950
- 上传时间:2023-06-03
- 格式:DOCX
- 页数:22
- 大小:18.33KB
编程器程序.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(); } else break;//等待回应失败 } ();//操作结束设置为运行状态 ComBuf[0]=0;//通知上位机编程器进入就绪状态 SendData(); } voidLock()//写锁定位 { (); SendData(); } ///////////////////////////////////////////////////////////////// //所支持的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; 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_7 BYTEOutBuf[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;//接RST P3_2=1;//接PROG P0=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; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编程 程序