#include<reg52.h> #include<intrins.h> sbit P3_7=P0^6; // 點動按鈕 sbit P3_6=P0^5; // 單梭按鈕 sbit P3_5=P0^4; // 啟動按鈕 sbit P3_4=P0^3; // 停止按鈕 sbit P3_3=P2^6; // 經停信號輸入 sbit P3_2=P2^7; // 緯停信號輸入 sbit P3_1=P3^1; // “加”指示燈 sbit P3_0=P3^0; // “減”指示燈 //sbit P2_7=P2^7; // //sbit P2_6=P2^6; // sbit P2_5=P2^5; // “減”按鈕 sbit P2_4=P2^4; // “加”按鈕 //sbit P2_4=P2^4; // 儲緯繼電器 sbit P2_3=P1^2 ; // 保護輸出,至指示燈, 繼電器 sbit P2_2=P3^7 ; // 高壓輸出 sbit P2_1=P3^6; // 離合輸出 sbit P2_0=P2^0; // 制動輸出 sbit P1_7=P0^7; // 儲緯停信號輸入 sbit P1_6=P0^2; // H3信號輸入 sbit P1_5=P0^1; // H2信號輸入 sbit P1_4=P0^0; // H1信號輸入 sbit P1_3=P3^4; // DIP2 sbit P1_2=P3^5; // DIP3 sbit P1_1=P3^3; // DIP4 // sbit P1_0=P1^0; // // sbit P0_7=P0^7; // sbit P0_6=P3^2; // 過載保護輸入 sbit P0_5=P2^1; // 保護輸入,高壓檢測 sbit P0_4=P2^2; // 保護輸入,離合檢測 sbit P0_3=P2^3; // 保護輸入,制動檢測 sbit P0_2=P1^3; // 儲緯停輸出,至指示燈,繼電器。 sbit P0_1=P1^0; // 緯停輸出 sbit P0_0=P1^1; // 經停輸出 #define uchar unsigned char # define uint unsigned int //注意 無冒號 static unsigned char flag,flag1,flag2,flag3,flag4,flag5,flag6,flag7; bit testflag,testflag1,testflag2,testflag3; static unsigned char temp=0,temp1=0,temp2=0,temp3=0,tag=0,tag1=0,tag2=0,tag3=0,count=0; static unsigned char tag4=0,tag5=0,tag6=0,tag7=0; static unsigned char temp4=0,temp5=0,temp6=0,temp7=0,temp8=0,temp9=0, xx=0,count1=0,enable=0,mean=0; static unsigned char x,x1,x2,x3; static unsigned int i,j,k,i1,j1,k1; sfr T2MOD = 0xC9; void delay(uchar ms); //sfr WDT_CONTR=0xe1; //看門狗地址 sfr ISP_DATA = 0xE2; /* Flash Data Register */ sfr ISP_ADDRH = 0xE3; /* flash address high */ sfr ISP_ADDRL = 0xE4; /* flash address low */ sfr ISP_CMD = 0xE5; /* flash command register */ sfr ISP_TRIG = 0xE6; /* flash command trigger */ sfr ISP_CONTR = 0xE7; /* isp/iap control register */ #define ISP_IAP_BYTE_READ 1; /* 讀字節 */ #define ISP_IAP_BYTE_PROGRAM 2; /* 字節編程 */ #define ISP_IAP_SECTOR_ERASE 3; /* 扇區擦除 */ #define ISP_IAP_ENABLE 0x81; /* 系統工作時鐘<12M,對ISP_CONTR寄存器設置此值 ,0x81*/ unsigned char byte_read(unsigned int addr); void byte_write(unsigned int addr,unsigned char program_data); void Sector_Erase(unsigned int addr); void IAP_Disable(); unsigned int eeprom_address;unsigned char read_eeprom; unsigned char value_buf[22]; void main (void) { P2_0=0; xx=0; TMOD=0x11; EA=1;ET0=1;ET1=1; TH0=(65536-10000)/256;TL0=(65536-10000)%256; TR0=0; TH1=(65536-10000)/256;TL1=(65536-10000)%256; TR1=0; ET2=1; //T2中斷允許 T2MOD=0x00; //如果T2MOD=0X02,則從P1_0輸出 T2CON=0x00; //CP_RL2=1;EXEN2=1; TH2=(65536-50000)/256; TL2=(65536-50000)%256; RCAP2H=(65536-50000)/256; //重裝載計數器賦初值 RCAP2L=(65536-50000)%256; read_eeprom=byte_read(0x2000); x=read_eeprom; if (x<5) x=5; if(x>25) x=25; x1=byte_read(0x2200); if (x1<35) x1=35; if(x1>45) x1=45; while(1) { if ((P3_7==1) &&(temp1==1) || (P3_6==1)&&(temp1==1) ) temp2=1; // temp2點動單梭終止運行標志 while (temp2==1) { //if (!((P1_6==1) && (P1_4==1)&&(P1_5==0)) ) continue; // else if((P1_6==1)&&(P1_5==0)&&(P1_4==1)) {P2_1=1;P2_0=0;temp=0;temp1=0;temp2=0;enable=0;} } if ((P3_3==1)&&(temp1==1) &&(xx==0)) {temp3=1;P0_0=0;} // temp3經停標志 while((temp3==1) && (temp1==1)&&(xx==0)) { // if(!((P1_6==1) && (P1_4==1)&&(P1_5==0))) continue; // else if((P1_6==1)&&(P1_5==0)&&(P1_4==1)) {P2_1=1;temp1=0;P2_0=0; P0_0=0;enable=0;temp3=0;} } if ((P1_7==1)&&(temp1==1) &&(xx==0) ) {temp4=1;P0_2=0;} //temp4儲緯停標志 while((temp4==1) &&(temp1==1)&&(xx==0)) { //if(!((P1_6==1) && (P1_4==1)&&(P1_5==0)) ) continue; // else if((P1_6==1)&&(P1_5==0)&&(P1_4==1)) {P2_1=1;temp1=0;P0_2=0;P2_0=0;enable=0;} } if ((temp4==1) && (temp1==0) && (P3_4==1)) {P0_2=1; temp4=0;} //解除儲緯停標志 if ((P3_2==0)&&(temp1==1) && (enable==1)&&(xx==0)) //緯停負輸入 { delay(10); if ((temp1==1) && (enable==1)&&(P3_2==0) &&(xx==0)) { //count1數字濾波計數 略 { } if (mean==5) //mean 采樣值 之和 略 { //enable=1 緯停允許 while ((temp1==1) && (enable==1)&&(P3_2==0)&&(xx==0)&&(P0_5==0)&&(P0_3==0)&&(P0_6==1)) { /*if(!((P1_6==1) && (P1_5==1))) continue; //斷緯時 仍可保護 else {delay(2); P2_1=1;P2_0=0;temp1=0;temp5=1;enable=0;P0_1=0;} */ //temp5 緯停標志 if((P1_6==1)&&(P1_4==0)&&(P1_5==1)&&(P3_2==0)) //傳感器正輸入 flag=1; //flag 斷緯,傳感器后沿停機記憶 while ((flag==1)&&(P3_2==0)&&(xx==0)&&(P0_5==0)&&(P0_3==0)&&(P0_6==1) ) { if ((P1_6==0)&&(P1_5==0)) {temp5=1;flag=0;enable=0;} //temp5 緯停標志 } } } } } if(P3_2==1) { flag=0; //松開按鈕 flag=0; for (count1=0;count1<5;count1++) //count1數字濾波計數 { value_buf[count1]=0; } mean=0; } if (temp5==1) { delay(2); P2_1=1;delay(1);P2_0=0;temp1=0;enable=0;P0_1=0;_nop_(); for (count1=0;count1<5;count1++) { value_buf[count1]=0; } mean=0; temp5=0; } if ((P3_6==1) && (temp1==0) &&(temp==0)&&(temp4==0)&&(xx==0)) //單梭 ,temp 單梭標志 { P2_0=1; P2_1=0; temp=1; } while (temp==1) { //if (!(( P1_5==1)&&(P1_6==0)&&(P1_4==0)|| (P3_4==1)) ) continue; //P1_5 ,H2信號 單梭停止 // else if((P1_6==0)&&(P1_5==1)&&(P1_4==0) ||(P3_4==1)) { P2_1=1; temp=0; P2_0=0; } } if ((P3_5==1) && (temp4==0)&&(P3_4==0)&&(xx==0)) //無儲緯停,無保護 ,啟動 {P2_0=1;P2_1=0;_nop_(); temp=0;temp1=1;temp3=0;temp5=0;_nop_();P0_0=1;P0_1=1;} //temp1 啟動標志 ,temp8==1,開機瞬間緯停無效 //while ( (temp3==0)&&(temp4==0)&& (temp5==0)&&(xx==0)&&(temp1==1)) if ((temp3==0)&&(temp4==0)&& (temp5==0)&&(xx==0)) //停止 { if (P3_4==1) { P2_1=1; P2_0=0;_nop_();temp=0;temp1=0;enable=0;} } if ((temp==0) && (temp1==0) &&(temp4==0)&& (P3_7==1) &&(xx==0) && (tag==0)) //tag 切斷點動動作按鈕 { //delay(1); temp9=1; //temp9 點動狀態運行中 P2_0=1; tag=1; tag1=0; count=1; //開機瞬間無高壓,count==0; delay(1); //間隔 P2_1=0; P2_2=0; delay(20);P2_2=1; //高壓1時間 delay(x1); //離合時間 if (P3_7==0) //松開點動按鈕 { P2_1=1; } } if ((P3_7==0)&&(temp==0) && (temp1==0) &&(temp4==0)&&(xx==0) ) //松開點動按鈕 { // delay(1); tag=0; P2_1=1;delay(1); //間隔 P2_0=0; //delay(1); } /* if ((P3_7==0)&&(P2_1==1)&&(temp==0)&&(temp1==0)&&(temp4==0)&&(tag1==0)&&(xx==0)) { tag=0;P2_1=1;_nop_();P2_0=0; tag1=1; //tag1 切斷點動制動 if (count==1) P2_2=0; //點動制動后,瞬間高壓 delay(20); //高壓2時間 P2_2=1; _nop_(); temp9=0; //temp9 點動狀態標志 } */ if ((P2_0==0) && (P2_1==1) &&(temp==0)&& (temp1==0)&&(temp4==0) &&(tag1==0)&&(tag==0)) { tag1=1;tag=0; //tag1 切斷點動制動 if (count==1) P2_2=0; //點動制動后,瞬間高壓 delay(20); //高壓2時間 P2_2=1; delay(20); _nop_(); temp9=0; } if ((tag==1) && (tag1==1)) tag=0; //防止互鎖 if ((P0_3==1) &&(P0_4==1)) { //delay(200); //延時時間不能太長 delay(10); if ((P0_3==1) &&(P0_4==1)) //{ temp6=1;xx=1;P2_1=1;P2_0=1;P2_2=1;P2_3=0; } //temp6 邏輯保護標志 TR1=1; // else {TR1=0;k=0;} } if ((P0_5==1)&&(P3_7==0)) TR1=1; //無點動,高壓觸發保護定時器 if(!((P0_3==1)&&(P0_4==1))&&(P0_5==0)) {TR1=0;k=0;} if (P0_6==0) //過載信號負輸入 { delay(200); if (P0_6==0) {temp7=1;xx=1;P2_1=1;P2_0=1;P2_2=1;P2_3=0; } //temp7 過載保護 } if ((temp6==1) ||(temp7==1)) {xx=1;P2_1=1;P2_0=1;P2_2=1;P2_3=0; } //保護 if((P1_3==0)&&(P1_2==1)&&(P1_1==0)) // DIP2 DIP4 ON DIP3 OFF 緯停采樣調整 { if(P3_4==1) //停止按鈕按下 { if ((P2_4==0) &&(tag2==0) ) // tag2切斷 加按鈕 最多按18次 { if(x<=24) {x+=1; P3_1=0;} tag4=0;tag2=1;delay(10);P3_1=1; } if (P2_4==1) tag2=0; if ((P2_5==0) &&(tag3==0)) //tag3切斷 減按鈕 最多按18次 { if(x>=6) {x-=1; P3_0=0;} tag4=0;tag3=1;delay(10);P3_0=1; } if (P2_5==1) tag3=0; } if((P3_4==0)&&(tag4==0)) //tag4==0 寫允許 停止按鈕松開 { Sector_Erase(0x2000); _nop_();byte_write( 0x2000, x); _nop_();_nop_();tag4=1; } } if((P1_3==0)&&(P1_2==0)&&(P1_1==1)) // DIP2 DIP3 ON DIP4 OFF 點動距離調整 { if(P3_4==1) //停止按鈕按下 { if ((P2_4==0) &&(tag2==0) ) // tag2切斷 加按鈕 最多按10次 { if(x1<=44) {x1+=1; P3_1=0;} tag4=0;tag2=1;delay(10);P3_1=1; } if (P2_4==1) tag2=0; if ((P2_5==0) &&(tag3==0)) //tag3切斷 減按鈕 最多按10次 { if(x1>=36) {x1-=1; P3_0=0;} tag4=0;tag3=1;delay(10);P3_0=1; } if (P2_5==1) tag3=0; } if((P3_4==0)&&(tag4==0)) //tag4==0 寫允許 停止按鈕松開 { Sector_Erase(0x2200); _nop_();byte_write( 0x2200, x1); _nop_();_nop_();tag4=1; } } //if (temp1==1) {delay(10); enable=1;} // 開機瞬間緯停無效 if (P3_5==1) TR2=1; //按鈕輸入正 if ((temp1==0)&&(P3_5==0)) {enable=0; i1=0;TR2=0;} if (P2_0==0) //制動后 所有狀態復位 ,temp4除外 { //count1數字濾波計數 for (count1=0;count1<5;count1++) { value_buf[count1]=0; } mean=0; enable=0; temp=0;temp1=0;temp2=0;temp3=0;temp5=0; } } } void int_1(void) interrupt 1 { TR0=0; TH0=(65536-10000)/256;TL0=(65536-10000)%256; } void int_3(void) interrupt 3 //保護定時器 { k++; if(k>=100) { xx=1;P2_1=1;P2_0=1;P2_2=1;P2_3=0; _nop_(); P2_0=1; TR1=0; k=0; temp6=1; } TH1=(65536-10000)/256;TL1=(65536-10000)%256; } void timer2() interrupt 5 { i1++; TF2=0; //T2中斷 溢出標志,必須清除 if (i1>=10) //1S, 0.5s { TR2=0; i1=0; enable=1; // 定時時間到標志 ,緯停允許 } // TH2=(65536-50000)/256; //TL2=(65536-50000)%256; } unsigned char byte_read(unsigned int addr) { unsigned char ii; ISP_ADDRH = (addr>>8); ISP_ADDRL = (addr&0x00ff); ISP_CONTR = ISP_IAP_ENABLE; //0x81 ISP_CMD = ISP_IAP_BYTE_READ; //1 ISP_TRIG = 0x46; ISP_TRIG = 0xb9; _nop_(); _nop_(); ii = ISP_DATA; ISP_CONTR = 0x00; ISP_CMD = 0x00; ISP_TRIG = 0x00; return ii; } void byte_write(unsigned int addr,unsigned char program_data) { ISP_DATA = program_data; ISP_ADDRH = (addr>>8); ISP_ADDRL = (addr&0x00ff); ISP_CONTR = ISP_IAP_ENABLE; // 0x81 ISP_CMD = ISP_IAP_BYTE_PROGRAM; // 2 ISP_TRIG = 0x46; ISP_TRIG = 0xb9; _nop_(); ISP_CONTR = 0x00; ISP_CMD = 0x00; ISP_TRIG = 0x00; } // void IAP_Disable() // { //IAP_CONTR=0; // IAP_CMD=0; // IAP_TRIG=0; // IAP_ADDRH=0; //IAP_ADDRL=0; // } void Sector_Erase(unsigned int addr) { //addr=(addr&0xfe00); //地址小于0xfe00? ISP_ADDRH = (addr>>8); ISP_ADDRL = (addr&0x00ff); ISP_CONTR = ISP_IAP_ENABLE; //0x81 ISP_CMD = ISP_IAP_SECTOR_ERASE; //3 ISP_TRIG = 0x46; ISP_TRIG = 0xb9; _nop_(); _nop_(); _nop_(); ISP_CONTR = 0x00; ISP_CMD = 0x00; ISP_TRIG = 0x00; } void delay(uchar ms) { uchar m; while (ms--) { for (m=0;m<250;m++) {;} } }