|
功能:藍(lán)牙遙控超聲波避障oled屏幕顯示
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
單片機(jī)源程序如下:
- #include<AT89x52.H>
- #include <intrins.h>
- #include "oled.h"
- #define Left_moto_go {P1_2=1,P1_3=0;} //左邊兩個(gè)電機(jī)向前走
- #define Left_moto_back {P1_2=0,P1_3=1;} //左邊兩個(gè)電機(jī)向后轉(zhuǎn)
- #define Left_moto_Stop {P1_2=0,P1_3=0;} //左邊兩個(gè)電機(jī)停轉(zhuǎn)
- #define Right_moto_go {P1_6=1,P1_7=0;} //右邊兩個(gè)電機(jī)向前走
- #define Right_moto_back {P1_6=0,P1_7=1;} //右邊兩個(gè)電機(jī)向前走
- #define Right_moto_Stop {P1_6=0,P1_7=0;} //右邊兩個(gè)電機(jī)停轉(zhuǎn)
- #define ECHO P2_0 //超聲波接口定義
- #define TRIG P2_1 //超聲波接口定義
- #define Sevro_moto_pwm P2_2 //接舵機(jī)信號(hào)端輸入PWM信號(hào)調(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' //手機(jī)軟件1號(hào)鍵
- #define Beep '5' //手機(jī)軟件5號(hào)鍵
- unsigned char disbuff[4] ={ 0,0,0,0,};
- unsigned char pwm_val_left = 0;//變量定義
- unsigned char push_val_left =15;//舵機(jī)歸中,產(chǎn)生約,1.5MS 信號(hào)
- unsigned int time=0; //時(shí)間變量
- unsigned int timer=0; //延時(shí)基準(zhǔn)變量
- unsigned long S=0; //計(jì)算出超聲波距離值
- unsigned long S1=0;
- unsigned long S2=0;
- unsigned long S3=0;
- unsigned long S4=0;
- bit flag_REC=0; //串行接收標(biāo)去位
- 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í)函數(shù)
- void delay(unsigned int k)
- {
- unsigned int x,y;
- for(x=0;x<k;x++)
- for(y=0;y<2000;y++);
- }
- /************************************************************************/
- //前速前進(jìn)
- void run(void)
- {
- Left_moto_go ; //左電機(jī)往前走
- Right_moto_go ; //右電機(jī)往前走
- }
- //前速后退
- void backrun(void)
- {
- Left_moto_back ; //左電機(jī)往前走
- Right_moto_back ; //右電機(jī)往前走
- }
- //左轉(zhuǎn)
- void leftrun(void)
- {
- Left_moto_back ; //左電機(jī)往前走
- Right_moto_go ; //右電機(jī)往前走
- }
- //右轉(zhuǎn)
- void rightrun(void)
- {
- Left_moto_go ; //左電機(jī)往前走
- Right_moto_back ; //右電機(jī)往前走
- }
- //STOP
- void stoprun(void)
- {
- Left_moto_Stop ; //左電機(jī)往前走
- Right_moto_Stop ; //右電機(jī)往前走
- }
- void whistle(void)
- {
- BEEP=0;
- }
- /************************************************************************/
- void StartModule() //啟動(dòng)測距信號(hào)
- {
- 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) //計(jì)算距離
- {
- while(!ECHO); //當(dāng)RX為零時(shí)等待
- TR0=1; //開啟計(jì)數(shù)
- while(ECHO); //當(dāng)RX為1計(jì)數(shù)并等待
- TR0=0; //關(guān)閉計(jì)數(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; //舵機(jī)向左轉(zhuǎn)90度
- timer=0;
- while(timer<=4000); //延時(shí)400MS讓舵機(jī)轉(zhuǎn)到其位置
- StartModule(); //啟動(dòng)超聲波測距
- Conut(); //計(jì)算距離
- S2=S;
- OLED_ShowNum(103,2,S2,3,16);//左側(cè)距離
- push_val_left=20; //舵機(jī)向右轉(zhuǎn)90度
- timer=0;
- while(timer<=4000); //延時(shí)400MS讓舵機(jī)轉(zhuǎn)到其位置
- StartModule(); //啟動(dòng)超聲波測距
- Conut(); //計(jì)算距離
- S4=S;
- OLED_ShowNum(103,6,S4,3,16);//右側(cè)距離
- push_val_left=15; //舵機(jī)歸中
- timer=0;
- while(timer<=4000); //延時(shí)400MS讓舵機(jī)轉(zhuǎn)到其位置
- StartModule(); //啟動(dòng)超聲波測距
- Conut(); //計(jì)算距離
- S1=S;
- if((S2<20)||(S4<20)) //只要左右各有距離小于,20CM小車后退
- {
- backrun(); //后退
- timer=0;
- while(timer<=4000);
- }
-
- if(S2>S4)
- {
- rightrun(); //車的左邊比車的右邊距離小 右轉(zhuǎn)
- timer=0;
- while(timer<=400);
- }
- else
- {
- leftrun(); //車的左邊比車的右邊距離大 左轉(zhuǎn)
- timer=0;
- while(timer<=400);
- }
-
- }
- /************************************************************************/
- /* PWM調(diào)制舵機(jī)信號(hào) */
- /************************************************************************/
- /* 左電機(jī)調(diào)速 */
- /*調(diào)節(jié)push_val_left的值改變電機(jī)轉(zhuǎn)速,占空比 */
- 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中斷服務(wù)子函數(shù)產(chǎn)生PWM信號(hào)*/
- void time1()interrupt 3 using 2
- {
- TH1=(65536-100)/256; //100US定時(shí)
- TL1=(65536-100)%256;
- timer++; //定時(shí)器100US為準(zhǔn)。在這個(gè)基礎(chǔ)上延時(shí)
- pwm_val_left++;
- pwm_Servomoto();
- }
- /************************************************************************/
- void sint() interrupt 4 //中斷接收3個(gè)字節(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定時(shí)
- 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; //舵機(jī)歸中
- 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);//側(cè)
- 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);//側(cè)
- 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檢測啟動(dòng)檢測一次
- {
- timer=0;
- StartModule(); //啟動(dòng)檢測
- Conut(); //計(jì)算距離
- if(S<20) //距離小于20CM
- {
- stoprun(); //小車停止
- COMM(); //方向函數(shù)
- }
- else
- if(S>30) //距離大于,30CM往前走
- run();
- }
- if(flag_REC==1)
- {
- push_val_left=15; //舵機(jī)歸中
- stoprun();
- break;
- }
- }
- if(flag_REC==1) //
- {
- flag_REC=0;
- if(buff[0]=='O'&&buff[1]=='N') //第一個(gè)字節(jié)為O,第二個(gè)字節(jié)為N,第三個(gè)字節(jié)為控制碼
- BEEP=1;
- switch(buff[2])
- {
- case up : // 前進(jìn)
- flag_xj=0;
- flag_bj=0;
- run();
- break;
- case down: // 后退
- flag_xj=0;
- flag_bj=0;
- backrun();
- break;
- case left: // 左轉(zhuǎn)
- flag_xj=0;
- flag_bj=0;
- leftrun();
- break;
- case right: // 右轉(zhuǎn)
- 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;
- }
- }
- }
- }
-
復(fù)制代碼 原理圖和pcb下載:
原理圖和PCB.7z
(15.05 MB, 下載次數(shù): 269)
2024-1-24 02:58 上傳
點(diǎn)擊文件名下載附件
|
評(píng)分
-
查看全部評(píng)分
|