看了好多智能小車,都是兩輪或者4輪麥克輪轉向的,一直想模仿阿克曼智能ROS 機器人,利用舵機來轉向的智能小車。經過多天學習c++語言和51芯片資料,通過改寫程序,買了舵機轉向前輪配件,用4wd小車改裝的舵機轉向智能小車,實現A舵機避障+B舵機轉向功能,經過多次場地測試,前進速度盡量降低一點能實現完美避障。比以前4個tt電機驅動轉向功耗小很多,玩耍時間更長。 。 最后附有程序和圖文組裝說明壓縮包。 4輪小車雙舵機避障零件清單 1、51主板1個+51單片機芯片 2、SG90舵機1個+塑料云臺空殼1個 3、HC-SR04超聲波測距1個 4、TT電機2個 5、L298N驅動1個 6、小車前輪舵機轉向組1套 7、小車后輪2個 8、理電池7.4v一個。(5號電池不耐用,費錢) 9、鋁合金或亞克力板底盤1個 10、螺絲、導線若干。 實物圖片如下:
111.jpg (85.05 KB, 下載次數: 59)
下載附件
2023-9-8 00:23 上傳
333.jpg (24.42 KB, 下載次數: 54)
下載附件
2023-9-8 00:23 上傳
6.jpg (63.06 KB, 下載次數: 60)
下載附件
2023-9-8 00:23 上傳
11.png (218.86 KB, 下載次數: 61)
下載附件
2023-9-8 00:23 上傳
單片機程序如下: - /*********************************************************************************
- * 【版 本】: 1.1
- * 【實驗平臺】: QX-A11智能小車 STC89C52
- * 【外部晶振】: 11.0592mhz
- * 【主控芯片】: STC89C52
- * 【編譯環境】: Keil μVisio4
- * Copyright(C) QXMBOT
- * All rights reserved
- ***********************************************************************************
- * 【程序功能】:QX-A11舵機云臺避障參考程序
- * 【注意事項】:避免小車輪子堵轉
- **********************************************************************************/
- #include <reg52.h>//51頭文件
- #include <QX_A11.h>//QX_A11智能小車配置文件
- #include <intrins.h>
- bit Timer1Overflow; //計數器1溢出標志位
- unsigned char disbuff[4]={0,0,0,0};//用于分別存放距離的值米,厘米,毫米
- unsigned int LeftDistance = 0, RightDistance = 0, FrontDistance = 0; //云臺測距距離緩存
- unsigned int DistBuf[5] = {0};//distance data buffer
- unsigned char pwm_val_left,pwm_val_right; //中間變量,用戶請勿修改。
- unsigned char pwm_left,pwm_right; //定義PWM輸出高電平的時間的變量。用戶操作PWM的變量(括號內輸入數值)。
- #define PWM_DUTY 200 //(用于舵機時不可修改)定義PWM的周期,數值為定時器0溢出周期,假如定時器溢出時間為100us,則PWM周期為20ms。
- #define PWM_HIGH_MIN 70 //限制PWM輸出的最小占空比。用戶請勿修改。
- #define PWM_HIGH_MAX PWM_DUTY //限制PWM輸出的最大占空比。用戶請勿修改。
- void Timer0_Init(void); //定時器0初始化
- void Timer1_Init(void);//定時器1初始化
- void LoadPWM(void);//裝入PWM輸出值
- void Delay_Ms(unsigned int ms);//毫秒級延時函數
- void forward(unsigned char LeftSpeed,unsigned char RightSpeed);//QX_A11智能小車前進
- void left_run(unsigned char LeftSpeed,unsigned char RightSpeed);//QX_A11智能小車左轉
- void right_run(unsigned char LeftSpeed,unsigned char RightSpeed);//QX_A11智能小車右轉
- 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);//舵機向前
- void QXMBOT_ServoLeft(void);//舵機左轉
- void QXMBOT_ServoRight(void);//舵機右轉
- void Servo1front(void);//舵機B向前
- void Servo1left(void);//舵機B左轉
- void Servo1right(void);//舵機B右轉
- void QXMBOT_PTZ_Avoid(unsigned int val);//舵機云臺避障
- unsigned int QXMBOT_GetDistance(void);//獲取超聲波距離
- void QXMBOT_TrigUltrasonic(void);// 觸發超聲波
- unsigned int QXMBOT_RefreshDistance(void);//超聲波測距
- /*主函數*/
- void main(void)
- {
- Timer0_Init();//定時0初始化
- Timer1_Init();//定時0初始化
- EA_on; //開中斷
- QXMBOT_ServoFront();//舵機向前
- Servo1front(); //B舵機向前
- Delay_Ms(1000);
- forward(20,20);//前進5v速度,7.4v情況下forward全部調成(80,80)可調速。
- while(1)
- {
- QXMBOT_PTZ_Avoid(500);//舵機云臺避障,LCD1602顯示距離,設置觸發距離300毫米
- }
- }
- /*********************************************
- 小車前進
- 入口參數:LeftSpeed,RightSpeed
- 說明:LeftSpeed,RightSpeed分別設置左右車輪轉速
- **********************************************/
- void forward(unsigned char LeftSpeed,unsigned char RightSpeed)//不能放1號舵機參數Servo1front(),動力抖顫.
- {
- pwm_left = LeftSpeed,pwm_right = RightSpeed;//設置速度
- left_motor_go; //左電機前進
- right_motor_go; //右電機前進
- }
- /*********************************************
- 小車左轉,入口參數:LeftSpeed,RightSpeed
- 說明:LeftSpeed,RightSpeed分別設置左右車輪轉速
- **********************************************/
- void left_run(unsigned char LeftSpeed,unsigned char RightSpeed)
- {
- pwm_left = LeftSpeed,pwm_right = RightSpeed;//設置速度
- left_motor_go; //左電機后退
- right_motor_go; //右電機前進
- }
- /*********************************************
- 小車右轉,入口參數:LeftSpeed,RightSpeed
- 說明:LeftSpeed,RightSpeed分別設置左右車輪轉速
- **********************************************/
- void right_run(unsigned char LeftSpeed,unsigned char RightSpeed)
- {
- pwm_left = LeftSpeed,pwm_right = RightSpeed;//設置速度
- right_motor_go;//右電機后退
- left_motor_go; //左電機前進
- }
- /*********************************************
- 小車后退
- 入口參數:LeftSpeed,RightSpeed
- 說明:LeftSpeed,RightSpeed分別設置左右車輪轉速
- **********************************************/
- void back_run(unsigned char LeftSpeed,unsigned char RightSpeed)
- {
- pwm_left = LeftSpeed,pwm_right = RightSpeed;//設置速度
- right_motor_back;//右電機后退
- left_motor_back; //左電機后退
- }
- /*********************************************
- 小車停車
- 入口參數:無
- 說明:小車停車
- **********************************************/
- void stop(void)
- {
- left_motor_stops;
- right_motor_stops;
- }
- /*====================================
- 函數:void Delay_Ms(INT16U ms)
- 參數:ms,毫秒延時形參
- 描述:12T 51單片機自適應主時鐘毫秒級延時函數
- ====================================*/
- void Delay_Ms(unsigned int ms)
- {
- unsigned int i;
- do{
- i = MAIN_Fosc / 96000;
- while(--i); //96T per loop
- }while(--ms);
- }
- /*舵機方波延時朝向小車正前方*/
- 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);
- }
- /*舵機方波延時向小車右方*/
- 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);
- }
- /*舵機方波延時朝向小車左方*/
- 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輸出
- 入口參數:無
- 出口參數: 無
- 說明:裝載PWM輸出,如果設置全局變量pwm_left,pwm_right分別配置左右輸出高電平時間
- **********************************************/
- void LoadPWM(void)
- {
- if(pwm_left > PWM_HIGH_MAX) pwm_left = PWM_HIGH_MAX; //如果左輸出寫入大于最大占空比數據,則強制為最大占空比。
- if(pwm_left < PWM_HIGH_MIN) pwm_left = PWM_HIGH_MIN; //如果左輸出寫入小于最小占空比數據,則強制為最小占空比。
- if(pwm_right > PWM_HIGH_MAX) pwm_right = PWM_HIGH_MAX; //如果右輸出寫入大于最大占空比數據,則強制為最大占空比。
- if(pwm_right < PWM_HIGH_MIN) pwm_right = PWM_HIGH_MIN; //如果右輸出寫入小于最小占空比數據,則強制為最小占空比。
- if(pwm_val_left<=pwm_left) Left_moto_pwm = 1; //裝載左PWM輸出高電平時間
- else Left_moto_pwm = 0; //裝載左PWM輸出低電平時間
- if(pwm_val_left>=PWM_DUTY) pwm_val_left = 0; //如果左對比值大于等于最大占空比數據,則為零
- if(pwm_val_right<=pwm_right) Right_moto_pwm = 1; //裝載右PWM輸出高電平時間
- else Right_moto_pwm = 0; //裝載右PWM輸出低電平時間
- if(pwm_val_right>=PWM_DUTY) pwm_val_right = 0; //如果右對比值大于等于最大占空比數據,則為零
- }
- //冒泡排序
- void QXMBOT_bubble(unsigned int *a,unsigned char n) /*定義兩個參數:數組首地址與數組大小*/
- {
- unsigned int i,j,temp;
- for(i = 0;i < n-1; i++)
- {
- for(j = i + 1; j < n; j++) /*注意循環的上下限*/
- {
- if(a[i] > a[j])
- {
- temp = a[i];
- a[i] = a[j];
- a[j] = temp;
- }
- }
- }
- }
- /*====================================
- 函數名 :QXMBOT_RefreshDistance距離單位:毫米
- 參數 :無
- 返回值 :經過冒泡排序后的距離
- 描述 :經過5次測距,去除最大值和最小值,取中間3次平均值
- ====================================*/
- unsigned int QXMBOT_RefreshDistance()
- {
- unsigned char num;
- unsigned int Dist;
- for(num=0; num<5; num++)
- {
- DistBuf[num] = QXMBOT_GetDistance();
- Delay_Ms(60);//測距周期不低于60毫秒
- }
- QXMBOT_bubble(DistBuf, 5);//
- Dist = (DistBuf[1]+DistBuf[2]+DistBuf[3])/3; //去掉最大和最小取中間平均值
- return(Dist);
- }
- /*超聲波觸發*/
- 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 控制端
- }
- /*====================================
- 函數名 :QXMBOT_GetDistance
- 參數 :無
- 返回值 :獲取距離單位毫米
- 描述 :超聲波測距
- 通過發射信號到收到回響信號的時間測試距離
- 單片機晶振11.0592Mhz
- 注意測距周期為60ms以上
- ====================================*/
- unsigned int QXMBOT_GetDistance()
- {
- unsigned int Distance = 0; //超聲波距離
- unsigned int Time=0; //用于存放定時器時間值
- QXMBOT_TrigUltrasonic(); //超聲波觸發
- while(!EchoPin); //判斷回響信號是否為低電平
- Timer1On; //啟動定時器1
- while(EchoPin); //等待收到回響信號
- Timer1Off; //關閉定時器1
- Time=TH1*256+TL1; //讀取時間
- TH1=0;
- TL1=0; //清空定時器
- Distance = (float)(Time*1.085)*0.17;//算出來是MM(一般超聲測距公式、12mHZ的芯片是=Time*0.17)如果用0.017/算出來是cM,那么后面數據對應要改
- return(Distance);//返回距離
- }
- /*====================================
- 函數名 :QXMBOT_PTZ_Avoid
- 參數 :val設置避障觸發距離
- 返回值 :無
- 描述 :智能小車舵機云臺避障
- 距離單位:毫米
- ====================================*/
- void QXMBOT_PTZ_Avoid(unsigned int val)
- {
- unsigned int Dis;//距離暫存變量
- Dis = QXMBOT_GetDistance();//獲取超聲波測距距離,單位:毫米
- if((Dis > 50) && (Dis < val))// 設置避障觸發距離30~val=300
- {
- LED1=0,LED2=0,beep=0;//LED1,2點亮,鳴笛
- stop(); //停車
- Delay_Ms(100);
- LED1=1,LED2=1,beep=1;//LED1,2熄滅,靜音
- /*舵機左轉測距*/
- QXMBOT_ServoLeft();
- LeftDistance = QXMBOT_RefreshDistance();
- /*舵機右轉測距*/
- QXMBOT_ServoRight();
- RightDistance = QXMBOT_RefreshDistance();
- /*舵機正前方測距*/
- QXMBOT_ServoFront();
- FrontDistance = QXMBOT_RefreshDistance();
- if((FrontDistance<150) && (LeftDistance<150) && (RightDistance<150))
- {
- do{
- Servo1right();
- Delay_Ms(60);
- left_run(20, 100);//原地左轉,電機動力值(0~200)超出200則為高電平全速運行
- Delay_Ms(200);//電機轉動時間
- Servo1front();
- /*舵機正前方測距*/
- QXMBOT_ServoFront();
- Dis = QXMBOT_RefreshDistance();
- }while(Dis < 200);//循環、距離
- }else if(FrontDistance<100)
- {
- stop(); //停車
- back_run(60, 60);//后退,電機動力值
- Delay_Ms(150);
- }else if((FrontDistance>LeftDistance) && (FrontDistance>RightDistance))
- {
- stop(); //停車
- Delay_Ms(100);
- forward(20, 20);//前進,電機動力值
- }else if(LeftDistance > RightDistance)
- {
- LED1=1,LED2=0;//LED1滅,2點亮
- stop(); //停車
- Servo1right();
- Delay_Ms(60);
- left_run(20, 100);//原地左轉,電機動力值
- Delay_Ms(200);//電機轉動時間
- Servo1front();
- LED1=1,LED2=1;//LED1滅,2點滅
- }else if(RightDistance > LeftDistance)
- {
- LED1=0,LED2=1;//LED1亮,2點滅
- stop(); //停車
- Servo1left();
- Delay_Ms(60);
- right_run(100, 20);//原地右轉,電機動力值
- Delay_Ms(200);//電機轉動時間,
- LED1=1,LED2=1;//LED1滅,2滅
- Delay_Ms(60);
- Servo1front();
- }
- }
- else
- {
- forward(20, 20);//前進(不能放1號舵機參數Servo1front()動力抖顫)
- Delay_Ms(60);
- }
- }
- /*=================================================
- *函數名稱:QXMBOT_ServoFront
- *函數功能:云臺向前轉動
- *調用:
- *輸入:
- =================================================*/
- void QXMBOT_ServoFront()
- {
- char i;
- EA_off; //關閉中斷否則會影響舵機轉向
- for(i=0;i<10;i++)
- {
- ServoPin = 1;
- Delay1550us();
- ServoPin = 0;
- Delay18450us();
- }
- EA_on; //開中斷
- Delay_Ms(100);
- }
- /*=================================================
- *函數名稱:QXMBOT_ServoLeft
- *函數功能:云臺向左轉動
- =================================================*/
- void QXMBOT_ServoLeft()
- {
- char i;
- EA_off; //關閉中斷否則會影響舵機轉向
- for(i=0;i<10;i++)
- {
- ServoPin = 1;
- Delay2500us();
- ServoPin = 0;
- Delay17500us();
- }
- EA_on; //開中斷
- Delay_Ms(100);
- }
- /*=================================================
- *函數名稱:QXMBOT_ServoFront
- *函數功能:云臺向右轉動
- =================================================*/
- void QXMBOT_ServoRight()
- {
- char i;
- EA_off; //關閉中斷否則會影響舵機轉向
- for(i=0;i<10;i++)
- {
- ServoPin = 1;
- Delay600us();
- ServoPin = 0;
- Delay19400us();
- }
- EA_on; //開中斷
- Delay_Ms(100);
- }
- /*=================================================
- *函數名稱:QXMBOT_ServoFront
- *函數功能:云臺B轉動前(90°)
- =================================================*/
- void Servo1front()//舵機B向前
- {
- char i;
- EA_off; //關閉中斷否則會影響舵機轉向
- for(i=0;i<10;i++)
- {
- Servo1Pin = 1;
- Delay1550us();
- Servo1Pin = 0;
- Delay18450us();
- }
- EA_on; //開中斷
- Delay_Ms(60);
- }
- /*=================================================
- *函數名稱:QXMBOT_ServoFront
- *函數功能:云臺B向左轉動
- =================================================*/
- void Servo1left()//舵機B左轉45度
- {
- char i;
- EA_off; //關閉中斷否則會影響舵機轉向
- for(i=0;i<10;i++)
- {
- Servo1Pin = 1;
- Delay_Ms(2);
- Servo1Pin = 0;
- Delay_Ms(18);
- }
- EA_on; //開中斷
- Delay_Ms(60);
- }
- /*=================================================
- *函數名稱:QXMBOT_ServoFront
- *函數功能:云臺B向右轉動
- =================================================*/
- void Servo1right()//舵機B右轉45度
- {
- char i;
- EA_off; //關閉中斷否則會影響舵機轉向
- for(i=0;i<10;i++)
- {
- Servo1Pin = 1;
- Delay_Ms(1);
- Servo1Pin = 0;
- Delay_Ms(19);
- }
- EA_on; //開中斷
- Delay_Ms(60);
- }
- /********************* Timer0初始化************************/
- void Timer0_Init(void)
- {
- TMOD |= 0x02;//定時器0,8位自動重裝模塊
- TH0 = 164;
- TL0 = 164;//11.0592M晶振,12T溢出時間約等于100微秒
- TR0 = 1;//啟動定時器0
- ET0 = 1;//允許定時器0中斷
- }
- /*定時器1初始化*/
- void Timer1_Init(void)
- {
- TMOD |= 0x10; //定時器1工作模式1,16位定時模式。T1用測ECH0脈沖長度
- TH1 = 0;
- TL1 = 0;
- ET1 = 1; //允許T1中斷
- }
-
- /********************* Timer0中斷函數************************/
- 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; //計數器1溢出標志位
- EchoPin = 0; //超聲波接收端
- }
復制代碼
圖文附件請下載:
4輪小車雙舵機避障程序 配件清單.zip
(1.28 MB, 下載次數: 22)
2023-9-8 00:27 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|