程序是循環使用超聲波傳感器測距 剛開始時正常工作,工作一兩分鐘后就死機了這是程序
//本程序為單機測試程序,大板可用
//本程序采用中斷形式接收指令,同時在進入中斷程序之后對所有控制指令進行停止
- #include<reg52.h>
- #include<math.h>
- #include<intrins.h>
- #define DIZHI 'C'
- sfr CMOD=0XD9;//工作模式寄存器
- sfr CCON=0XD8;//控制寄存器
- sfr CCAPM0=0XDA;//模塊0比較、捕獲寄存器
- sfr CCAPM1=0XDB;//模塊1比較、捕獲寄存器
- sfr CH=0XF9;//可編程計數器高8位
- sfr CL=0Xe9;//可編程計數器低8位
- sfr CCAP0H=0XFA;//捕獲、比較寄存器0高8位
- sfr CCAP0L=0XEA;//捕獲、比較寄存器0低8位
- sfr CCAP1H=0XFB;//捕獲、比較寄存器1高8位
- sfr CCAP1L=0XEB;//捕獲、比較寄存器1低8位
- sfr PCAPWM0=0XF2;//模塊0的PWM寄存器
- sfr PCAPWM1=0XF3;//模塊1的PWM寄存器
- sfr AUXR=0X8E;//多路開關寄存器
- sfr BRT=0X9C;//獨立波特率發生器
- sfr P1ASF=0X9D;//P1口模擬通道選擇寄存器
- sfr ADC_CONTR=0XBC;//ADC控制寄存器
- sfr ADC_RES=0XBD;//ADC結果寄存器高8位
- sfr ADC_RESL=0XBE;//ADC結果寄存器低2位
- sfr P4SW=0XBB;//設置P4.4/5/6引腳為IO口
- sfr P4=0XC0;
- sfr IAP_CONTR=0XC7; //與復位相關寄存器
- sfr AUXR1=0XA2;//可以將P1口遷移到P4口
- sbit EADC=IE^5;//ADC中斷允許位
- sbit CR=CCON^6;//PWM時鐘輸入位
- sbit b1=P2^3;//繼電器——左——上前12V
- sbit b2=P2^2;//繼電器——左——下后12V
- sbit b3=P2^0;//繼電器——左——角度
- sbit b4=P2^1;//繼電器——左——距離
- sbit b11=P2^6;//繼電器——右——上前12V
- sbit b21=P2^7;//繼電器——右——下后12V
- sbit b31=P2^4;//繼電器——右——角度
- sbit b41=P2^5;//繼電器——右——距離
- sbit trig1=P1^5;// j9 6
- sbit echo1=P1^4;// 5
- sbit trig2=P1^7;// 8
- sbit echo2=P1^6;// 7
- sbit trig3=P0^3;// 10
- sbit echo3=P0^2;// 9
- sbit trig4=P0^5;// 12
- sbit echo4=P0^4;// 11
- sbit d=P0^6;//燈——手動和自動選擇指示燈
- sbit d1=P0^7;//燈——亮表示左腿調平機構到位
- sbit d2=P4^6;//燈——亮表示右腿調平機構到位
- sbit w11=P0^0;//左電機方向
- sbit w21=P0^1;//右電機方向
- sbit Q3=P4^4;//左電機開關
- sbit Q4=P4^5;//上升
- sbit Q5=P3^6;//下降
- sbit Q6=P3^4;//右電機開關
- sbit pxx=P4^0;//多機通信判斷是否有人占用T總線
- int c1,m1,m2,m3;//m1上位機發送的角度值,m2上位機發送的前后距離值,m3上位機發送的上升距離值,
- float a0,a1,a2,a3,b,b01;
- bit dbzh,c5,c51,tzb=0;
- unsigned char kzh;//kzh點動控制數據
- float ceju(int b) //測距離
- { int k=0;float a;
- // ES=0;
- loop0:
- TH0=0X00;
- TL0=0X00;
- if(b==1)//左腿——前后距離測量
- {
- trig1=1;
- k++;k++;k++;k++;k++;k++;k++;k++;k++;k++;
- trig1=0;
- while(!echo1);
- TR0=1;
- while(echo1);
- a=TH0*256+TL0;
- a=a*12*17;
- TR0=0;
- }
- if(b==2)//右腿——前后距離測量
- {
- trig2=1;
- k++;k++;k++;k++;k++;k++;k++;k++;k++;
- trig2=0;
- while(!echo2);
- TR0=1;
- while(echo2);
- a=TH0*256+TL0;
- a=a*12*17;
- TR0=0;
- }
- if(b==3)//左腿上升下降距離
- {
- trig3=1;
- k++;k++;k++;k++;k++;k++;k++;k++;k++;
- trig3=0;
- while(!echo3);
- TR0=1;
- while(echo3);
- a=TH0*256+TL0;
- a=a*12*17;
- TR0=0;
-
- }
- if(b==4)//右腿上升下降距離
- {
- trig4=1;
- k++;k++;k++;k++;k++;k++;k++;k++;k++;
- trig4=0;
- while(!echo4);
- TR0=1;
- while(echo4);
- a=TH0*256+TL0;
- a=a*12*17;
- TR0=0;
- }
- a=(a/11059.2)+0.7; //修正誤差
- if(a<2) goto loop0;
- return a;
- //ES=1;
- }
- float jiaodu(int b) // 角度測量
- { char i;float a1;
- if(b==1) ADC_CONTR=0XEA;
- else ADC_CONTR=0XEB;
- i++;i++;//可以沒有,有是為了讀取ADC_CONTR時更加可靠;
- while(!(ADC_CONTR&0X10));
- ADC_CONTR=0XE0;
- a1=(ADC_RES*4+ADC_RESL)*3.26/1024;
- if(b==1) a1=-38.141*a1*a1*a1*a1+101.23*a1*a1*a1-25.47*a1*a1-201.9*a1+274.58;//zuo角度傳感器
- else a1=-31.349*a1*a1*a1*a1+91.498*a1*a1*a1+7.381*a1*a1-306.34*a1+383.6;//右角度傳感器
- return a1;
- }
- void songxian(float a) // 串口送顯
- { float b1,c1;int b,c;char data x[8],i;
- c1=modf(a,&b1);
- b=(int)(b1);
- c=(int)(1000*c1);
- x[0]=0x30+b/100;
- x[1]=0x30+b/10-10*(b/100);
- x[2]=0x30+b-10*(b/10);
- x[3]=0x2e;
- x[4]=0x30+c/100;
- x[5]=0x30+c/10-10*(c/100);
- x[6]=0x20;;
- x[7]='\0';
- // ES=0; //關閉中斷,采用查詢發送,數據傳輸更快
- for(i=0;i<8;i++)
- { if((x[i]==0x30)&&(i<2))
- { if(!(x[0]==0x30))
- { SBUF=x[i];
- while(!TI);
- TI=0;
- }
- else
- { SBUF=0x20;
- while(!TI);
- TI=0;
- }
- }
- else { SBUF=x[i];
- while(!TI);
- TI=0;
- }
- }
- // ES=1;
- }
- void delay(int a)
- {
- int i,j;
- for(i=1;i<a;i++)
- for(j=1;j<=500;j++);
- }
- void anjiankongzhi(char i) //手動控制模塊
- {
- int k,j;
- d=0;
- while(1)
- {
-
-
- for(k=1;i<200;k++)
- for(j=1;j<=500;j++);
- a0=ceju(1);
-
- a1=ceju(2);
-
- a2=ceju(3);
-
- a3=ceju(4);
-
- b=jiaodu(1);
-
- b01=jiaodu(2);
-
-
-
- if(i==1) // 手動控制--左右腿同步上下移
- {
- /* a=ceju(3);// 左腿距離
- songxian(a);
- a=ceju(4);// 右腿距離
- songxian(a);*/
- if(Q3==0) CCAPM0=0X42;
- else CCAPM0=0X40;
- if(Q6==0) CCAPM1=0X42;
- else CCAPM1=0X40;
- if(Q4==0) {w11=1;w21=1;while(!Q4);}
- if(Q5==0) {w11=0;w21=0;while(!Q5);}
- }
- if(i==2)//左腿下模塊控制
- {
- /* a=ceju(1);// 左距離
- songxian(a);
- a=jiaodu(1); //左角度
- songxian(a); */
- if(Q6==0) { b1=1;b2=0;b3=0; }//角度向上走
- if(Q5==0) { b1=0;b2=1;b3=0; }//角度向下走
- if(Q3==0) { b1=1;b2=0;b4=0; }//距離向前走
- if(Q4==0) { b1=0;b2=1;b4=0; }//距離向后走
- if((Q6==1)&&(Q5==1)&&(Q3==1)&&(Q4==1)) {b1=1;b2=1;b3=1;b4=1;}
- }
- if(i==3)//右腿下模塊控制
- {
- /* a=ceju(2);// 右距離
- songxian(a);
- a=jiaodu(2); //右角度
- songxian(a); */
- if(Q6==0) { b11=1;b21=0;b31=0; }//角度向上走
- if(Q5==0) { b11=0;b21=1;b31=0; }//角度向下走
- if(Q3==0) { b11=1;b21=0;b41=0; }//距離向前走
- if(Q4==0) { b11=0;b21=1;b41=0; }//距離向后走
- if((Q6==1)&&(Q5==1)&&(Q3==1)&&(Q4==1)) {b11=1;b21=1;b31=1;b41=1;}
- }
-
- }
- }
- void s1() interrupt 4 //中斷接收數據,能提高實時性,發送采用查詢更快
- {
- int zh,i,j;
- bit pb;
- ES=0;
- if(d==0){pb=1;}
- else pb=0;
- if(RI==1)
- {
- RI=0;
- SM2=0;
- zh=SBUF;
- if(DIZHI==zh)
- {
- CCAPM0=0x40; // 左腿停止工作 防止在接收數據期間發生碰撞
- CCAPM1=0x40; // 右腿停止工作 防止在接收數據期間發生碰撞
- b1=1;b2=1;b3=1;b4=1; b11=1;b21=1;b31=1;b41=1;//讓所有繼電器停止工作,防止位姿機構卡死
- while(!RI);
- RI=0;
- zh=SBUF;// 接收數據包標志位
- if(dbzh!=1)
- {
- switch(zh)//自動控制接收數據模塊
- {
- case 0x31: while(RI==0);
- RI=0;
- m3=SBUF-0x30;//接收抬高控制數據
- while(RI==0);
- RI=0;
- m2=SBUF-0x30;//接收位姿伸縮控制數據
- while(RI==0);
- RI=0;
- m1=SBUF-0x30;//接收位姿角度控制數據
- while(pxx==0);
- pxx=0;
- TB8=1;SBUF=DIZHI;
- while(!TI);TI=0;
- TB8=0;SBUF=0x31;
- while(!TI);TI=0;
- songxian(a2);songxian(a3);
- songxian(a0);songxian(b);
- songxian(a1);songxian(b01);
- songxian(0);songxian(0);
- TB8=0;SBUF='S' ;while(!TI);TI=0;
- pxx=1;
-
-
-
- case 0x32:if((c5!=0)||(c51!=0)||(pb==1))//c5=0;c51=0; 表示所有控制指令已經完成
- {
- while(pxx==0);
- pxx=0;
- TB8=1;SBUF=DIZHI;
- while(!TI);TI=0;
- TB8=0;SBUF=0x32;
- while(!TI);TI=0;
- songxian(a2);
- songxian(a3);
- songxian(a0);
- songxian(b);
- songxian(a1);
- songxian(b01);
- songxian(0);
- songxian(0);
- TB8=0;SBUF='S' ;while(!TI);TI=0;
- pxx=1;
- break;
- }
- else
- {
- while(pxx==0);
- pxx=0;
- TB8=1;SBUF=DIZHI;
- while(!TI);TI=0;
- TB8=0;SBUF=0x33;
- while(!TI);TI=0;
- songxian(a2);songxian(a3);
- songxian(a0);songxian(b);
- songxian(a1);songxian(b01);
- songxian(0);songxian(0);
- TB8=0;SBUF='S' ;while(!TI);TI=0;
- pxx=1;
- break;
- }
- case 0x35: d=0; //在多機情況下,表示燒寫程序使用
- for(i=0;i<5000;i++)
- for(j=0;j<500;j++);
- d=1;
- IAP_CONTR=0x60; // 與復位相關的操作
- break;
- }
- }
-
- }
- TI=0;SM2=1;
- }
- ES=1;
-
- }
- void main()
- {
- float d11,d12,d13;
- int i,j,k,m,bzh=0;
- bit e3,e4;
- //初始化
- BRT=0XFD;
- AUXR=0X11;
- TMOD=0X01;
- SCON=0Xf8;
- P1ASF=0X0C; //記住一定要把當ADC通道的引腳一定要值1;
- ADC_CONTR=0XE0;
- EADC=0;
- EA=1;
- ES=1;
- trig1=0;
- echo1=1;
- trig2=0;
- echo2=1;
- trig3=0;
- echo3=1;
- trig4=0;
- echo4=1;
- CMOD=0X00; //控制輸出速度
- CL=0;
- CH=0;
- CCAP1H=CCAP1L=0X80;
- CCAP0H=CCAP0L=0X80;
- PCAPWM0=0;
- PCAPWM1=0;
- CCAPM0=0X40;
- CCAPM1=0X40;
- AUXR1=0X40;//將PWM口搬遷到P4口
- CR=1;
- P4SW=0X70;
- pxx=1;
- IAP_CONTR=0x40; //與復位相關的操作
- b1=1;b2=1;b3=1;b4=1;d=1;d1=1;d2=1;b11=1;b21=1;b31=1;b41=1;
- dbzh=0;
-
- for(k=0;k<6;k++)//手動和自動選擇部分
- { m++;d=m%2;
- for(i=0;i<600;i++)
- for(j=0;j<1000;j++);
-
- if(Q3==0) { while(!Q3); anjiankongzhi(1); }//抬高機構按鍵
- if(Q6==0) { while(!Q6); anjiankongzhi(2); }//左位姿調節機構按鍵
- if(Q5==0) { while(!Q5); anjiankongzhi(3); }//右位姿調節機構按鍵
- if(Q4==0) { while(!Q4); dbzh=1;break; }//上位機點動
- }
- d=1;
- i=0;
- while(1)//空循環
- {; }
- }
- }
-
復制代碼
|