51智能避障蓝牙小车
程序员文章站
2022-05-21 22:20:30
...
51智能避障+蓝牙小车
清单:
- 51最小系统板
- HC-SR04超声测距模块
- SG90舵机(注意180°和360°区别)
- 车壳,车轮
- 电机*4
- 18650电池(3.7V)*3
- L298N电机驱动
- HC-08 主从一体蓝牙模块
- 其他零件
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uint time,count;
int S;
sbit k1=P2^5;
sbit k2=P2^6;
sbit Trig = P2^2; //超声波模块的TRIG
sbit Echo = P2^3; //超声波模块的ECHO
sbit motorDriver_1 =P1^0; //控制第一个电机,从单片机出来后接L298n模块的IN1
sbit motorDriver_2 =P1^1; //控制第一个电机,从单片机出来后接L298n模块的IN2
sbit motorDriver_3 =P1^2; //控制第二个电机,从单片机出来后接L298n模块的IN3
sbit motorDriver_4 =P1^3; //控制第二个电机,从单片机出来后接L298n模块的IN4
sbit pwm =P0^0; //舵机的控制引脚
uchar a=0;
int jd=3;
uchar servorTime=0;
int lflag;//左方向障碍物距离
int rflag;//右方向障碍物距离
int sflag;//q方障碍物距离
uchar flag=0;//前方障碍物距离
char receive_data;
int mod;
int openhc();
void delay(uchar time){ //延迟函数
uchar i;
for(;time>0;time--){
for(i=0;i<255;i++);
}
}
void delay500ms(void) //误差 -0.000000000114us
{
unsigned char a,b,c;
for(c=98;c>0;c--)
for(b=127;b>0;b--)
for(a=17;a>0;a--);
_nop_(); //if Keil,require use intrins.h
}
void stop(){ //小车停止
motorDriver_1=0;
motorDriver_2=0;
motorDriver_3=0;
motorDriver_4=0;
}
void turnLeft(){ //小车向左转
motorDriver_1=0;
motorDriver_2=1;
motorDriver_3=1;
motorDriver_4=0;
} //小车向右转
void turnRight(){
motorDriver_1=1;
motorDriver_2=0;
motorDriver_3=0;
motorDriver_4=1;
}
void qian(){ //小车向前走
motorDriver_1=1;
motorDriver_2=0;
motorDriver_3=1;
motorDriver_4=0;
}
void hou(){ //小车向后走
motorDriver_1=0;
motorDriver_2=1;
motorDriver_3=0;
motorDriver_4=1;
}
void Conut(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.87)/100; //算出来是CM
flag=0;
}
void zd0() interrupt 3
{
TH1 = 0xfe; //重新赋值
TL1 = 0x33;
if(count< jd) //判断0.5ms次数是否小于角度标识
pwm=1; //确实小于,PWM输出高电平
else
pwm=0; //大于则输出低电平
count=(count+1); //0.5ms次数加1
count=count%40; //次数始终保持为40 即保持周期为20ms
}
int openhc()
{ int i;
flag=1;
S=0;
Trig=0;
Echo=0;
_nop_();
Trig=1;
for(i=0;i<12;i++)
{
_nop_();
}
Trig=0;
while(!Echo); //当RX为零时等待
TR0=1; //开启计数
while(Echo); //当RX为1计数并等待
TR0=0; //关闭计数
Conut(); //计算
Echo=0;
return S;
}
void init()
{
TMOD=0x11; //设T0为方式1,GATE=1;
TH0=0;
TL0=0;
TH1 = 0xfe; //重新赋值
TL1 = 0x33;
ET0=1; //允许T0中断
EA=1;
TR1=0;
PT0=1;
PT1=0;
ET1 = 1;
TR1 = 0;
}
void goback()
{
while(rflag<=30 && lflag<=30)
{
hou();
delay(200);
delay(200);
delay(200);
stop();
jd=1;
TR1=1;
delay500ms();
TR1=0;
rflag=openhc();
jd=5;
TR1=1;
delay500ms();
TR1=0;
lflag=openhc();
jd=3;
TR1=1;
delay500ms();
TR1=0;
}
}
void autogo()
{
init();
while(1)
{
jd=3;
TR1=1;
delay500ms();
TR1=0;
openhc();
while(S>40)
{
qian();
openhc();
if(S<=40)
{
stop();
break;
}
}
stop();
jd=1;
TR1=1;
delay500ms();
TR1=0;
rflag=openhc();
jd=5;
TR1=1;
delay500ms();
TR1=0;
lflag=openhc();
jd=3;
TR1=1;
delay500ms();
TR1=0;
sflag=openhc();
if( rflag<40 && lflag<40 )
{
goback();
}
if(sflag>=40)
{
qian();
continue;
}
else
{
if(rflag>=lflag)
{
turnRight();
delay(200);
delay(100);
}
else{
turnLeft();
delay(200);
delay(100);
}
}
stop();
}
}
void UsartConfiguration()
{
SCON=0X50; //设置为工作方式1,8位数据,可变波特率
TMOD=0X20; //设置计数器工作方式2
PCON=0X00; //波特率不加倍
TH1=0XFd; //计数器初始值设置,aaa@qq.com
TL1=0XFd;
TR1=1; //打开计数器
ES = 1; //开串口中断
EA = 1; //开总中断
}
void Com_Int(void) interrupt 4
{
if(RI == 1) //当硬件接收到一个数据时,RI会置位
{
RI = 0;
receive_data = SBUF;//接收到的数据
if(receive_data == '1')
{
qian();
}
else if(receive_data == '2')
{
hou();
}
else if(receive_data == '3')
{
turnLeft();
}
else if(receive_data == '4')
{
turnRight();
}
else if(receive_data == '5')
{
stop();
}
}
}
int
keypros()
{
if(k1==0) //检测按键K1是否按下
{
delay(1000); //消除抖动 一般大约10ms
if(k1==0) //再次判断按键是否按下
{
autogo();
}
while(!k1); //检测按键是否松开
}
if(k2==0) //检测按键K1是否按下
{
delay(1000); //消除抖动 一般大约10ms
if(k2==0) //再次判断按键是否按下
{
return 0;
}
while(!k2); //检测按键是否松开
}
}
void main()
{
UsartConfiguration();
while(keypros());
}
先贴上程序,具体设计过程以后再写哈哈
上一篇: MATLAB的GUI如何清空坐标轴的图像