超聲波避障+藍牙遙控智能小車
單片機源程序如下:
- #include<reg52.h>
- #include <intrins.h>
- typedef unsigned char u8;
- typedef unsigned int u16;
- typedef unsigned long u32;
- sbit Sevro_moto_pwm = P2^6; //接舵機信號端輸入PWM信號調節速度
- sbit ECHO= P1^1; //超聲波接口定義
- sbit TRIG= P1^0; //超聲波接口定義
- sbit PWM1 = P2^5; //左電機高電平
- sbit PWM2 = P2^4; //右電機高電平
- sbit IN1 = P2^3;
- sbit IN2 = P2^2; //左電機
- sbit IN3 = P2^1;
- sbit IN4 = P2^0; //右電機
- sbit A1 = P1^4; //左紅外避障模塊
- sbit A2 = P2^7; //右紅外避障模塊
- //sbit A3 = P1^2; //左紅外尋跡模塊
- //sbit A4 = P1^3; //右紅外尋跡模塊
- sbit K1 = P3^2; //功能轉換按鍵
- sbit K2 = P3^3; //加速鍵
- sbit K3 = P3^4; //減速鍵
- u8 connt; //調速周期
- u8 PWM_NO; //高電平時間
- u8 a=0,c=0; //標志位
- u8 COM;
- u8 pwm_val_left = 0;//變量定義
- u8 push_val_left ;//舵機歸中,產生約,1.5MS 信號
- u32 S=0; //距離變量定義
- u32 S1=0;
- u32 S2=0;
- u32 S3=0;
- u32 S4=0;
- u16 time=0; //時間變量
- u16 timer=0; //延時基準變量
- u8 non=0,t=0;
- u8 pon=3; //數碼管顯示
- u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f};//顯示0~9的值
-
- /************************************************************************/
- void delay(u16 k) //延時函數
- {
- u16 x,y;
- for(x=0;x<k;x++)
- for(y=0;y<2000;y++);
- }
- void delay1(u16 j) //延時函數
- {
- u16 x,y;
- for(x=0;x<j;x++)
- for(y=0;y<120;y++);
- }
- /************************************************************************/
- void Display(void) //掃描數碼管
- {
- P0=smgduan[pon];
- if(K2==0) // 加速
- {
- delay1(10);
- if(K2==0)
- {
- pon++;
- PWM_NO--;
- }
- while(!K2); //松鍵檢測
- }
- if(K3==0) //減速
- {
- delay1(10);
- if(K3==0)
- {
- pon--;
- PWM_NO++;
- }
- while(!K3);
- }
- }
- void SC() //剎車
- {
- IN1 = 0;
- IN2 = 0;
- IN3 = 0;
- IN4 = 0;
- }
- void QJ() //前進
- {
- IN1 = 1;
- IN2 = 0;
- IN3 = 1;
- IN4 = 0;
- }
- void HT() //后退
- {
- IN1 = 0;
- IN2 = 1;
- IN3 = 0;
- IN4 = 1;
- }
- void ZZ1() //左大轉
- {
- IN1 = 0;
- IN2 = 1;
- IN3 = 1;
- IN4 = 0;
- }
- void YZ1() //右大轉
- {
- IN1 = 1;
- IN2 = 0;
- IN3 = 0;
- IN4 = 1;
- }
- /************************************************************************/
- void StartModule() //啟動測距信號
- {
- TRIG=1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- TRIG=0;
-
- }
- void InitUART(void) //串口中斷初始化函數
- {
- SCON=0x50; //設置為工作方式1
- TMOD=0x20; //設置計數器工作方式2
- PCON=0x00; //波特率不加倍
- TH1=0xfd; //計數器初始值設置,注意波特率是9600的
- TL1=0xfd;
- ES=1; //打開接收中斷
- EA=1; //打開總中斷
- TR1=1; //打開計數器
-
- }
- /***************************************************/
- void Conut(void) //計算距離
- {
- while(!ECHO); //當RX為零時等待
- TR1=1; //開啟計數
- while(ECHO); //當RX為1計數并等待
- TR1=0; //關閉計數
- time=TH1*256+TL1; //讀取脈寬長度
- TH1=0;
- TL1=0;
- S=(time*1.7)/100; //算出來是CM
-
- }
- /************************************************************************/
- void COMM( void )
- {
-
- push_val_left=23; //舵機向左轉90度
- timer=0;
- while(timer<=4000); //延時400MS讓舵機轉到其位置 4000
- StartModule(); //啟動超聲波測距
- Conut(); //計算距離
- S2=S;
-
- push_val_left=5; //舵機向右轉90度
- timer=0;
- while(timer<=4000); //延時400MS讓舵機轉到其位置
- StartModule(); //啟動超聲波測距
- Conut(); //計算距離
- S4=S;
-
- push_val_left=14; //舵機歸中
- timer=0;
- while(timer<=4000); //延時400MS讓舵機轉到其位置
- StartModule(); //啟動超聲波測距
- Conut(); //計算距離
- S1=S;
- if((S2<20)||(S4<20)||(S1<20)) //只要左右各有距離小于,20CM小車后退
- {
- HT(); //后退
- timer=0;
- while(timer<=4000);
- }
- if((S2<20)&&(S4<20)&&(S1<20)) //只要左右各有距離小于,20CM小車后退
- {
- HT(); //后退
- timer=0;
- while(timer<=4000);
- }
-
- if(S2>S4)
- {
- ZZ1(); //車的左邊比車的右邊距離小 右轉
- timer=0;
- while(timer<=4000);
- }
- else
- {
- YZ1(); //車的左邊比車的右邊距離大 左轉
- timer=0;
- while(timer<=4000);
- }
-
-
- }
- /************************************************************************/
- /* PWM調制舵機轉速 */
- /************************************************************************/
- /* 舵機調速 */
- /*調節push_val_left的值改變電機轉速,占空比 */
- void pwm_Servomoto(void)
- {
-
- if(pwm_val_left <= push_val_left)
- Sevro_moto_pwm=1;
- else
- Sevro_moto_pwm=0;
- if(pwm_val_left>=100)
- pwm_val_left=0;
-
- }
- void minm() //按鈕控制功能轉換
- {
- COM=0;
- if(K1==0)
- {
- delay1(10);
- if(K1==0)
- {
- COM++;
- }
- while(!K1);
- }
- if(COM==4)
- COM=0;
- }
- /***************************************************/
- ///*TIMER1中斷服務子函數產生PWM信號*/
- void time0()interrupt 1
- {
-
- TH0=(65536-100)/256; //100US定時
- TL0=(65536-100)%256;
- timer++; //定時器100US為準。在這個基礎上延時
- pwm_val_left++;
- pwm_Servomoto();
- t++;
- if(t==5) //PWM調制左右電機速度
- {
- t=0;
- non++;
- }
- if( non == PWM_NO )
- {
- PWM1 = 1;
- PWM2 = 1;
- }
- if( non == connt )
- {
- non = 0;
- if( PWM_NO != 0)
- {
- PWM1 = 0;
- PWM2 = 0;
- }
- }
- }
- void lin() //避障功能
- {
- if(timer>=1000) //100MS檢測啟動檢測一次 1000
- {
- timer=0;
- StartModule(); //啟動檢測
- Conut(); //計算距離
- if(S<=25) //距離小于30CM
- {
- SC(); //小車停止
- COMM(); //方向函數
- }
- else
- if(S>25) //距離大于,30CM往前走
- QJ();
- if(!A1)
- {
- SC();
- delay1(20);
- HT();
- delay1(300);
- SC();
- COMM();
- }
- if(!A2)
- {
- SC();
- delay1(20);
- HT();
- delay1(300);
- SC();
- COMM();
- }
- }
-
- }
- /***************************************************/
- ///*TIMER0中斷服務子函數產生PWM信號*/
- void timer0()interrupt 3
- {
-
- }
- /***************************************************/
- void UARTInterrupt(void) interrupt 4 //串口中斷函數
- {
- unsigned char com;
- if(a==1) //判斷能否執行
- {
- if(RI==1)
- com = SBUF; //暫存接收到的數據
- RI=0;
- }
- P0=smgduan[pon];
- switch(com) //接收到字符并要執行的功能
- {
- case 0: QJ();break;
- case 1: SC();break;
- case 2: ZZ1();break;
- case 3: YZ1();break;
- case 4: HT();break;
- case 5: pon++;PWM_NO--;break;
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
Keil代碼下載:
超聲波避障 藍牙遙控智能小車.rar
(40.42 KB, 下載次數: 567)
2018-5-12 14:57 上傳
點擊文件名下載附件
|