標(biāo)題:
51單片機(jī)智能車超聲波舵機(jī)避障程序分享
[打印本頁(yè)]
作者:
賊六的噠噠噠
時(shí)間:
2021-4-25 16:40
標(biāo)題:
51單片機(jī)智能車超聲波舵機(jī)避障程序分享
附加程序
#include <reg52.h>//51頭文件
#include <QX_A11.h>//QX_A11智能小車配置文件
#include <intrins.h>
bit Timer1Overflow; //計(jì)數(shù)器1溢出標(biāo)志位
unsigned char disbuff[4]={0,0,0,0};//用于分別存放距離的值米,厘米,毫米
unsigned int LeftDistance = 0, RightDistance = 0, FrontDistance = 0; //云臺(tái)測(cè)距距離緩存
unsigned int DistBuf[5] = {0};//distance data buffer
unsigned char pwm_val_left,pwm_val_right; //中間變量,用戶請(qǐng)勿修改。
unsigned char pwm_left,pwm_right; //定義PWM輸出高電平的時(shí)間的變量。用戶操作PWM的變量。
#define PWM_DUTY 200 //(用于舵機(jī)時(shí)不可修改)定義PWM的周期,數(shù)值為定時(shí)器0溢出周期,假如定時(shí)器溢出時(shí)間為100us,則PWM周期為20ms。
#define PWM_HIGH_MIN 70 //限制PWM輸出的最小占空比。用戶請(qǐng)勿修改。
#define PWM_HIGH_MAX PWM_DUTY //限制PWM輸出的最大占空比。用戶請(qǐng)勿修改。
void Timer0_Init(void); //定時(shí)器0初始化
void Timer1_Init(void);//定時(shí)器1初始化
void LoadPWM(void);//裝入PWM輸出值
void Delay_Ms(unsigned int ms);//毫秒級(jí)延時(shí)函數(shù)
void forward(unsigned char LeftSpeed,unsigned char RightSpeed);//QX_A11智能小車前進(jìn)
void left_run(unsigned char LeftSpeed,unsigned char RightSpeed);//QX_A11智能小車左轉(zhuǎn)
void right_run(unsigned char LeftSpeed,unsigned char RightSpeed);//QX_A11智能小車右轉(zhuǎn)
//void back_run(unsigned char LeftSpeed,unsigned char RightSpeed);//QX_A11智能小車后退
void stop(void);//QX_A11智能小車停車
void Delay18450us(void); //@11.0592MHz
void Delay1550us(void); //@11.0592MHz
void Delay19400us(void); //@11.0592MHz
void Delay600us(void); //@11.0592MHz
void Delay17500us(void); //@11.0592MHz
void Delay2500us(void); //@11.0592MHz
void QXMBOT_bubble(unsigned int *a,unsigned char n);//冒泡排序
void QXMBOT_ServoFront(void);//舵機(jī)向前
void QXMBOT_ServoLeft(void);//舵機(jī)左轉(zhuǎn)
void QXMBOT_ServoRight(void);//舵機(jī)右轉(zhuǎn)
void QXMBOT_PTZ_Avoid(unsigned int val);//舵機(jī)云臺(tái)避障
unsigned int QXMBOT_GetDistance(void);//獲取超聲波距離
void QXMBOT_TrigUltrasonic(void);// 觸發(fā)超聲波
unsigned int QXMBOT_RefreshDistance(void);//超聲波測(cè)距
/*主函數(shù)*/
void main(void)
{
Timer0_Init();//定時(shí)0初始化
Timer1_Init();//定時(shí)0初始化
EA_on; //開(kāi)中斷
QXMBOT_ServoFront();//舵機(jī)向前
Delay_Ms(1000);
forward(120,120);//前進(jìn)
while(1)
{
QXMBOT_PTZ_Avoid(300);//舵機(jī)云臺(tái)避障,LCD1602顯示距離,形參設(shè)置觸發(fā)距離,單位:毫米
}
}
/*********************************************
QX_A11智能小車前進(jìn)
入口參數(shù):LeftSpeed,RightSpeed
出口參數(shù): 無(wú)
說(shuō)明:LeftSpeed,RightSpeed分別設(shè)置左右車輪轉(zhuǎn)速
**********************************************/
void forward(unsigned char LeftSpeed,unsigned char RightSpeed)
{
pwm_left = LeftSpeed,pwm_right = RightSpeed;//設(shè)置速度
left_motor_go; //左電機(jī)前進(jìn)
right_motor_go; //右電機(jī)前進(jìn)
}
/*小車左轉(zhuǎn)*/
/*********************************************
QX_A11智能小車左轉(zhuǎn)
入口參數(shù):LeftSpeed,RightSpeed
出口參數(shù): 無(wú)
說(shuō)明:LeftSpeed,RightSpeed分別設(shè)置左右車輪轉(zhuǎn)速
**********************************************/
void left_run(unsigned char LeftSpeed,unsigned char RightSpeed)
{
pwm_left = LeftSpeed,pwm_right = RightSpeed;//設(shè)置速度
left_motor_back; //左電機(jī)后退
right_motor_go; //右電機(jī)前進(jìn)
}
/*********************************************
QX_A11智能小車右轉(zhuǎn)
入口參數(shù):LeftSpeed,RightSpeed
出口參數(shù): 無(wú)
說(shuō)明:LeftSpeed,RightSpeed分別設(shè)置左右車輪轉(zhuǎn)速
**********************************************/
void right_run(unsigned char LeftSpeed,unsigned char RightSpeed)
{
pwm_left = LeftSpeed,pwm_right = RightSpeed;//設(shè)置速度
right_motor_back;//右電機(jī)后退
left_motor_go; //左電機(jī)前進(jìn)
}
/*********************************************
QX_A11智能小車后退
入口參數(shù):LeftSpeed,RightSpeed
出口參數(shù): 無(wú)
說(shuō)明:LeftSpeed,RightSpeed分別設(shè)置左右車輪轉(zhuǎn)速
**********************************************/
//void back_run(unsigned char LeftSpeed,unsigned char RightSpeed)
//{
// pwm_left = LeftSpeed,pwm_right = RightSpeed;//設(shè)置速度
// right_motor_back;//右電機(jī)后退
// left_motor_back; //左電機(jī)后退
//}
/*********************************************
QX_A11智能小車停車
入口參數(shù):無(wú)
出口參數(shù): 無(wú)
說(shuō)明:QX_A11智能小車停車
**********************************************/
void stop(void)
{
left_motor_stops;
right_motor_stops;
}
/*====================================
函數(shù):void Delay_Ms(INT16U ms)
參數(shù):ms,毫秒延時(shí)形參
描述:12T 51單片機(jī)自適應(yīng)主時(shí)鐘毫秒級(jí)延時(shí)函數(shù)
====================================*/
void Delay_Ms(unsigned int ms)
{
unsigned int i;
do{
i = MAIN_Fosc / 96000;
while(--i); //96T per loop
}while(--ms);
}
/*舵機(jī)方波延時(shí)朝向小車正前方*/
void Delay1550us() //@11.0592MHz
{
unsigned char i, j;
i = 3;
j = 196;
do
{
while (--j);
} while (--i);
}
void Delay18450us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
i = 34;
j = 16;
do
{
while (--j);
} while (--i);
}
/*舵機(jī)方波延時(shí)向小車右方*/
void Delay600us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
i = 2;
j = 15;
do
{
while (--j);
} while (--i);
}
void Delay19400us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
i = 35;
j = 197;
do
{
while (--j);
} while (--i);
}
/*舵機(jī)方波延時(shí)朝向小車左方*/
void Delay17500us() //@11.0592MHz
{
unsigned char i, j;
i = 32;
j = 93;
do
{
while (--j);
} while (--i);
}
void Delay2500us() //@11.0592MHz
{
unsigned char i, j;
i = 5;
j = 120;
do
{
while (--j);
} while (--i);
}
/*********************************************
QX_A11智能小車PWM輸出
入口參數(shù):無(wú)
出口參數(shù): 無(wú)
說(shuō)明:裝載PWM輸出,如果設(shè)置全局變量pwm_left,pwm_right分別配置左右輸出高電平時(shí)間
**********************************************/
void LoadPWM(void)
{
if(pwm_left > PWM_HIGH_MAX) pwm_left = PWM_HIGH_MAX; //如果左輸出寫(xiě)入大于最大占空比數(shù)據(jù),則強(qiáng)制為最大占空比。
if(pwm_left < PWM_HIGH_MIN) pwm_left = PWM_HIGH_MIN; //如果左輸出寫(xiě)入小于最小占空比數(shù)據(jù),則強(qiáng)制為最小占空比。
if(pwm_right > PWM_HIGH_MAX) pwm_right = PWM_HIGH_MAX; //如果右輸出寫(xiě)入大于最大占空比數(shù)據(jù),則強(qiáng)制為最大占空比。
if(pwm_right < PWM_HIGH_MIN) pwm_right = PWM_HIGH_MIN; //如果右輸出寫(xiě)入小于最小占空比數(shù)據(jù),則強(qiáng)制為最小占空比。
if(pwm_val_left<=pwm_left) Left_moto_pwm = 1; //裝載左PWM輸出高電平時(shí)間
else Left_moto_pwm = 0; //裝載左PWM輸出低電平時(shí)間
if(pwm_val_left>=PWM_DUTY) pwm_val_left = 0; //如果左對(duì)比值大于等于最大占空比數(shù)據(jù),則為零
if(pwm_val_right<=pwm_right) Right_moto_pwm = 1; //裝載右PWM輸出高電平時(shí)間
else Right_moto_pwm = 0; //裝載右PWM輸出低電平時(shí)間
if(pwm_val_right>=PWM_DUTY) pwm_val_right = 0; //如果右對(duì)比值大于等于最大占空比數(shù)據(jù),則為零
}
//冒泡排序
void QXMBOT_bubble(unsigned int *a,unsigned char n) /*定義兩個(gè)參數(shù):數(shù)組首地址與數(shù)組大小*/
{
unsigned int i,j,temp;
for(i = 0;i < n-1; i++)
{
for(j = i + 1; j < n; j++) /*注意循環(huán)的上下限*/
{
if(a[i] > a[j])
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
/*====================================
函數(shù)名 :QXMBOT_RefreshDistance
參數(shù) :無(wú)
返回值 :經(jīng)過(guò)冒泡排序后的距離
描述 :經(jīng)過(guò)5次測(cè)距,去除最大值和最小值,取中間3次平均值
距離單位:毫米
====================================*/
unsigned int QXMBOT_RefreshDistance()
{
unsigned char num;
unsigned int Dist;
for(num=0; num<5; num++)
{
DistBuf[num] = QXMBOT_GetDistance();
Delay_Ms(60);//測(cè)距周期不低于60毫秒
}
QXMBOT_bubble(DistBuf, 5);//
Dist = (DistBuf[1]+DistBuf[2]+DistBuf[3])/3; //去掉最大和最小取中間平均值
return(Dist);
}
/*超聲波觸發(fā)*/
void QXMBOT_TrigUltrasonic()
{
TrigPin = 0; //超聲波模塊Trig 控制端
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TrigPin = 1; //超聲波模塊Trig 控制端
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
TrigPin = 0; //超聲波模塊Trig 控制端
}
/*====================================
函數(shù)名 :QXMBOT_GetDistance
參數(shù) :無(wú)
返回值 :獲取距離單位毫米
描述 :超聲波測(cè)距
通過(guò)發(fā)射信號(hào)到收到回響信號(hào)的時(shí)間測(cè)試距離
單片機(jī)晶振11.0592Mhz
注意測(cè)距周期為60ms以上
====================================*/
unsigned int QXMBOT_GetDistance()
{
unsigned int Distance = 0; //超聲波距離
unsigned int Time=0; //用于存放定時(shí)器時(shí)間值
QXMBOT_TrigUltrasonic(); //超聲波觸發(fā)
while(!EchoPin); //判斷回響信號(hào)是否為低電平
Timer1On; //啟動(dòng)定時(shí)器1
while(EchoPin); //等待收到回響信號(hào)
Timer1Off; //關(guān)閉定時(shí)器1
Time=TH1*256+TL1; //讀取時(shí)間
TH1=0;
TL1=0; //清空定時(shí)器
Distance = (float)(Time*1.085)*0.17;//算出來(lái)是MM
return(Distance);//返回距離
}
/*====================================
函數(shù)名 :QXMBOT_PTZ_Avoid
參數(shù) :val設(shè)置避障觸發(fā)距離
返回值 :無(wú)
描述 :智能小車舵機(jī)云臺(tái)避障
距離單位:毫米
====================================*/
void QXMBOT_PTZ_Avoid(unsigned int val)
{
unsigned int Dis;//距離暫存變量
Dis = QXMBOT_GetDistance();//獲取超聲波測(cè)距距離,單位:毫米
if((Dis > 30) && (Dis < val))
{
LED1=0,LED2=0,beep=0;//LED1,2點(diǎn)亮,鳴笛
stop(); //停車
Delay_Ms(100);
LED1=1,LED2=1,beep=1;//LED1,2熄滅,靜音
/*舵機(jī)左轉(zhuǎn)測(cè)距*/
QXMBOT_ServoLeft();
LeftDistance = QXMBOT_RefreshDistance();
/*舵機(jī)右轉(zhuǎn)測(cè)距*/
QXMBOT_ServoRight();
RightDistance = QXMBOT_RefreshDistance();
/*舵機(jī)正前方測(cè)距*/
QXMBOT_ServoFront();
FrontDistance = QXMBOT_RefreshDistance();
if((FrontDistance<100) && (LeftDistance<100) && (RightDistance<100))
{
do{
left_run(160, 160);//原地左轉(zhuǎn)
Delay_Ms(60);
/*舵機(jī)正前方測(cè)距*/
QXMBOT_ServoFront();
Dis = QXMBOT_RefreshDistance();
}while(Dis < 200);
}else if((FrontDistance>LeftDistance) && (FrontDistance>RightDistance))
{
stop(); //停車
Delay_Ms(100);
forward(120, 120);//前進(jìn)
}else if(LeftDistance > RightDistance)
{
LED1=1,LED2=0;//LED1滅,2點(diǎn)亮
stop(); //停車
Delay_Ms(100);
left_run(160, 160);//原地左轉(zhuǎn)
Delay_Ms(60);
LED1=1,LED2=1;//LED1滅,2點(diǎn)滅
}else if(RightDistance > LeftDistance)
{
LED1=0,LED2=1;//LED1亮,2點(diǎn)滅
stop(); //停車
Delay_Ms(100);
right_run(160, 160);//原地右轉(zhuǎn)
Delay_Ms(60);
LED1=1,LED2=1;//LED1滅,2點(diǎn)滅
}
}
else
{
forward(120, 120);//前進(jìn)
Delay_Ms(60);
}
}
/*=================================================
*函數(shù)名稱:QXMBOT_ServoFront
*函數(shù)功能:云臺(tái)向前轉(zhuǎn)動(dòng)
*調(diào)用:
*輸入:
=================================================*/
void QXMBOT_ServoFront()
{
char i;
EA_off; //關(guān)閉中斷否則會(huì)影響舵機(jī)轉(zhuǎn)向
for(i=0;i<10;i++)
{
ServoPin = 1;
Delay1550us();
ServoPin = 0;
Delay18450us();
}
EA_on; //開(kāi)中斷
Delay_Ms(100);
}
/*=================================================
*函數(shù)名稱:QXMBOT_ServoLeft
*函數(shù)功能:云臺(tái)向左轉(zhuǎn)動(dòng)
*調(diào)用:
*輸入:
=================================================*/
void QXMBOT_ServoLeft()
{
char i;
EA_off; //關(guān)閉中斷否則會(huì)影響舵機(jī)轉(zhuǎn)向
for(i=0;i<10;i++)
{
ServoPin = 1;
Delay2500us();
ServoPin = 0;
Delay17500us();
}
EA_on; //開(kāi)中斷
Delay_Ms(100);
}
/*=================================================
*函數(shù)名稱:QXMBOT_ServoFront
*函數(shù)功能:云臺(tái)向右轉(zhuǎn)動(dòng)
*調(diào)用:
*輸入:
=================================================*/
void QXMBOT_ServoRight()
{
char i;
EA_off; //關(guān)閉中斷否則會(huì)影響舵機(jī)轉(zhuǎn)向
for(i=0;i<10;i++)
{
ServoPin = 1;
Delay600us();
ServoPin = 0;
Delay19400us();
}
EA_on; //開(kāi)中斷
Delay_Ms(100);
}
/********************* Timer0初始化************************/
void Timer0_Init(void)
{
TMOD |= 0x02;//定時(shí)器0,8位自動(dòng)重裝模塊
TH0 = 164;
TL0 = 164;//11.0592M晶振,12T溢出時(shí)間約等于100微秒
TR0 = 1;//啟動(dòng)定時(shí)器0
ET0 = 1;//允許定時(shí)器0中斷
}
/*定時(shí)器1初始化*/
void Timer1_Init(void)
{
TMOD |= 0x10; //定時(shí)器1工作模式1,16位定時(shí)模式。T1用測(cè)ECH0脈沖長(zhǎng)度
TH1 = 0;
TL1 = 0;
ET1 = 1; //允許T1中斷
}
/********************* Timer0中斷函數(shù)************************/
void timer0_int (void) interrupt 1
{
pwm_val_left++;
pwm_val_right++;
LoadPWM();//裝載PWM輸出
}
/* Timer0 interrupt routine */
void tm1_isr() interrupt 3 using 1
{
Timer1Overflow = 1; //計(jì)數(shù)器1溢出標(biāo)志位
EchoPin = 0; //超聲波接收端
}
復(fù)制代碼
代碼下載:
智能小車I套餐舵機(jī)云臺(tái)避障資料.7z
(17.3 MB, 下載次數(shù): 107)
2021-4-25 17:36 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者:
dj3365191
時(shí)間:
2021-5-5 18:26
你好樓主,附件里除了程序以外有原理圖嗎
作者:
賊六的噠噠噠
時(shí)間:
2021-5-6 20:11
dj3365191 發(fā)表于 2021-5-5 18:26
你好樓主,附件里除了程序以外有原理圖嗎
有一部分
作者:
15038217543
時(shí)間:
2021-6-21 11:42
這個(gè)有流程圖不?
作者:
zk
時(shí)間:
2021-6-22 22:26
擦墻現(xiàn)象有嗎,有解決方案嗎。
作者:
51_chuan
時(shí)間:
2022-5-6 09:48
你好,請(qǐng)問(wèn)可以提供一下 <QX_A11.h>//QX_A11智能小車配置文件 這個(gè)文件的代碼嗎? 新手幣不夠,下載不了
作者:
亂世狂魔
時(shí)間:
2022-5-7 23:08
這個(gè)是需要用KeilMDK編輯嗎大佬?
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1