功能:藍牙遙控超聲波避障oled屏幕顯示
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
51hei.png (42.57 KB, 下載次數(shù): 98)
下載附件
2021-11-6 18:58 上傳
51hei.png (71.67 KB, 下載次數(shù): 92)
下載附件
2021-11-6 18:58 上傳
單片機源程序如下:
- #include<AT89x52.H>
- #include <intrins.h>
- #include "oled.h"
- #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_6=1,P1_7=0;} //右邊兩個電機向前走
- #define Right_moto_back {P1_6=0,P1_7=1;} //右邊兩個電機向前走
- #define Right_moto_Stop {P1_6=0,P1_7=0;} //右邊兩個電機停轉
- #define ECHO P2_0 //超聲波接口定義
- #define TRIG P2_1 //超聲波接口定義
- #define Sevro_moto_pwm P2_2 //接舵機信號端輸入PWM信號調(diào)節(jié)速度
- #define BEEP P2_3
- #define left 'C'
- #define right 'D'
- #define up 'A'
- #define down 'B'
- #define stop 'F'
- #define Car1 '2' //手機軟件1號鍵
- #define Beep '5' //手機軟件5號鍵
- unsigned char disbuff[4] ={ 0,0,0,0,};
- unsigned char pwm_val_left = 0;//變量定義
- unsigned char push_val_left =15;//舵機歸中,產(chǎn)生約,1.5MS 信號
- unsigned int time=0; //時間變量
- unsigned int timer=0; //延時基準變量
- unsigned long S=0; //計算出超聲波距離值
- unsigned long S1=0;
- unsigned long S2=0;
- unsigned long S3=0;
- unsigned long S4=0;
- bit flag_REC=0; //串行接收標去位
- bit flag =0;
- bit flag_xj =0;
- bit flag_bj =0;
-
- unsigned char i=0;
- unsigned char dat=0;
- unsigned char buff[5]=0; //接收緩沖字節(jié)
- /************************************************************************/
- //延時函數(shù)
- void delay(unsigned int k)
- {
- unsigned int x,y;
- for(x=0;x<k;x++)
- for(y=0;y<2000;y++);
- }
- /************************************************************************/
- //前速前進
- void run(void)
- {
- Left_moto_go ; //左電機往前走
- Right_moto_go ; //右電機往前走
- }
- //前速后退
- void backrun(void)
- {
- Left_moto_back ; //左電機往前走
- Right_moto_back ; //右電機往前走
- }
- //左轉
- void leftrun(void)
- {
- Left_moto_back ; //左電機往前走
- Right_moto_go ; //右電機往前走
- }
- //右轉
- void rightrun(void)
- {
- Left_moto_go ; //左電機往前走
- Right_moto_back ; //右電機往前走
- }
- //STOP
- void stoprun(void)
- {
- Left_moto_Stop ; //左電機往前走
- Right_moto_Stop ; //右電機往前走
- }
- void whistle(void)
- {
- BEEP=0;
- }
- /************************************************************************/
- 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 Conut(void) //計算距離
- {
- while(!ECHO); //當RX為零時等待
- TR0=1; //開啟計數(shù)
- while(ECHO); //當RX為1計數(shù)并等待
- TR0=0; //關閉計數(shù)
- time=TH0*256+TL0; //讀取脈寬長度
- TH0=0;
- TL0=0;
- S=(time*1.7)/100; //算出來是CM
- OLED_ShowNum(103,4,S,3,16);//距離
- }
-
- /************************************************************************/
- void COMM( void )
- {
- push_val_left=10; //舵機向左轉90度
- timer=0;
- while(timer<=4000); //延時400MS讓舵機轉到其位置
- StartModule(); //啟動超聲波測距
- Conut(); //計算距離
- S2=S;
- OLED_ShowNum(103,2,S2,3,16);//左側距離
- push_val_left=20; //舵機向右轉90度
- timer=0;
- while(timer<=4000); //延時400MS讓舵機轉到其位置
- StartModule(); //啟動超聲波測距
- Conut(); //計算距離
- S4=S;
- OLED_ShowNum(103,6,S4,3,16);//右側距離
- push_val_left=15; //舵機歸中
- timer=0;
- while(timer<=4000); //延時400MS讓舵機轉到其位置
- StartModule(); //啟動超聲波測距
- Conut(); //計算距離
- S1=S;
- if((S2<20)||(S4<20)) //只要左右各有距離小于,20CM小車后退
- {
- backrun(); //后退
- timer=0;
- while(timer<=4000);
- }
-
- if(S2>S4)
- {
- rightrun(); //車的左邊比車的右邊距離小 右轉
- timer=0;
- while(timer<=400);
- }
- else
- {
- leftrun(); //車的左邊比車的右邊距離大 左轉
- timer=0;
- while(timer<=400);
- }
-
- }
- /************************************************************************/
- /* PWM調(diào)制舵機信號 */
- /************************************************************************/
- /* 左電機調(diào)速 */
- /*調(diào)節(jié)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>=200)
- pwm_val_left=0;
- }
- /***************************************************/
- ///*TIMER1中斷服務子函數(shù)產(chǎn)生PWM信號*/
- void time1()interrupt 3 using 2
- {
- TH1=(65536-100)/256; //100US定時
- TL1=(65536-100)%256;
- timer++; //定時器100US為準。在這個基礎上延時
- pwm_val_left++;
- pwm_Servomoto();
- }
- /************************************************************************/
- void sint() interrupt 4 //中斷接收3個字節(jié)
- {
- if(RI) //是否接收中斷
- {
- RI=0;
- dat=SBUF;
- if(dat=='O'&&(i==0)) //接收數(shù)據(jù)第一幀
- {
- buff[i]=dat;
- flag=1; //開始接收數(shù)據(jù)
- }
- else
- if(flag==1)
- {
- i++;
- buff[i]=dat;
- if(i>=2)
- {i=0;flag=0;flag_REC=1 ;} // 停止接收
- }
- }
- }
- /*********************************************************************/
- /*--主函數(shù)--*/
- void main(void)
- {
- TMOD=0x11;
- TH1=(65536-100)/256; //100US定時
- TL1=(65536-100)%256;
- TH0=0;
- TL0=0;
- T2CON=0x34;
- T2MOD=0x00;
- RCAP2H=0xFF;
- RCAP2L=0xDC;
- SCON=0x50;
- PCON=0x00;
- PS=1;
- TR1=1;
- ET1=1;
- ES=1;
- EA=1;
-
- delay(100);
- OLED_Init(); //初始化OLED
- OLED_Clear();
- BEEP=1;
- push_val_left=15; //舵機歸中
- OLED_ShowCHinese(0,0,0);//信
- OLED_ShowCHinese(16,0,1);//息
- OLED_ShowString(32,0,"1902",16);
- OLED_ShowCHinese(64,0,2);//王
- OLED_ShowCHinese(80,0,3);//晨
- OLED_ShowCHinese(0,2,6);//左
- OLED_ShowCHinese(16,2,9);//側
- OLED_ShowCHinese(32,2,4);//距
- OLED_ShowCHinese(48,2,5);//離
- OLED_ShowCHinese(64,2,10);//:
-
- OLED_ShowCHinese(32,4,4);//距
- OLED_ShowCHinese(48,4,5);//離
- OLED_ShowCHinese(64,4,10);//:
-
- OLED_ShowCHinese(0,6,7);//右
- OLED_ShowCHinese(16,6,9);//側
- OLED_ShowCHinese(32,6,4);//距
- OLED_ShowCHinese(48,6,5);//離
- OLED_ShowCHinese(64,6,10);//:
- while(1) /*無限循環(huán)*/
- {
- while(flag_bj) /*無限循環(huán)*/
- {
- if(timer>=1000) //100MS檢測啟動檢測一次
- {
- timer=0;
- StartModule(); //啟動檢測
- Conut(); //計算距離
- if(S<20) //距離小于20CM
- {
- stoprun(); //小車停止
- COMM(); //方向函數(shù)
- }
- else
- if(S>30) //距離大于,30CM往前走
- run();
- }
- if(flag_REC==1)
- {
- push_val_left=15; //舵機歸中
- stoprun();
- break;
- }
- }
- if(flag_REC==1) //
- {
- flag_REC=0;
- if(buff[0]=='O'&&buff[1]=='N') //第一個字節(jié)為O,第二個字節(jié)為N,第三個字節(jié)為控制碼
- BEEP=1;
- switch(buff[2])
- {
- case up : // 前進
- flag_xj=0;
- flag_bj=0;
- run();
- break;
- case down: // 后退
- flag_xj=0;
- flag_bj=0;
- backrun();
- break;
- case left: // 左轉
- flag_xj=0;
- flag_bj=0;
- leftrun();
- break;
- case right: // 右轉
- flag_bj=0;
- rightrun();
- break;
- case stop: // 停止
- flag_bj=0;
- stoprun();
- break;
- case Car1: //
- flag_bj=1;
- break;
-
- case Beep:
- flag_bj=0;
- whistle();
- break;
- }
- }
- }
- }
-
復制代碼 原理圖和pcb下載:
原理圖和PCB.7z
(15.05 MB, 下載次數(shù): 269)
2024-1-24 02:58 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|