|
壁障小車
0.png (54.69 KB, 下載次數(shù): 92)
下載附件
2017-7-3 02:58 上傳
單片機(jī)源程序如下:
- /*******************************************************
- * 項(xiàng)目名稱:循跡避障小車
- * 單 片 機(jī):STC89C52RC
- * 功 能:循跡,紅外遙控,超聲波避障,舵機(jī),PWM,跟蹤
- * 作 者:劉琦
- * IO口定義:紅外循跡 P3^4,P3^5
- * 紅外避障 P3^6,P3^7
- * 電機(jī) P1^0~P1^7
- * 超聲波避障 P2^4~P2^5
- * 紅外遙控 P3^3
- * 舵機(jī) P2^3
- * 數(shù)碼管段選 P0
- * 數(shù)碼管位選 P2^0~P2^3
- * 遙 控 器:2 前進(jìn) (18)
- * 8 后退 (52)
- * 5 停止 (1C)
- * 4 左轉(zhuǎn) (08)
- * 6 右轉(zhuǎn) (5A)
- * 1 遙控模式 (0C)
- * 3 循跡模式 (5E)
- * 7 跟隨模式 (42)
- * 9 避障模式 (4A)
- * + 加速 (15)
- * - 減速 (07)
- * 定 時(shí) 器:T0 PWM(電機(jī)、舵機(jī)),數(shù)碼管(超聲波測(cè)距)
- * T1 紅外遙控計(jì)時(shí)
- * T2 超聲波計(jì)時(shí)
- *******************************************************/
- /******************************頭文件區(qū)***********************************************/
- #include <reg52.h>
- #include "Dianji.h"
- #include "Yaokong.h"
- #include "RTX51TNY.H"
- #include "Chaoshengbo.h"
- #include "Duoji.h"
- /******************************宏定義區(qū)***********************************************/
- //需要定時(shí)刷新的任務(wù)數(shù),0YaoKong,1Display,2CSB
- #define NUM_TASK_REFRESH 3
- //刷新頻率
- //#define TIME_PER_SEC 200 //每次進(jìn)入中斷的頻率,200Hz,5ms
- #define TIME_PER_SEC 10000 //每次進(jìn)入中斷的頻率,10000Hz,0.1ms
- #define TIME_CLOCK 11059200 //晶振頻率
- #define TIME_YAOKONG_50HZ TIME_PER_SEC/50 //響應(yīng)遙控命令頻率,0.02s
- #define TIME_SUMA_300HZ TIME_PER_SEC/300 //超聲波距離顯示數(shù)碼管刷新頻率,0.003s
- #define TIME_CSB_5HZ TIME_PER_SEC/5 //超聲波自動(dòng)檢測(cè)的頻率,0.2s
- #define FLAG_YAOKONG 0
- #define FLAG_XUNJI 1
- #define FLAG_BIZHANG 2
- #define FLAG_GENSUI 3
-
- #define FLAG_GO 0
- #define FLAG_BACK 1
- #define FLAG_STOP 2
- #define FLAG_TURNLEFT 3
- #define FLAG_TURNRIGHT 4
- #define NO 0
- #define YES 1
- #define DELAYTURN 5000
- #define DELAYDUOJI 5000
- /******************************子函數(shù)聲明區(qū)***********************************************/
- void initial_myself(void);
- void initial_peripheral(void);
- void delay100ms(void);
- /******************************IO口定義區(qū)***********************************************/
- sbit LEFT_XJ = P3^4; // 左循跡
- sbit RIGHT_XJ = P3^5; // 右循跡
- sbit LEFT_GS = P3^6; // 左跟隨
- sbit RIGHT_GS = P3^7; // 右跟隨
- //sbit LEFT_CS = P // 左測(cè)速
- //sbit RIGHT_CS = P // 右測(cè)速
- sbit KEY=P2^6; // 激活超聲波測(cè)距,測(cè)試用,蜂鳴器也響;
- /******************************全局變量定義區(qū)***********************************************/
- unsigned char ucPwm = 4; //電機(jī)的PWM占空比,N/10
-
- unsigned int ucPwmCountDianJ = 0; //電機(jī)Pwm計(jì)數(shù)
- unsigned int ucPwmCountDuoJ = 0; //舵機(jī)Pwm計(jì)數(shù)
- unsigned char ucFlagState = FLAG_YAOKONG; //模式選擇,遙控,循跡,避障
- unsigned char ucFlagControl = FLAG_STOP; //遙控模式下的控制選擇,前進(jìn)后退停止左轉(zhuǎn)右轉(zhuǎn)
- unsigned int uc_delay_task_cnt[NUM_TASK_REFRESH]; //任務(wù)刷新延遲
- unsigned char ucCSBCheck = NO; //用于判斷是否需要停車檢測(cè)
- unsigned int ucPwmDuoj = 6; //舵機(jī)歸中,默認(rèn)情況下先歸中
- unsigned int ulS[4] = {0,0,0,0}; //儲(chǔ)存距離數(shù)據(jù),0°,180°,90°,后退時(shí)90°
- unsigned char ucDuoJiPosition[3]={11,2,6}; //舵機(jī)的0°,180°,90°對(duì)應(yīng)的ucPwmDuoj數(shù)值
- unsigned char ucFlagTurning=NO; //在超聲波避障模式中,判斷是否正在轉(zhuǎn)彎
- unsigned char ucFlagDuoJiPositon=0; //正在檢測(cè)的舵機(jī)位置標(biāo)示,0代表正在檢測(cè)0°
- unsigned char ucLockCSBCheck=NO; //超聲波檢測(cè)過程中時(shí),此為YES,鎖住紅外傳感器的檢測(cè)
- unsigned int uiDelayDuoJiMove=DELAYDUOJI; //舵機(jī)移動(dòng)延遲結(jié)束
- unsigned char ucFlagDuoJiMove=NO; //舵機(jī)開始移動(dòng)的標(biāo)志,此標(biāo)志為YES時(shí)uiDelayDuoJiMove開始減
- unsigned char ucFlagCSBBegin=NO; //超聲波開始檢測(cè)標(biāo)志,當(dāng)uiDelayDuoJiMove為0時(shí),為YES
- unsigned char ucNumS=0; //ulS數(shù)組的第幾位
- unsigned char ucNumCSB=0; //進(jìn)入超聲波檢測(cè)的次數(shù),用來控制什么時(shí)候結(jié)束檢測(cè),開始轉(zhuǎn)彎
- unsigned int uiDelayTurn=DELAYTURN; //轉(zhuǎn)彎結(jié)束,大概90°
- unsigned char ucFlagTurn=NO; //開始轉(zhuǎn)動(dòng)的標(biāo)志,此標(biāo)志為YES時(shí)uiDelayTurn開始減
- unsigned char ucFlagTurnOver=NO; //轉(zhuǎn)彎結(jié)束標(biāo)志,為YES時(shí),退出轉(zhuǎn)彎
- unsigned char ucFlagSMGLock=NO; //數(shù)碼管鎖,從檢測(cè)到障礙,到轉(zhuǎn)彎結(jié)束,這段時(shí)間鎖上不顯示
- unsigned char ucFlagGuiZhong=NO; //頭一次進(jìn)入避障模式先歸中
- unsigned char ucFlagBegin=NO; //歸中后此位為YES
- unsigned char ucFlagChangeState=NO; //改變狀態(tài)標(biāo)識(shí),如果改變了,那么初始化避障模式的變量
- unsigned char ucFlagBackOK=NO; //后退OK標(biāo)識(shí),后退結(jié)束后,才開始轉(zhuǎn)彎
- //unsigned char ucCSBDirection = 0; //用來記錄并判斷檢測(cè)后行進(jìn)方向
- //unsigned char ucCSBFlag = 0; //用來激活400ms計(jì)時(shí)
- //unsigned char ucFlagJumpoutPwm = 0; //Pwm跳出標(biāo)示,1為跳出
- //unsigned char const discode[] ={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0xff/*-*/};
- //unsigned char const positon[3]={ 0xfe,0xfd,0xfb};
- /******************************主函數(shù)開始***********************************************/
- void main(void)
- {
- initial_myself();
- delay100ms();
- initial_peripheral();
- while(1)
- {
- if(ucFlagChangeState==YES) //每次改變狀態(tài),將避障模式的變量初始化
- {
- ucFlagTurning=NO; //在超聲波避障模式中,判斷是否正在轉(zhuǎn)彎
- ucFlagDuoJiPositon=0; //正在檢測(cè)的舵機(jī)位置標(biāo)示,0代表正在檢測(cè)0°
- ucLockCSBCheck=NO; //超聲波檢測(cè)過程中時(shí),此為YES,鎖住紅外傳感器的檢測(cè)
- uiDelayDuoJiMove=DELAYDUOJI; //舵機(jī)移動(dòng)延遲結(jié)束
- ucFlagDuoJiMove=NO; //舵機(jī)開始移動(dòng)的標(biāo)志,此標(biāo)志為YES時(shí)uiDelayDuoJiMove開始減
- ucFlagCSBBegin=NO; //超聲波開始檢測(cè)標(biāo)志,當(dāng)uiDelayDuoJiMove為0時(shí),為YES
- ucNumS=0; //ulS數(shù)組的第幾位
- ucNumCSB=0; //進(jìn)入超聲波檢測(cè)的次數(shù),用來控制什么時(shí)候結(jié)束檢測(cè),開始轉(zhuǎn)彎
- uiDelayTurn=DELAYTURN; //轉(zhuǎn)彎結(jié)束,大概90°
- ucFlagTurn=NO; //開始轉(zhuǎn)動(dòng)的標(biāo)志,此標(biāo)志為YES時(shí)uiDelayTurn開始減
- ucFlagTurnOver=NO; //轉(zhuǎn)彎結(jié)束標(biāo)志,為YES時(shí),退出轉(zhuǎn)彎
- ucFlagSMGLock=NO; //數(shù)碼管鎖,從檢測(cè)到障礙,到轉(zhuǎn)彎結(jié)束,這段時(shí)間鎖上不顯示
- ucFlagGuiZhong=NO; //頭一次進(jìn)入避障模式先歸中
- ucFlagBegin=NO; //歸中后此位為YES
- ucFlagBackOK=NO; //后退OK標(biāo)識(shí),后退結(jié)束后,才開始轉(zhuǎn)彎
- ucPwm=4;
- ucFlagChangeState=NO;
- }
- if(uc_delay_task_cnt[0]==0)
- {
- YaoKong();
- ET0=0;//在中斷中也有可能變化的變量在更改前時(shí)先關(guān)閉中斷
- uc_delay_task_cnt[0]=TIME_YAOKONG_50HZ;
- ET0=1;
- }
- //遙控模式
- if(ucFlagState==FLAG_YAOKONG)
- {
- switch(ucFlagControl)
- {
- case FLAG_GO:
- Go();
- break;
- case FLAG_STOP:
- Stop();
- break;
- case FLAG_BACK:
- Back();
- break;
- case FLAG_TURNLEFT:
- TurnLeft();
- break;
- case FLAG_TURNRIGHT:
- TurnRight();
- break;
- default:
- break;
- }
- }
- //循跡模式
- if(ucFlagState==FLAG_XUNJI)
- {
- if(LEFT_XJ==1&&RIGHT_XJ==1)
- {
- ucPwm=3;
- Go();
- }
- else if(RIGHT_XJ==0)
- {
- ucPwm=8;
- TurnRight();
- }
- else if(LEFT_XJ==0)
- {
- ucPwm=8;
- TurnLeft();
- }
-
- }
- //跟隨模式
- if(ucFlagState==FLAG_GENSUI)
- {
- if(LEFT_GS==1&&RIGHT_GS==1) //左右都檢測(cè)到物體
- {
- Stop();
- }
- else if(LEFT_GS==0&&RIGHT_GS==1) //左側(cè)未檢測(cè)到,右側(cè)檢測(cè)到
- {
- TurnRight();
- }
- else if(LEFT_GS==1&&RIGHT_GS==0) //右側(cè)未檢測(cè)到,左側(cè)檢測(cè)到
- {
- TurnLeft();
- }
- else //左右都未檢測(cè)到
- {
- Go();
- }
- }
- //超聲波+紅外避障模式
- //ucFlagBegin=NO,
- if(ucFlagState==FLAG_BIZHANG)
- {
- if(ucFlagBegin==NO)
- {
- ucPwmDuoj=ucDuoJiPosition[2];
- ucFlagGuiZhong=YES;
- }
- else
- {
- // if(ucFlagSMGLock==NO&&uc_delay_task_cnt[1]==0) //數(shù)碼管刷新
- if(uc_delay_task_cnt[1]==0) //數(shù)碼管刷新
- {
- Display();
- ET0=0;//在中斷中也有可能變化的變量在更改前時(shí)先關(guān)閉中斷
- uc_delay_task_cnt[1]=TIME_SUMA_300HZ;
- ET0=1;
- }
-
- if(ucFlagTurning==NO) //沒在轉(zhuǎn)彎
- {
- if(ucLockCSBCheck==NO&&uc_delay_task_cnt[2]==0) //超聲波自動(dòng)檢測(cè)
- {
- CSB ();
- ET0=0;//在中斷中也有可能變化的變量在更改前時(shí)先關(guān)閉中斷
- uc_delay_task_cnt[2]=TIME_CSB_5HZ;
- ET0=1;
- if(S<=40)
- {
- ucLockCSBCheck=YES;
- ucFlagSMGLock=YES;
- Stop();
- }
- }
-
- if(ucLockCSBCheck==NO)
- {
- Go();
- }
-
- if(ucLockCSBCheck==YES) //遇到障礙后超聲波檢測(cè)整個(gè)過程開始
- {
- if(ucFlagCSBBegin==NO) //超聲波檢測(cè)未開始
- {
- ucPwmDuoj=ucDuoJiPosition[ucFlagDuoJiPositon]; //正在檢測(cè)的角度,隨著ucFlagDuoJiPositon變化而變化
- ucFlagDuoJiMove=YES;
- }
- if(ucFlagCSBBegin==YES)
- {
- // if(ucFlagDuoJiPositon<2) //只在0°,180°進(jìn)行超聲波檢測(cè)
- // {
- CSB ();
- CSB ();
- CSB ();
- ulS[ucNumS]=S; //將距離數(shù)據(jù)存起來
- // if(ucNumS<2)
- ucNumS++;
- // }
- if(++ucFlagDuoJiPositon>2)
- ucFlagDuoJiPositon=0;
- if(++ucNumCSB>=3)
- {
- ucFlagTurning=YES; //激活轉(zhuǎn)彎
- ucLockCSBCheck=NO;
- ucNumCSB=0; //進(jìn)入檢測(cè)的次數(shù)清0
- ucNumS=0; //存儲(chǔ)距離數(shù)據(jù)的位置清0
- }
- ucFlagCSBBegin=NO; //超聲波檢測(cè)結(jié)束
- }
-
- }
- }
- else //正在轉(zhuǎn)彎
- {
- if(ucFlagBackOK==NO)
- {
- if( ulS[2]<30)
- {
- Back();
- CSB();
- ulS[3]=S;
- if(ulS[3]>=30)
- ucFlagBackOK=YES;
- }
- else
- ucFlagBackOK=YES;
- }
- else
- {
- if(ucFlagTurnOver==NO) //未轉(zhuǎn)彎結(jié)束
- {
- ucFlagTurn=YES;
- if(ulS[0]>ulS[1]) //左側(cè)>右側(cè)
- TurnLeft();
- else
- TurnRight();
- }
- else
- {
- ucFlagTurning=NO;
- ucFlagTurnOver=NO;
- ucFlagSMGLock=NO;
- ucFlagBackOK=NO;
- }
- }
- }
- }
- }
- }
- }
- //中斷函數(shù)
- void timer0(void) interrupt 1
- {
- unsigned char i;
- TR0=0;
- TH0=255-TIME_CLOCK/TIME_PER_SEC/12/256;
- TL0=255-TIME_CLOCK/TIME_PER_SEC/12%256;
- //task_delay[]減到0時(shí),相應(yīng)的函數(shù)準(zhǔn)備就緒
- for(i=0;i<NUM_TASK_REFRESH;i++)
- {
- if(uc_delay_task_cnt[i]!=0)//延遲不為0時(shí)才減
- {uc_delay_task_cnt[i]--;};
- }
- ucPwmCountDianJ++;
- if(ucPwmCountDianJ >= 10)
- {
- ucPwmCountDianJ = 0;
- }
-
- //舵機(jī)轉(zhuǎn)動(dòng)距離控制
- if(ucFlagDuoJiMove==YES||ucFlagGuiZhong==YES)
- {
- ucPwmCountDuoJ++;
- if(ucPwmCountDuoJ>205) //0.5+20(ms),整個(gè)周期長(zhǎng)度
- {
- ucPwmCountDuoJ=0;
- }
- PwmServomoto();
- }
- //舵機(jī)轉(zhuǎn)動(dòng)時(shí)間控制
- if(ucFlagDuoJiMove==YES)
- {
- if(uiDelayDuoJiMove!=0)
- uiDelayDuoJiMove--;
- else
- {
- uiDelayDuoJiMove=DELAYDUOJI;
- ucFlagDuoJiMove=NO;
- ucFlagCSBBegin=YES;
- }
- }
- //頭一次進(jìn)入避障模式的舵機(jī)歸中
- if(ucFlagGuiZhong==YES)
- {
- if(uiDelayDuoJiMove!=0)
- uiDelayDuoJiMove--;
- else
- {
- uiDelayDuoJiMove=DELAYDUOJI;
- ucFlagGuiZhong=NO;
- ucFlagBegin=YES;
- }
- }
- //轉(zhuǎn)彎延遲
- if(ucFlagTurn==YES)
- {
- if(uiDelayTurn!=0)
- uiDelayTurn--;
- else
- {
- uiDelayTurn=DELAYTURN;
- ucFlagTurn=NO;
- ucFlagTurnOver=YES;
- }
- }
- TR0=1;
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
8.6 No.1 超聲波避障基本可以用,還不完善.zip
(90.83 KB, 下載次數(shù): 12)
2017-7-2 22:55 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
|