视频地址:
https://pan.baidu.com/s/11iu7wd4hWIhEDV5gP1jhZQ?pwd=5j8u 提取码:5j8u
一、系统介绍
如图 1所示,本实验以 STC89C52RC单片机为核心,通过单片机 I/O口与红外寻迹模块、超声波避障模块、电机驱动模块相连,RXD、TXD与蓝牙通信模块相连,利用电池盒对整体系统提供电力。根据蓝牙通信发送端发送相关命令与传感器模块反馈数据,通过程序控制系统,实现电机的正传反转以达成避障与寻迹相关功能。
二、系统组装
三、部件介绍
红外光电传感器
使用集成红外光电传感器寻迹模块,其包含一对红外线发射与接收管,其发射管发射出一定频率的红外线,当检测方向下方为黑线时,红外线反射回来被接收管接收,经过比较器电路处理之后,绿灯亮起并输出信号到单片机。
超声波传感器
使用集成超声波传感器避障模块 HC-SRF05,其包含超声波发射器、接收器、与控制电路,可提供 2cm-450cm的非接触式感测功能,测距精度可达到 3mm。通过单片机向模块发射一段至少 10us的高电平信号,模块自动发射 8个 40kHz的方波检测是否有信号返回以执行测距功能,当有信号返回时将输出信号到单片机。
电机驱动模块
电机驱动模块采用 2片 L298N芯片提供四路电机控制,通过单片机 I/O口与芯片控制针脚连接以实现小车四驱驱动,并提供 5V电压输出模块。采用 PWM脉宽调制方法来实现对智能小车转速的调整。由于 MCU STC89C52RC并不能产生 PWM波形,需要通过定时器中断来产生 PWM方波。
蓝牙通信模块
蓝牙通信模块采用 HC-05主从一体无线蓝牙模块,该模块采用 CSR BC417芯片工作于 2.4GHzISM频段,GFSK调制方式。本实验中设置模块为从机模式,手机端作为主机实现蓝牙通信进行控制小车。
供电系统
供电系统采用 12V锂电池组,提供稳定的 12V电压输出到四路电机驱动模块,通过降压芯片向 MCU提供 5V电源实现整车电源提供,并可充电重复利用。
四、寻迹程序设计思路
五、避障程序设计思路
六、源码
寻迹源码
main.c
#include "car.h"
#include "xunji.h"
void main ()
{
Timer0_Init();
car_go ();
while (1)
{
xunji ();
}
}
xunji.c
#include <REGX52.H>
#include "car.h"
#include <intrins.h>
sbit D1 = P2^7;
sbit D2 = P2^6;
//sbit D3 = P2^5;
//sbit D4 = P2^4;
void Delay50ms() //@11.0592MHz
{
unsigned char i, j;
i = 90;
j = 163;
do
{
while (--j);
} while (--i);
}
void Delay100ms() //@11.0592MHz
{
unsigned char i, j;
i = 180;
j = 73;
do
{
while (--j);
} while (--i);
}
void Delay400ms() //@11.0592MHz £¨ÑÓʱ400ms£©
{
unsigned char i, j, k;
_nop_();
i = 3;
j = 206;
k = 43;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void xunji ()
{
if(D1 == 0 && D2 == 0) //2¸ö̽ͷ¾ùδѹÏߣ¬Ö±ÐÐ
{
car_go ();//Ö±ÐÐ
}
if(D1 == 1 && D2 == 0) //×ó̽ͷѹÏߣ¬³µ×ÓÓÒÇ㣬×óת
{
car_stop();
Delay100ms();
Delay100ms();
car_leftgo ();
Delay100ms();
Delay100ms();
if(D1==0&&D2==0)
{car_go ();}
}
if(D1 == 0 && D2 == 1) //ÓÒ̽ͷѹÏߣ¬³µ×Ó×óÇ㣬ÓÒת
{
car_stop();
Delay100ms();
Delay100ms();
car_rightgo ();
Delay100ms();
Delay100ms();
if(D1==0&&D2==0)
{car_go ();}
}
if(D1 == 1 && D2 == 1) //2¸ö̽ͷ¾ùѹÏߣ¬Í£Ö¹
{
car_stop();
}
xunji.h
#ifndef __XUNJI_H_
#define __XUNJI_H_
void xunji ();
#endif
car.c
/************С³µÒƶ¯·½Ïò*************/
/* ÏòÇ°Ö±ÐС¾Ëĵç»úÕýת¡¿ */
/* ÏòºóÖ±ÐС¾Ëĵç»ú·´×ª¡¿ */
/* ÏòÇ°×ó¹Õ¡¾ÓÒµç»úÕýת£¬×óµç»úÍ£Ö¹¡¿*/
/* ÏòÇ°ÓÒ¹Õ¡¾ÓÒµç»úÍ£Ö¹£¬×óµç»úÕýת¡¿*/
/* Ïòºó×ó¹Õ¡¾ÓÒµç»ú·´×ª£¬×óµç»úÍ£Ö¹¡¿*/
/* ÏòºóÓÒ¹Õ¡¾ÓÒµç»úÍ£Ö¹£¬×óµç»ú·´×ª¡¿*/
/* Í£ Ö¹¡¾Ëĵç»úÍ£Ö¹¡¿ */
/************С³µÒƶ¯·½Ïò*************/
#include <REGX52.H>
#include "motor.h"
sbit EN1A = P0^7;//×óÇ°
sbit EN1B = P0^2;//ÓÒÇ°
sbit EN2A = P3^7;//×óºó
sbit EN2B = P3^2;//ÓÒºó
unsigned char counter1,speed; //¼ÆÊýÖµºÍ±È½ÏÖµ£¬ÓÃÓÚÊä³öPWM
void Timer0_Init() //100΢Ãë@11.0592MHz
{
TMOD = 0x11; //ÉèÖö¨Ê±Æ÷ģʽ
TL0 = 0xA4; //ÉèÖö¨Ê±³õʼֵ
TH0 = 0xFF; //ÉèÖö¨Ê±³õʼֵ
TF0 = 0; //Çå³ýTF0±êÖ¾
TR0 = 1; //¶¨Ê±Æ÷0¿ªÊ¼¼Æʱ
ET0 = 1; //¶¨Ê±Æ÷0µÄÖжËÔÊÐí¿ª¹Ø
EA = 1; //¶¨Ê±Æ÷×Ü¿ª¹Ø
PT0 = 1; //ÉèÖö¨Ê±Æ÷Ϊ¸ßµÍ¿ØÖÆÓÅÏȼ¶£¬1Ϊ¸ßÓÅÏȼ¶£¬0ΪµÍÓÅÏȼ¶
}
void Timer0_Routine() interrupt 1 //ÖжϺ¯Êý
{
TL0 = 0xA4; //ÉèÖö¨Ê±³õʼֵ
TH0 = 0xFF; //ÉèÖö¨Ê±³õʼֵ
counter1++;
if (counter1 >= 100)
{
counter1 = 0;
}
if (counter1 < speed)
{
EN1A = 1;
EN1B = 1;
EN2A = 1;
EN2B = 1;
}
else
{
EN1A = 0;
EN1B = 0;
EN2A = 0;
EN2B = 0;
}
}
void car_go () //С³µÏòÇ°Ö±ÐÐ
{
speed = 25;
LF_motor_go ();
RF_motor_go ();
LR_motor_go ();
RR_motor_go ();
}
void car_back () //С³µÏòºóÖ±ÐÐ
{
speed = 25;
LF_motor_back ();
RF_motor_back ();
LR_motor_back ();
RR_motor_back ();
}
void car_stop () //С³µÍ£Ö¹
{
speed = 0;
RR_motor_stop ();
LR_motor_stop ();
RF_motor_stop ();
LF_motor_stop ();
}
void car_leftgo () //С³µÏòÇ°×ó¹Õ
{
speed = 30;
RF_motor_go ();
RR_motor_go ();
LF_motor_stop ();
LR_motor_stop ();
}
void car_rightgo () //С³µÏòÇ°ÓÒ¹Õ
{
speed = 30;
LF_motor_go ();
LR_motor_go ();
RF_motor_stop ();
RR_motor_stop ();
}
void car_reverse() //С³µµôÍ·
{
speed = 60;
LF_motor_go();
LR_motor_go();
RF_motor_back();
RR_motor_back();
}
void car_leftback () //С³µÏòºó×ó¹Õ
{
speed = 15;
RR_motor_back ();
RF_motor_back ();
LF_motor_stop ();
LR_motor_stop ();
}
void car_rightback () //С³µÏòºóÓÒ¹Õ
{
speed = 15;
LF_motor_back ();
LR_motor_back ();
RF_motor_stop ();
RR_motor_stop ();
}
void car_rightstop () //С³µÔµØÓÒ¹Õ
{
speed = 26;
LF_motor_go ();
LR_motor_go ();
RF_motor_back ();
RR_motor_back ();
}
void car_leftstop () //С³µÔµØ×ó¹Õ
{
speed = 26;
LF_motor_back ();
LR_motor_back ();
RF_motor_go ();
RR_motor_go ();
}
car.h
#ifndef __CAR_H_
#define __CAR_H_
void car_go (); //С³µÏòÇ°Ö±ÐÐ
void car_back (); //С³µÏòºóÖ±ÐÐ
void car_stop (); //С³µÍ£Ö¹
void car_leftgo (); //С³µÏòÇ°×ó¹Õ
void car_rightgo (); //С³µÏòÇ°ÓÒ¹Õ
void car_leftback (); //С³µÏòºó×ó¹Õ
void car_rightback (); //С³µÏòºóÓÒ¹Õ
void car_leftstop (); //С³µÔµØ×ó¹Õ
void car_rightstop (); //С³µÔµØÓÒ¹Õ
#endif
motor.c
/**********µç»úµÄÕý·´×ª**********/
/* */
/*LF×óÇ° RFÓÒÇ° LR×óºó RRÓÒºó*/
/* */
/**********µç»úµÄÕý·´×ª**********/
#include <REGX52.H>
//붨Òå
sbit IN11 = P0^5;//×óÇ°
sbit IN12 = P0^6;
sbit IN13 = P0^3;//ÓÒÇ°
sbit IN14 = P0^4;
sbit IN21 = P3^5;//×óºó
sbit IN22 = P3^6;
sbit IN23 = P3^3;//ÓÒºó
sbit IN24 = P3^4;
void LF_motor_go () //×óÇ°µç»úÕýת
{IN11 = 0;IN12 = 1;}
void LF_motor_back () //×óÇ°µç»ú·´×ª
{IN11 = 1;IN12 = 0;}
void LF_motor_stop () //×óÇ°µç»úÍ£Ö¹
{IN11 = 1;IN12 = 1;}
void RF_motor_go () //ÓÒÇ°µç»úÕýת
{IN13 = 0;IN14 = 1;}
void RF_motor_back () //ÓÒÇ°µç»ú·´×ª
{IN13 = 1;IN14 = 0;}
void RF_motor_stop () //ÓÒÇ°µç»úÍ£Ö¹
{IN13 = 1;IN14 = 1;}
void LR_motor_go () //×óºóµç»úÕýת
{IN21 = 1;IN22 = 0;}
void LR_motor_back () //×óºóµç»ú·´×ª
{IN21 = 0;IN22 = 1;}
void LR_motor_stop () //×óºóµç»úÍ£Ö¹
{IN21 = 1;IN22 = 1;}
void RR_motor_go () //ÓÒºóµç»úÕýת
{IN23 = 1;IN24 = 0;}
void RR_motor_back () //ÓÒºóµç»ú·´×ª
{IN23 = 0;IN24 = 1;}
void RR_motor_stop () //ÓÒºóµç»úÍ£Ö¹
{IN23 = 1;IN24 = 1;}
motor.h
#ifndef __MOTOR_H_
#define __MOTOR_H_
void LF_motor_go (); //×óÇ°µç»úÕýת
void LF_motor_back (); //×óÇ°µç»ú·´×ª
void RF_motor_go (); //ÓÒÇ°µç»úÕýת
void RF_motor_back (); //ÓÒÇ°µç»ú·´×ª
void LR_motor_go (); //×óºóµç»úÕýת
void LR_motor_back (); //×óºóµç»ú·´×ª
void RR_motor_go (); //ÓÒºóµç»úÕýת
void RR_motor_back (); //ÓÒºóµç»ú·´×ª
void LF_motor_stop (); //×óÇ°µç»úÍ£Ö¹
void RF_motor_stop (); //ÓÒÇ°µç»úÍ£Ö¹
void LR_motor_stop (); //×óºóµç»úÍ£Ö¹
void RR_motor_stop (); //ÓÒºóµç»úÍ£Ö¹
#endif
超声波避障源码
此处超声波避障源码中motor有关代码相同,car有关代码仅有占空比不同不再赘述,需要工程文件可文末自取。
evadible.c
#include <REGX52.H>
#include "car.h"
#include <intrins.h>
sbit IR_LF = P1^2; //×óÇ°ºìÍâ´«¸ÐÆ÷λµã
sbit IR_RF = P1^1; //ÓÒÇ°ºìÍâ´«¸ÐÆ÷λµã
sbit IR_LR = P1^3; //×óºóºìÍâ´«¸ÐÆ÷λµã
sbit IR_RR = P1^4; //ÓÒºóºìÍâ´«¸ÐÆ÷λµã
sbit Trig = P2^1; //³¬Éù²¨²â¾à·¢Éä¶Ëλµã
sbit Echo = P2^2; //³¬Éù²¨²â¾à½ÓÊÕ¶Ëλµã
sbit PWM = P1^0; //¶æ»úÐźÅÊäÈëλµã
unsigned int sum,distance1,distance2,distance3; //³¬Éù²¨²â¾à½á¹û
unsigned char counter2,angle; //¼ÆÊýÖµºÍÐýת·½Ïò£¬angle·¶Î§£¨1~5£©
unsigned int mindistance = 25; //С³µÓëÕÏ°ÎïµÄÏÞÖƾàÀë
void Delay100ms() //@11.0592MHz
{
unsigned char i, j;
i = 180;
j = 73;
do
{
while (--j);
} while (--i);
}
void Delay400ms() //@11.0592MHz £¨ÑÓʱ400ms£©
{
unsigned char i, j, k;
_nop_();
i = 3;
j = 206;
k = 43;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Timer1_Init() //500΢Ãë@11.0592MHz
{
TMOD = 0x11; //ÉèÖö¨Ê±Æ÷ģʽ
TL1 = 0x33; //ÉèÖö¨Ê±³õʼֵ
TH1 = 0xFE; //ÉèÖö¨Ê±³õʼֵ
TF1 = 0; //Çå³ýTF1±êÖ¾
TR1 = 1; //¶¨Ê±Æ÷1¿ªÊ¼¼Æʱ
ET1 = 1; //¶¨Ê±Æ÷0µÄÖжËÔÊÐí¿ª¹Ø
EA = 1; //¶¨Ê±Æ÷×Ü¿ª¹Ø
PT1 = 1; //ÉèÖö¨Ê±Æ÷Ϊ¸ßµÍ¿ØÖÆÓÅÏȼ¶£¬1Ϊ¸ßÓÅÏȼ¶£¬0ΪµÍÓÅÏȼ¶
}
void Timer1_Routine() interrupt 3 //ÖжϺ¯Êý
{
TL1 = 0x33; //ÉèÖö¨Ê±³õʼֵ
TH1 = 0xFE; //ÉèÖö¨Ê±³õʼֵ
counter2++;
if (counter2 >= 40)
{
counter2 = 0;
}
if (counter2 < angle)
{
PWM = 1;
}
else
{
PWM = 0;
}
}
void Delay20us() //@11.0592MHz £¨ÑÓʱ20us£©
{
unsigned char i;
_nop_();
i = 6;
while (--i);
}
void chaoshengbo () //³¬Éù²¨²â¾à³ÌÐò
{
T2MOD = 0; //³õʼ»¯Ä£Ê½¼Ä´æÆ÷
T2CON = 0; //³õʼ»¯¿ØÖƼĴæÆ÷
TL2 = 0; //ÉèÖö¨Ê±³õʼֵ
TH2 = 0; //ÉèÖö¨Ê±³õʼֵ
RCAP2L = 0; //ÉèÖö¨Ê±ÖØÔØÖµ
RCAP2H = 0; //ÉèÖö¨Ê±ÖØÔØÖµ
Trig = 1; //·¢ÉäÒ»¶ÎÂö³å£¬ÖÁÉÙ20us
Delay20us();
Trig = 0;
while(!Echo); //µÈ´ý³¬Éù²¨Ä£¿éµÄ·µ»ØÂö³å
TR2 = 1; //´ò¿ª¶¨Ê±Æ÷
while(Echo); //µÈ´ý³¬Éù²¨Ä£¿é·µ»ØÂö³å½áÊø
TR2 = 0; //Í£Ö¹¶¨Ê±Æ÷£¬¼Æʱ½áÊø
sum = ((TH2*256+TL2)*0.034)/2+1; //¼ÆËã¾àÀë
}
void hongwai ()
{
if(IR_LF ==0)
{
car_stop ();
Delay100ms();
car_back ();
Delay100ms();
car_stop ();
Delay100ms();
car_rightgo ();//С³µÏòÇ°ÓÒ¹Õ
Delay100ms();
car_go();
}
if(IR_RF ==0)
{
car_stop ();
Delay100ms();
car_back ();
Delay100ms();
car_stop ();
Delay100ms();
car_leftgo (); //С³µÏòÇ°×ó¹Õ
Delay100ms();
car_go();
}
if(IR_LR ==0)
{
car_stop ();
Delay100ms();
car_go ();
Delay400ms();
car_stop ();
Delay100ms();
car_rightgo (); //С³µÓÒ¹Õ
Delay100ms();
car_go();
}
if(IR_RR ==0)
{
car_stop ();
Delay100ms();
car_go ();
Delay100ms();
car_stop ();
Delay100ms();
car_leftgo (); //С³µ×ó¹Õ
Delay100ms();
car_go();
}
}
void control0 () //¶æ»ú¹éÖгÌÐò
{
counter2 = 0;
angle = 3; //¶æ»ú¹éÖÐ
Delay400ms();
}
void control () //¶æ»úÐýת³ÌÐò
{
counter2 = 0;
angle = 2;
Delay400ms();
chaoshengbo ();
distance1 = sum;
counter2 = 0;
angle = 4;
Delay400ms();
counter2 = 0;
angle = 3; //¶æ»ú¹éÖÐ
Delay400ms();
chaoshengbo ();
distance2 = sum;
}
void system ()
{
// hongwai ();
car_go();
chaoshengbo ();
distance3 = sum;
if(distance3 < mindistance)
{
car_stop ();
Delay400ms();
control ();
if(distance1 < distance2)
{
car_back () ;
Delay400ms();
car_leftstop (); //С³µÔµØ×ó¹Õ
Delay100ms();
Delay100ms();
car_stop();
Delay100ms();
car_go ();
}
if(distance2 < distance1)
{
car_back () ;
Delay400ms();
car_rightstop (); //С³µÔµØÓÒ¹Õ
Delay100ms();
Delay100ms();
car_stop();
Delay100ms();
car_go ();
}
if(distance2 == distance1)
{
car_back () ;
Delay400ms();
car_rightstop (); //С³µÔµØÓÒ¹Õ
Delay400ms();
car_stop();
Delay100ms();
car_go();
}
}
else
{car_go();}
}
evadible.h
#ifndef __EVADIBLE_H_
#define __EVADIBLE_H_
void control0 (); //¶æ»ú¹éÖгÌÐò
void system ();
void Timer0_Init();
void Timer1_Init();
#endif
蓝牙控制
main.c
#include <REGX52.H>
#include "car.h"
unsigned char receiveData; //½ÓÊÕµ½µÄÊý¾Ý´æ·Å±äÁ¿
void receive(unsigned char m) //Ö´Ðк¯Êý
{
switch(m)
{
case '2': //Ç°½ø
car_go ();
break;
case '4': //ÏòÇ°×óת
car_leftgo ();
break;
case '6': //ÏòÇ°ÓÒת
car_rightgo ();
break;
case '8': //ºóÍË
car_back ();
break;
case '5': //Í£Ö¹
car_stop ();
break;
case '7': //ÔµØ×ó¹Õ
car_leftstop ();
break;
case '9': //ÔµØÓÒ¹Õ
car_rightstop ();
break;
}
}
void Uart_Init() //9600bps@11.0592MHz
{
PCON=0x00; //¹Ø±¶Æµ
SCON = 0x50; //8λÊý¾Ý,¿É±ä²¨ÌØÂÊ
TMOD = 0x20; //ÉèÖö¨Ê±Æ÷ģʽ
TL1 = 0xFd; //ÉèÖö¨Ê±³õʼֵ
TH1 = 0xFd; //ÉèÖö¨Ê±³õʼֵ
ET1 = 0; //½ûÖ¹¶¨Ê±Æ÷1ÖжÏ
TR1 = 1; //¶¨Ê±Æ÷1¿ªÊ¼¼Æʱ
EA=1; //×ÜÖжÏ
ES=1; //´ò¿ª´®¿ÚÖжÏ
}
void Uart_Routine() interrupt 4 //ÖжϺ¯Êý
{
car_stop ();
RI = 0; //Çå³ý½ÓÊÕÖжϱê־λ
receiveData=SBUF; //³öÈ¥½ÓÊÕµ½µÄÊý¾Ý
receive(receiveData);
}
void main ()
{
Timer0_Init();
Uart_Init();
while (1);
}
七、效果演示
八、Keill工程地址
https://pan.baidu.com/s/1GpwwNnDkqAa-jzERsbiwGA?pwd=u2ab 提取码:u2ab