版权声明:转载请标明原文章地址 https://blog.csdn.net/weixin_41543617/article/details/83995057
一、 设计任务
a.熟悉机器人的构造及组成,实现机器人按指令行走(前进,左转,右转,匀加速,匀减速,停止等)
b.通过红外传感器触发,实现每次触发的时候运行状态的改变
c.通过超声波传感器测量距离,并且能够串口观察测量数据
d.根据超声波测量距离的不同实现运行状态的转换
e.利用红外传感器作为触发开关,利用超声波传感器测距,最终控制机器人在规划的场地内避开障碍物走遍整个场地。
二、模块使用
1.红外模块
模块接口说明:
(1)VCC 外接 3.3V-5V 电压(可以直接与 5v 单片机和 3.3v 单片机相连)
(2)GND 外接 GND
(3)OUT 小板数字量输出接口(0 和 1)
2.超声波(HC-SR04)
工作原理:
(1)采用IO口TRIG触发测距,给至少10us的高电平信号;
(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;
(3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2;
(4)本模块使用方法简单,一个控制口发一个10US以上的高电平,就可以在接收口等待高电平输出。一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,此时就为此次测距的时间,方可算出距离。如此不断的周期测,即可以达到你移动测量的值
3.行走机构为360度舵机
三、代码
#include <intrins.h>
#include<BoeBot.h>
#include<uart.h>
#define uchar unsigned char
#define uint unsigned int
#define ECHO P1_4
#define TRIC P1_2
#define RED P0_0
uint time=0;
uint timer=0;
float S=0;
bit flag =0;
uint i=0;
uint end=0;
uint turn=0;
/*************计算超声波探测距离***************************/
void Conut(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.85)/100; //算出来是CM
if(flag==1) //超出测量
{
flag=0;
S=1000;
printf("-----\n");
}
printf("S=%f\n",S);
}
/********************************************************/
void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
{
flag=1; //中断溢出标志
}
/************************启动超声波****************************/
void StartModule()
{
TRIC=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TRIC=0;
}
/********************控制小车姿态************************************/
// P1_0=1; //P1_0输出高电平 1300 右正
// P1_1=1; //P1_1输出高电平 1700 左正
void stop(void)
{
P1_0=1;
delay_nus(1500);
P1_1=1;
P1_0=0;
delay_nus(1500);
P1_1=0;
P1_1=0;
delay_nms(20);
}
void forward(void)
{
P1_1=1;
delay_nus(1700);
P1_0=1;
P1_1=0;
delay_nus(1300);
P1_0=0;
P1_1=0;
delay_nms(20);
if(RED==0)
{
while(1)
{stop();}
}
}
void left(void)
{
for(i=23;i>0;i--)
{
P1_1=1;
delay_nus(1300);
P1_0=1;
P1_1=0;
delay_nus(1300);
P1_0=0;
P1_1=0;
delay_nms(20);
if(RED==0)
{
while(1)
{stop();}
}
}
}
void right(void)
{
for(i=23;i>0;i--)
{
P1_1=1;
delay_nus(1700);
P1_0=1;
P1_1=0;
delay_nus(1700);
P1_0=0;
P1_1=0;
delay_nms(20);
if(RED==0)
{
while(1)
{stop();}
}
}
}
void backward(void)
{
P1_1=1;
delay_nus(1300);
P1_0=1;
P1_1=0;
delay_nus(1700);
P1_0=0;
P1_1=0;
delay_nms(20);
}
/********************读取超声波测距***********************************/
void read(void)
{
StartModule();
while(!ECHO); //当RX为零时等待
TR0=1; //开启计数
while(ECHO); //当RX为1计数并等待
TR0=0; //关闭计数
Conut(); //计算
}
/******************************************************/
void main(void)
{
TMOD |=0x20; //设置定时器T/C1工作在方式2,定时1工作于自动重载模式
SCON=0x50; //设置串行口工作方式1
TH1=0xfd; //波特率9600
TL1=0xfd;
TR1=1; //启动定时器
ES=1; //开串行口中断
TH0=0;
TL0=0;
TR0=1;
ET0=1; //允许T0中断
TR1=1; //开启定时器
TI=1;
EA=1; //开启总中断
end=0;
turn=0;
while(RED);
while(RED==0);
while(1)
{
read();
if(S>=100)
forward();
else
{
turn++;
end=0;
}
if(end==0)
{
switch(turn){
case 1:
left();
for(i=40;i>0;i--)
{
forward();
}
left();
end=1;
break;
case 2:
left();
end=1;
break;
case 3:
right();
end=1;
break;
case 4:
right();
for(i=40;i>0;i--)
{
forward();
}
right();
end=1;
break;
case 5:
left();
end=1;
break;
case 6:
right();
end=1;
break;
case 7:
left();
left();
end=1;
break;
case 8:
left();
end=1;
break;
case 9:
left();
turn=0;
end=1;
break;
default:
break;
}
}
}
}