小车测距避障-通过串口(可蓝牙)控制

小车摇头测距避障-串口控制

实验效果

可用串口控制小车前进后退左转右转,开启或关闭避障模式,将蓝牙模块接到串口上,就可用手机HC蓝牙助手控制小车启动或切换到避障模式

程序

拿前面舵机摇头+超声波测距避障的代码来进行修改,新增串口控制的功能即可

程序文件:

1.main.c:定时器0、定时器2、串口的初始化函数调用,while循环内进行避障函数的调用

2.Motor.c:小车前进、后退、左转、右转和停止的函数,左右转函数是一个轮前进,另一个轮后退

3.Delay.c:延时函数

4.Sg90.c:定时器0初始化函数,中断PWM,舵机摇头的角度(封装成函数)

5.HC-SR04.c:定时器2初始化函数,不开启中断,因为这次用到串口控制,要用定时器1作波特率发生器,所以超声波改为用定时器2,超声波测距的函数

6.Avoid.c:将上次超声波避障的逻辑代码进行函数封装,单独写成一个源文件,供主函数调用

7.Uart.c:串口初始化函数,中断处理也是使用之前的判断逻辑

在这里插入图片描述

Avoid.c:

把前面测距避障的代码进行封装整合,写成一个源文件

#include <REGX52.H>
#include "Delay.h"
#include "Motor.h"
#include "HC-SR04.h"
#include "Sg90.h"

unsigned char MiddleFlag;		//超声波方向朝前标志位
double MiddleDis,LeftDis,RightDis;

/**
  * @brief 舵机初始化时90度,让超声波模块向前
  * @param 无
  * @retval无
  */
void HC_Init()
{
	SgMiddle();		//一开始为90度,往前
	Delay1ms(300);
	MiddleFlag = 1;	//标志位置1
}

/**
  * @brief 开启避障模式
  * @param 无
  * @retval无
  */
void Start_Avoid()
{
	if(MiddleFlag != 1)				//避免舵机抽搐
	{
		SgMiddle();
		Delay1ms(180);
		MiddleFlag = 1;
	}
	MiddleDis = ultrasonic();		//检测前方距离
	if(MiddleDis > 30)				//前方没有障碍
	{
		GoForward();				//前进
	}
	else if(MiddleDis < 10)			//如果距离过小
	{
		GoBack();					//后退
	}
	else							//前方有障碍
	{
		//停止
		Stop();
		SgLeft();					//180度,左扭头
		Delay1ms(180);
		LeftDis = ultrasonic();		//测左边距离
		
		SgMiddle();					//回到中间
		Delay1ms(180);
		
		SgRight();					//0度,右扭头
		Delay1ms(180);
		RightDis = ultrasonic();	//测右边距离
		
		//若左边距离大于右边距离,说明左边宽敞,向左转
		if(LeftDis > RightDis)	
		{
			GoLeft();
			Delay1ms(170);
			Stop();
		}
		//若右边距离大于左边距离,说明右边宽敞,向右转
		if(RightDis > LeftDis)
		{
			GoRight();
			Delay1ms(170);
			Stop();
		}
		MiddleFlag = 0;
	}
}

Uart.c:

串口中断函数中加入新指令,串口收到的指令如果是“Avoid”,则将避障模式的标志位置1,其他判断不变

#include <REGX52.H>
#include "Motor.h"
#include "Delay.h"
#include "string.h"

#define SIZE 10
unsigned char rec[SIZE];
extern unsigned char Avoid_Flag;

/**
  * @brief 串口初始化
  * @param 无
  * @retval无
  */
void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	ES = 1;			//开启串口中断
	EA = 1;			//开启总中断
}

//串口中断处理
void Uart_Rountine() interrupt 4
{
	static unsigned int i = 0;
	unsigned char temp;
	if(RI)
	{
		RI = 0;
		temp = SBUF;
		if(temp == 'F' || temp == 'B' || temp == 'L' || temp == 'R' || temp == 'S' || temp == 'A')
		{
			i = 0;
		}
		rec[i++] = temp;
		//前进
		if(rec[0] == 'F' && rec[1] == 'o')
		{
			GoForward();
			Delay1ms(200);
			i = 0;
			memset(rec,'\0',SIZE);
		}
		//后退
		if(rec[0] == 'B' && rec[1] == 'a')
		{
			GoBack();
			Delay1ms(200);
			i = 0;
			memset(rec,'\0',SIZE);
		}
		//左转
		if(rec[0] == 'L' && rec[1] == 'e')
		{
			GoLeft();
			Delay1ms(100);
			i = 0;
			memset(rec,'\0',SIZE);
		}
		//右转
		if(rec[0] == 'R' && rec[1] == 'i')
		{
			GoRight();
			Delay1ms(100);
			i = 0;
			memset(rec,'\0',SIZE);
		}
		//停止
		if(rec[0] == 'S' && rec[1] == 't')
		{
			Stop();
			Avoid_Flag = 0;
			i = 0;
			memset(rec,'\0',SIZE);
		}
		//避障模式
		if(rec[0] == 'A' && rec[1] == 'v')
		{
			Avoid_Flag = 1;
			i = 0;
			memset(rec,'\0',SIZE);
		}
		//松手停止
		if(rec[0] == '\0' && rec[1] == '\0')
		{
			Stop();
		}
		if(i == SIZE){i = 0;}
	}
}

main.c:

主函数中要先调用定时器0、定时器2、串口的初始化函数,调用函数让舵机旋转,让超声波模块往前,然后while循环内就不断判断标志位是否是1,是1则说明串口那边下指令了,就调用函数让小车进入避障模式

#include <REGX52.H>
#include "Motor.h"
#include "Delay.h"
#include "Sg90.h"
#include "Avoid.h"
#include "HC-SR04.h"
#include "Uart.h"

/*1.先将避障的方法模块化
  2.将超声波改用定时器2,定时器1留给串口
  3.增加串口源文件和头文件
*/

unsigned char Avoid_Flag;
unsigned char temp;

void main()
{
	Timer0Init();
	Timer2Init();
	UartInit();
	HC_Init();		//超声波模块往前
	while(1)
	{
		//开始避障
		if(Avoid_Flag == 1)
		{
			Start_Avoid();
		}
	}
}
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值