小車用的是52單片機的四驅wifi,兩側電機串聯,超聲波模塊是便宜實用的HC-SR04
0.png (356.89 KB, 下載次數: 69)
下載附件
2017-10-17 17:40 上傳
單片機源程序:
- /****************************************************************************
- 硬件連接
- ****************************************************************************/
- #include<reg52.h>
- #include <intrins.h>
- #define ECHO1 P1_0 //超聲波接口定義
- #define TX1 P1_1 //超聲波接口定義
- #define ECHO2 P1_2 //超聲波接口定義
- #define TX2 P1_3 //超聲波接口定義
- #define ECHO3 P1_4 //超聲波接口定義
- #define TX3 P1_5 //超聲波接口定義
- #define ECHO4 P1_6 //超聲波接口定義
- #define TX4 P1_7 //超聲波接口定義
- #define ECHO5 P0_0 //超聲波接口定義
- #define TX5 P0_1 //超聲波接口定義
- #define Left_moto_pwm P2_2 //PWM信號端
- #define Right_moto_pwm P2_3 //PWM信號端
- sbit IN1=P2^0;
- sbit IN2=P2^1;
- sbit IN3=P2^4;
- sbit IN4=P2^5;
- sbit EN1=P2^2;
- sbit EN2=P2^3;
- bit Right_moto_stop=1;
- bit Left_moto_stop =1;
- #define Left_moto_go {IN1=0,IN2=1,EN1=1;} //左電機向前走
- #define Left_moto_back {IN1=1,IN2=0,EN1=1;} //左邊電機向后走
- #define Left_moto_Stop {EN1=0;} //左邊電機停轉
- #define Right_moto_go {IN3=1,IN4=0,EN2=1;} //右邊電機向前走
- #define Right_moto_back {IN3=0,IN4=1,EN2=1;} //右邊電機向后走
- #define Right_moto_Stop {EN2=0;} //右邊電機停轉
- unsigned char pwm_val_left =0;//變量定義
- unsigned char push_val_left =0;// 左電機占空比N/20
- unsigned char pwm_val_right =0;
- unsigned char push_val_right=0;// 右電機占空比N/20
-
- unsigned int time=0;
- unsigned int timer=0;
- unsigned long S1=0;
- unsigned long S2=0;
- unsigned long S3=0;
- unsigned long S4=0;
- unsigned long S5=0;
- unsigned char timer1=0; //掃描時間變量
- /************************************************************************/
- void delay(unsigned char x) //1ms延時函數,100ms以內可用
- {
- unsigned char i;
- while(x--)
- for(i=124;i>0;i--);
- }
- void Conut1(void) //計算距離
- {
- while(!ECHO1); //當RX為零時等待
- TR0=1; //開啟計數
- while(ECHO1); //當RX為1計數并等待
- TR0=0; //關閉計數
- time=TH0*256+TL0; //讀取脈寬長度
- TH0=0;
- TL0=0;
- S1=(time*1.7)/100; //算出來是CM
- }
- void Conut2(void) //計算距離
- {
- while(!ECHO2); //當RX為零時等待
- TR0=1; //開啟計數
- while(ECHO2); //當RX為1計數并等待
- TR0=0; //關閉計數
- time=TH0*256+TL0; //讀取脈寬長度
- TH0=0;
- TL0=0;
- S2=(time*1.7)/100; //算出來是CM
- }
- void Conut3(void) //計算距離
- {
- while(!ECHO3); //當RX為零時等待
- TR0=1; //開啟計數
- while(ECHO3); //當RX為1計數并等待
- TR0=0; //關閉計數
- time=TH0*256+TL0; //讀取脈寬長度
- TH0=0;
- TL0=0;
- S3=(time*1.7)/100; //算出來是CM
- }
- void Conut4(void) //計算距離
- {
- while(!ECHO4); //當RX為零時等待
- TR0=1; //開啟計數
- while(ECHO4); //當RX為1計數并等待
- TR0=0; //關閉計數
- time=TH0*256+TL0; //讀取脈寬長度
- TH0=0;
- TL0=0;
- S4=(time*1.7)/100; //算出來是CM
- }
- void Conut5(void) //計算距離
- {
- while(!ECHO5); //當RX為零時等待
- TR0=1; //開啟計數
- while(ECHO5); //當RX為1計數并等待
- TR0=0; //關閉計數
- time=TH0*256+TL0; //讀取脈寬長度
- TH0=0;
- TL0=0;
- S5=(time*1.7)/100; //算出來是CM
- }
- //全速前進
- void run(void)
- {
- push_val_left=20; //左電機調速,速度調節變量 0-20。。。0最小,20最大,四驅大輪>6
- push_val_right=18; //右電機調速
- Left_moto_go ; //左電機往前走
- Right_moto_go ; //右電機往前走
-
- }
- /************************************************************************/
- //全速后退
- void backrun(void)
- {
- push_val_left=20;
- push_val_right=18 ;
- Left_moto_back ; //左電機往前走
- Right_moto_back ; //右電機往前走
- }
- /************************************************************************/
- //左轉
- void leftrun(void)
- {
- push_val_left=13;
- push_val_right=10;
- Left_moto_back ; //左電機往后走
- Right_moto_go ; //右電機往前走
- }
- /************************************************************************/
- //右轉
- void rightrun(void)
- {
- push_val_left=13;
- push_val_right=10;
- Left_moto_go ; //左電機往前走
- Right_moto_back ; //右電機往后走
- }
- /************************************************************************/
- //STOP
- void stoprun(void)
- {
- Left_moto_Stop ; //左電機停
- Right_moto_Stop ; //右電機停
- }
- /************************************************************************/
- void COMM( void )
- {
-
- TX1=1;
- delay(1);
- TX1=0; //啟動超聲波測距
- Conut1(); //計算距離
-
- TX2=1;
- delay(1);
- TX2=0; //啟動超聲波測距
- Conut2(); //計算距離
-
- TX3=1;
- delay(1);
- TX3=0; //啟動超聲波測距
- Conut3(); //計算距離
- TX4=1;
- delay(1);
- TX4=0; //啟動超聲波測距
- Conut4(); //計算距離
- TX5=1;
- delay(1);
- TX5=0; //啟動超聲波測距
- Conut5(); //計算距離
-
- if(S1<20 && S3<30 && S5<20) //進入狹窄通道
- {
- backrun(); //倒車
- }
- if(S2<20 && S3<30 && S4<20) //進入狹窄通道
- {
- backrun(); //倒車
- if(S2>30 && S3>30)
- leftrun();
- if(S4>30 && S3>30)
- rightrun();
- }
- else
- if(S1<20)
- {
- rightrun(); //車與障礙物呈45度角時,車的左邊比車的右邊距離小,右轉
- }
- else
- if(S2<20)
- {
- rightrun(); //車與障礙物呈45度角時,車的左邊比車的右邊距離小,右轉
- }
- else
- if(S3<30 ) //車子與障礙物90度垂直,右邊距離小左轉
- {
- backrun();
- if(S2>20&&S4<20)
- {
- leftrun(); //車與障礙物呈45度角時,車的左邊比車的右邊距離小,右轉
- if(S2<20&&S4>20)
- { backrun(); //車與障礙物呈45度角時,車的左邊比車的右邊距離小,右轉
- delay(90);
- delay(90);
- }
- }
- }
- else
- if(S4<20)
- {
- leftrun(); //車與障礙物呈45度角時,車的右邊比車的左邊距離小,左轉
- }
- else
- if(S5<20)
- {
- leftrun(); //車與障礙物呈45度角時,車的右邊比車的左邊距離小,左轉
- }
- else
- if(S3<30 && S1<S5 ) //車子與障礙物90度垂直,左邊距離小右轉
- {
- rightrun();
- }
- else
- if(S3<30 && S1>S5 ) //車子與障礙物90度垂直,右邊距離小左轉
- {
- leftrun();
- }
- else
- if(S1<20&&S5<20)
- {
- backrun();
- }
- else
- if(S3<30&&S2<20)
- {
- rightrun(); //車與障礙物呈45度角時,車的左邊比車的右邊距離小,右轉
- }
- else
- if(S3<30&&S4<20)
- {
- leftrun(); //車與障礙物呈45度角時,車的右邊比車的左邊距離小,左轉
- }
- else
- if(S3>30&&S4<20)
- {
- leftrun(); //車與障礙物呈45度角時,車的右邊比車的左邊距離小,左轉
- }
- else
- if(S3>30&&S2<20)
- {
- rightrun(); //車與障礙物呈45度角時,車的左邊比車的右邊距離小,右轉
- }
-
- else
- if(S2>20&&S4<20)
- {
- leftrun(); //車與障礙物呈45度角時,車的左邊比車的右邊距離小,右轉
- if(S2<20&&S4>20)
- { backrun(); //車與障礙物呈45度角時,車的左邊比車的右邊距離小,右轉
- delay(90);
- delay(90);
- }
- }
- else
- {
- run();
- }
- }
- /************************************************************************/
- /* 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;
- }
- }
- ///*TIMER1中斷服務子函數產生PWM信號*/
- void time1()interrupt 3 using 2
- {
- TH1=(65536-100)/256; //100US定時
- TL1=(65536-100)%256;
- timer++;
- pwm_val_left++;
- pwm_val_right++;
- pwm_out_left_moto();
- pwm_out_right_moto(); //定時器100US為準。在這個基礎上延時
- }
- /***************************************************/
- ///*TIMER0中斷服務子函數產生PWM信號*/
- void timer0()interrupt 1
- {
- }
- /***************************************************/
- void main(void)
- {
- TMOD=0X11;
- TH1=(65536-100)/256; //100US定時
- TL1=(65536-100)%256;
- TH0=0;
- TL0=0;
- TR1= 1;
- ET1= 1;
- ET0= 1;
- EA = 1;
- delay(100);
- while(1) /*無限循環*/
- {
- COMM();
- }
- }
復制代碼 |