www.pudn.com > at89c51pro.rar > AT89C51PRO.C
/////////////////////////////////////////////////////////////////////////////////////////////////// //FID=00:AT89C51系列编程器 //实现编程的读,写,擦等细节 /////////////////////////////////////////////////////////////////////////////////////////////////// #include#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; }