- StartModule(); //啟動模塊測距
- while(!RX); //當RX(ECHO信號回響)為零時等待
- TR1=1; //開啟計數
- while(RX); //當RX為1計數并等待
- TR1=0; //關閉計數
- Dist(); //計算距離
復制代碼- void zd0() interrupt 1 //T0中斷用來計數器溢出,超過測距范圍
- {
-
- flag=1;
- //中斷溢出標志
- }
復制代碼
上面是一段普通的超聲波避障代碼,可以實現基本避障,但是我需要在巡線過程中用超聲波識別礙物并作出動作,小車的pwm用的T0,定時1ms,如果都在T0里面中斷,超聲波發送接收信號會使T0開關,然后pwm就會亂,怎么才能在一個定時器里面同時做超聲波中斷和pwm中斷,或者說怎么在T0不單獨清零時,計算出超聲波發送和接受信號的時間。用上面代碼放在循跡代碼以前,只用超聲波計算距離不執行其他動作,小車具體表現為:搖晃幅度較大,很容易就偏離軌跡,偶爾也可以循跡但是成功率特別低。 - StartModule(); //啟動模塊測距
- while(!RX); //當RX(ECHO信號回響)為零時等待
- l=0;
- l=(TH0<<8)|TL0; //記錄為0的時間
- while(RX); //當RX為1計數并等待
- l=T*1000+l-((TH0<<8)|TL0); //計算時間
- S=l*0.17;
- delay(60);
復制代碼- void zd0() interrupt 1 //T1中斷用來計數器溢出,超過測距范圍
- {
-
- flag=1; //中斷溢出標志
- T++;
- }
復制代碼
上面是朋友給我想的計算時間的辦法,思路是這樣:每執行一次中斷,使T累加。啟動超聲波模塊記錄Rx為0時的時間,然后記錄Rx為1的時間,算出時間差,再加上中斷的時間,算出總時間,最后算距離。用這個代碼在串口S的返回值為0,s放大100倍后,出現不穩定的正負巨大值。根本無法實現超聲波測距功能,請問這個代碼思路對不對,該怎么完善?或者有沒有其他方式解決這個問題?
附上完整代碼,感謝各位大神幫助- #include<AT89X52.H> //包含51單片機頭文件,內部有各種寄存器定義
- #include<8testpwm.h> //包含pwm等函數
- /*超聲波避障*/
- long int l; //時間
- void Avoid(void)
- {
- //這段代碼無法實現測距
- StartModule(); //啟動模塊測距
- while(!RX); //當RX(ECHO信號回響)為零時等待
- l=0;
- l=(TH0<<8)|TL0; //
- while(RX); //當RX為1計數并等待
- l=T*1000+l-((TH0<<8)|TL0); //
- S=l*0.17;
- delay(60);
- //注解代碼能正常測距,但在巡線過程測距干擾巡線
- /* StartModule(); //啟動模塊測距
- while(!RX); //當RX(ECHO信號回響)為零時等待
- TR1=1; //開啟計數
- while(RX); //當RX為1計數并等待
- TR1=0; //關閉計數
- Dist(); //計算距離 */
-
-
- }
- void Go_line()
- {
- if(Led_1==1&&Led_3==1)
- {
- line='L';
- }
- else if(Led_6&&Led_8==1)
- {
- line='R';
- }
- else if(Led_1==1)
- {
- line='1';
- }
- else if(Led_2==1)
- {
- line='2';
- }
- else if(Led_3==1)
- {
- line='3';
- }
- else if(Led_4==1)
- {
- line='4';
- }
- else if(Led_5==1)
- {
- line='5';
- }
- else if(Led_6==1)
- {
- line='6';
- }
- else if(Led_7==1)
- {
- line='7';
- }
- else if(Led_8==1)
- {
- line='8';
- }
- }
- /**************************巡線函數**********************************************/
- void Go()
- {
- switch(line)
- {
- case 'L':
- {
-
- counter();
- if(Count==3||Count==4||Count==7||Count==18||Count==20||Count==21)
- { stop();
- leftrun();
- stop();
-
-
- }
- else if(Count==9||Count==14)
- {
- run();
-
- }
- else if(Count==12||Count==17)
- { stop();
- rightrun();
- stop();
-
-
- }
- else if(Count==2||Count==5||Count==10||Count==13||Count==15)
- { stop();
- Return();
- stop();
- }
- else if(Count==22)
- {
- stop();
- }
- }; break;
- case 'R':
- {
- counter();
- if(Count==8||Count==11||Count==12||Count==16||Count==17||Count==19)
- {
- stop();
- rightrun();
- stop();
-
-
- }
- else if(Count<2||Count==6)
- {
- run();
-
- }
- else if(Count==4||Count==21)
- {
- stop();
- leftrun();
- stop();
-
-
- }
- else if(Count==2||Count==5||Count==10||Count==13||Count==15)
- {
- stop();
- Return();
- stop();
-
- }
- else if(Count==22)
- {
- stop();
- }
- };break;
- case '1':
- {
- leftp_3();
- }; break;
- case '2':
- {
- leftp_2();
- }; break;
- case '3':
- {
- leftp_1();
- }; break;
- case '4':
- {
- run();
- }; break;
- case '5':
- {
- run();
- }; break;
- case '6':
- {
- rightp_1();
- }; break;
- case '7':
- {
- rightp_2();
- }; break;
- case '8':
- {
- rightp_3();
- }; break;
-
- }
- }
- /**************************巡線函數**********************************************/
- //主函數
- void main(void)
- {
- P1=0X00; //關電機
- TMOD |= 0x01;//定時器0工作模塊1,16位定時模式,測量PWM波
- TH0= 0XFc; //1ms定時
- TL0= 0X18;
- TR0= 1;
- ET0= 1;
- SCON=0x50;
- EA = 1; //開總中斷
- TI=1;
- Count=0;
- push_val_left=0;
- push_val_right=0;
- while(1) //無限循環
- {
-
- //有信號為0 沒有信號為1
- Avoid();
- Go_line();
- Go();
- delay(50);
- }
- }
- #include <intrins.h> //包含nop等系統函數
- #ifndef _LED_H_
- #define _LED_H_
- //定義小車驅動模塊輸入IO口
- sbit L293D_IN1=P1^2;
- sbit L293D_IN2=P1^3;
- sbit L293D_IN3=P1^4;
- sbit L293D_IN4=P1^5;
- sbit L293D_EN1=P1^6;
- sbit L293D_EN2=P1^7;
-
- #define TX P3_3
- #define RX P3_2
- #define ShowPort P0 //數碼管顯示端口
- /****************定義傳感器端口********************/
- #define Led_1 P2_7
- #define Led_2 P2_6
- #define Led_3 P2_5
- #define Led_4 P2_4
- #define Led_5 P2_3
- #define Led_6 P2_2
- #define Led_7 P2_1
- #define Led_8 P2_0
-
-
- #define Left_moto_pwm P1_6 //PWM信號端
- #define Right_moto_pwm P1_7 //PWM信號端
-
- #define Left_moto_go {P1_2=1,P1_3=0;} //左電機向前走
- #define Left_moto_back {P1_2=0,P1_3=1;} //左邊電機向后轉
- #define Left_moto_Stop {P1_2=0,P1_3=0;} //左邊電機停轉
- #define Right_moto_go {P1_4=1,P1_5=0;} //右邊電機向前走
- #define Right_moto_back {P1_4=0,P1_5=1;} //右邊電機向后走
- #define Right_moto_Stop {P1_4=0,P1_5=0;} //右邊電機停轉
- unsigned char code LedShowData[]={0x03,0x9F,0x25,0x0D,0x99, //定義數碼管顯示數據
- 0x49,0x41,0x1F,0x01,0x19 };//0,1,2,3,4,5,6,7,8,9
-
- unsigned char voice_sign;
- unsigned int T;
- unsigned char line;
- unsigned int Count;
- unsigned char pwm_val_left =0;//變量定義
- unsigned char push_val_left ;// 左電機占空比N/20
- unsigned char pwm_val_right =0;
- unsigned char push_val_right ;// 右電機占空比N/20
- unsigned int time = 0;//傳輸時間
- unsigned long S = 0;//距離
- bit Right_moto_stop=1;
- bit Left_moto_stop =1;
- bit flag = 0;//超出測量范圍標志位
-
- /************************************************************************/
- //延時函數
- void delay(unsigned int k) //1mm延時
- {
- unsigned int x,y;
- for(x=0;x<k;x++)
- for(y=0;y<110;y++);
- }
- void Delay10us(unsigned char i) //10us延時函數 啟動超聲波模塊時使用
- {
- unsigned char j;
- do{
- j = 10;
- do{
- _nop_();
- }while(--j);
- }while(--i);
- }
- /************************************************************************/
- /*定時器0中斷*/
- void zd0() interrupt 1 //T1中斷用來計數器溢出,超過測距范圍
- {
-
- flag=1;
- T++; //中斷溢出標志
- }
- void StartModule() //啟動超聲波模塊
- {
- TX=1; //啟動一次模塊
- Delay10us(2);
- TX=0;
- }
- void Dist() //測試距離
- {
- time=TH1*256+TL1;
- TH1=0;
- TL1=0;
-
- S=(float)(time*1.085)*0.17; //算出來是MM
- if((S>=5000)||flag==1) //超出測量范圍
- {
- flag=0;
- }
- }
- /**************************計數函數**********************************************/
- void counter(void)
- {
-
- Count++;
- ShowPort = LedShowData[Count] ;
- delay(200);
- }
- /**************************計數函數**********************************************/
- //前速前進
- void run(void)
- {
- push_val_left=12; //速度調節變量 0-20。。。0最小,20最大
- push_val_right=12;
- Left_moto_go ; //左電機往前走
- Right_moto_go ; //右電機往前走
- }
- //后退函數
- void backrun(void)
- {
- push_val_left=12; //速度調節變量 0-20。。。0最小,20最大
- push_val_right=12;
- Left_moto_back; //左電機往后走
- Right_moto_back; //右電機往后走
- }
- //左轉
- void leftrun(void)
- {
-
- push_val_left=12;
- push_val_right=18;
- Right_moto_go ; //右電機往前走
- Left_moto_back ; //左電機后走
- delay(490);
- }
- //左小偏
- void leftp_1(void)
- {
- push_val_left=3;
- push_val_right=12;
- Right_moto_go ; //右電機往前走
- Left_moto_go ; //左電機后走
-
-
- }
- //左中偏
- void leftp_2(void)
- {
- push_val_left=1;
- push_val_right=12;
- Right_moto_go ; //右電機往前走
- Left_moto_back ; //左電機后走
-
-
- }
- //左大偏
- void leftp_3(void)
- {
- push_val_left=3;
- push_val_right=12;
- Right_moto_go ; //右電機往前走
- Left_moto_back ; //左電機后走
-
-
- }
- //右轉
- void rightrun(void)
- {
-
- push_val_left=18;
- push_val_right=12;
- Left_moto_go ; //左電機往前走
- Right_moto_back ; //右電機往后走
- delay(490) ;
- }
- //右小偏
- void rightp_1(void)
- {
- push_val_left=12;
- push_val_right=3;
- Left_moto_go ; //左電機往前走
- Right_moto_go ; //右電機往后走
- }
- //右中偏
- void rightp_2(void)
- {
- push_val_left=12;
- push_val_right=1;
- Left_moto_go ; //左電機往前走
- Right_moto_back ; //右電機往后走
- }
- //右大偏
- void rightp_3(void)
- {
- push_val_left=12;
- push_val_right=3;
- Left_moto_go ; //左電機往前走
- Right_moto_back ; //右電機往后走
-
-
- }
- //停止
- void stop(void)
- {
- delay(200);
- Right_moto_Stop ; //右電機停止
- Left_moto_Stop ; //左電機停止
- delay(100);
- }
- //掉頭
- void Return(void)
- {
- push_val_left=18;
- push_val_right=18;
- Left_moto_go ; //左電機往前走
- Right_moto_back ; //右電機往后走
- delay(700) ;
-
- }
-
- /************************************************************************/
- /* PWM調制電機轉速 */
- /************************************************************************/
- /* 左電機調速 */
- /*調節push_val_left的值改變電機轉速,占空比 */
- void pwm_out_left_moto(void)
- {
- if(Left_moto_stop)
- {
- if(pwm_val_left<=push_val_left)
- {
- Left_moto_pwm=1;
-
- }
- else
- {
- Left_moto_pwm=0;
- }
- if(pwm_val_left>=20)
- pwm_val_left=0;
- }
- else
- {
- Left_moto_pwm=0;
-
- }
- }
- /******************************************************************/
- /* 右電機調速 */
- void pwm_out_right_moto(void)
- {
- if(Right_moto_stop)
- {
- if(pwm_val_right<=push_val_right)
- {
- Right_moto_pwm=1;
-
- }
- else
- {
- Right_moto_pwm=0;
- }
- if(pwm_val_right>=20)
- pwm_val_right=0;
- }
- else
- {
- Right_moto_pwm=0;
- }
- }
-
- /***************************************************/
- ///*TIMER0中斷服務子函數產生PWM信號*/
- void timer0()interrupt 1 using 2
- {
- TH0=0XFc; //1Ms定時
- TL0=0X18;
- pwm_val_left++;
- pwm_val_right++;
- pwm_out_left_moto();
- pwm_out_right_moto();
- }
- /*********************************************************************/
- #endif
復制代碼
|