51蓝牙红外循迹避障小车+代码

Posted 另一个^梦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51蓝牙红外循迹避障小车+代码相关的知识,希望对你有一定的参考价值。

 设计背景:

本次设计主要是为了学校的一个电子竞赛才做的这一个小项目,这也是我刚学习51单片机以来做的第一个大制作。其实这个制作的原理很简单,但实际做出来却花了一些时间,下面就简单地给大家介绍一下我们的制作,也为各位网友作为一个参考。

使用到的模块:

51单片机  L298N电机驱动模块  红外传感器模块  hc05蓝牙模块  普通直流电机

实现的原理:

 电路设计:

成品展示:

 

 

 程序设计: 

L298N驱动直行转向程序,这里用的是定时器0作为PWM输出。关于L298N和定时器可以在网上查找资料,知道如何使用,这里就不给大家详细介绍了。

#include "xunji.h"
#include "reg52.h"

uchar PWMCnt1;
uchar PWMCnt2;
uchar cntPWM1;
uchar cntPWM2;

//uchar PWMA;
//uchar PWMB;

void Delay(int xms)		//@12.000MHz
 while(xms--)
	unsigned char i, j;

	i = 2;
	j = 239;
	do
	
		while (--j);
	 while (--i);
 

void Timer0_init()

	TMOD &=0xF0;
	TMOD |=0X01;//使用定时器0
	
	TH0 = 0xFF;
	TL0 = 0xA3;
	
	EA=1;//全局中断位
	ET0=1;//定时器0中断允许位
	TR0=1;//定时器0运行允许位

void turnright1()		   //右转

	IN1 = 0;	//右轮反转
	IN2 = 1;

	IN3 = 0;	//左轮正转
	IN4 = 1;
	cntPWM1 = 50;
	cntPWM2	= 45;


void turnRight2()		   //右转

	IN1 = 0;	//右轮反转
	IN2 = 1;

	IN3 = 0;	//左轮正转
	IN4 = 1;
	cntPWM1 = 45;
	cntPWM2	= 40;


void turnleft1()				//左转

	IN1 = 1;
	IN2 = 0;   	//右轮正转

	IN3 = 1;
	IN4 = 0;   	//左轮反转
	cntPWM1 = 45;
	cntPWM2	= 50;
			  	

void turnLeft2()				//左转

	IN1 = 1;
	IN2 = 0;   	//右轮正转
 
	IN3 = 1;
	IN4 = 0;   	//左轮反转
	cntPWM1 = 40;
	cntPWM2	= 45;
	
	
void forward()				 //前进

	IN1 = 1;
	IN2 = 0;   	//右轮正转

	IN3 = 0;   	//左轮正转
	IN4 = 1;

	cntPWM1 = 26;
	cntPWM2	= 25;


void backward()					 //后退

	IN1 = 0;	//右轮反转
	IN2 = 1;

	IN3 = 1;
	IN4 = 0;	//左轮反转
	cntPWM1 = 26;
	cntPWM2	= 25;


void Stop()					  //停止

	IN1 = 0;
	IN2 = 0;

	IN3 = 0;
	IN4 = 0;


void interrupttimer0() interrupt 1

	TH0 = (65536 - 50)/256;
	TL0 = (65536 - 50)%256;

	PWMCnt1++;
	PWMCnt2++;
	
	PWMCnt1%=100;
	PWMCnt2%=100;
	
	if(PWMCnt1<=cntPWM1)
	
		ENA=1;
	
	else
		ENA=0;
	
	if(PWMCnt2<=cntPWM2)
	
		ENB=1;
	
	else
		ENB=0;
	
//	
//	if(PWMA<=cntPWM1)
//	
//		ENA=1;
//	
//	else
//		ENA=0;
//	
//	if(PWMB<=cntPWM2)
//	
//		ENB=1;
//	
//	else
//		ENB=0;

循迹模块程序,这里利用是4个红外传感器返回的高低电平来判断黑线的位置,从而驱使小车的直行与转向。程序比较繁杂,其实有很多是多余的,还可以进行一些简化,不需要4个传感器都要判断是否输出高低,另外直行的程序最好放在前面,并且再加上else,这样的话,前面判断成功了就不用再去执行后面的程序,可以缩短cpu消耗的时间。

void XunJi()


	unsigned char flag = 0;
  
	if((left1 == 0)&&(left2 == 0)&&(right1 == 0)&&(right2 == 0))   //0 0 0 0
	  flag = 0;

	if((left1 == 0)&&(left2 == 0)&&(right1 == 0)&&(right2 == 1))   //0 0 0 1
		flag = 1;

	if((left1 == 0)&&(left2 == 0)&&(right1 == 1)&&(right2 == 0))   //0 0 1 0
		flag = 0;

	if((left1 == 0)&&(left2 == 0)&&(right1 == 1)&&(right2 == 1))   //0 0 1 1
		flag = 2;

	if((left1 == 0)&&(left2 == 1)&&(right1 == 0)&&(right2 == 0))   //0 1 0 0
		flag = 0;

	if((left1 == 0)&&(left2 == 1)&&(right1 == 0)&&(right2 == 1))   //0 1 0 1
		flag = 4;

	if((left1 == 0)&&(left2 == 1)&&(right1 == 1)&&(right2 == 0))   //0 1 1 0
		flag = 0;
	
	if((left1 == 0)&&(left2 == 1)&&(right1 == 1)&&(right2 == 1))    //0 1 1 1
		flag = 1;
	
	if((left1 == 1)&&(left2 == 0)&&(right1 == 0)&&(right2 == 0))   //1 0 0 0
		flag = 3;
	
	if((left1 == 1)&&(left2 == 0)&&(right1 == 0)&&(right2 == 1))   //1 0 0 1
		flag = 0;
	
	if((left1 == 1)&&(left2 == 0)&&(right1 == 1)&&(right2 == 0))   //1 0 1 0
		flag = 2;
	
	if((left1 == 1)&&(left2 == 0)&&(right1 == 1)&&(right2 == 1))   //1 0 1 1
		flag = 0;
	
	if((left1 == 1)&&(left2 == 1)&&(right1 == 0)&&(right2 == 0))   //1 1 0 0
		flag = 4;
	 
	if((left1 == 1)&&(left2 == 1)&&(right1 == 0)&&(right2 == 1))   //1 1 0 1
		flag = 0;

	if((left1 == 1)&&(left2 == 1)&&(right1 == 1)&&(right2 == 0))   //1 1 1 0
		flag = 3;
	
	if((left1 == 1)&&(left2 == 1)&&(right1 == 1)&&(right2 == 1))   //1 1 1 1
		flag = 6;
	
	switch(flag)
	

		case 0:forward();break;
	
		case 1:turnright1();break;
	
		case 2:turnright2();break;
	
		case 3:turnleft1();break;
	
		case 4:turnleft2();break;
	
		case 5:backward();break;
	
	  default:stop();break;
	

避障模块程序,这里是利用的小车上边的3个红外传感器来识别前方障碍物,根据障碍物位置来做如何的转向,从而实现避障。

void bizhan()  //循迹+避障

	if((bizh1==1)&&(bizh2==1)&&(bizh3==1))
		XunJi();
	if((bizh1==0)||(bizh2==0)||(bizh3==0))
	
		stop();
		Delay (500);
		turnright2();
		Delay (60); 
	

	
void bizh()    //避障

	if((bizh1==1)&&(bizh2==1)&&(bizh3==1))
		forward();
	if((bizh1==0)&&(bizh2==1)&&(bizh3==1))
		turnleft2();
	if((bizh1==1)&&(bizh2==0)&&(bizh3==1))
		turnright2();
	if((bizh1==1)&&(bizh2==1)&&(bizh3==0))
		turnright2();
	if((bizh1==0)&&(bizh2==0)&&(bizh3==0))
	  turnleft2();
	if((bizh1==0)&&(bizh2==0)&&(bizh3==1))
		turnleft1();
	if((bizh1==1)&&(bizh2==0)&&(bizh3==0))
		turnright1();

蓝牙控制程序

#include "reg52.h"
#include "bluetooth.h"

uchar temp;

uchar speedA;
uchar speedB;

void uart_init()//这是对蓝牙串口进行初始化,不是定时器1

	TMOD &=0xF0;
	TMOD |=0x21;//定时器1采用方式2 8位初值自动重装
	SCON=0x50;
	
	TL1=0xFD;
	TH1=0xFD;
	
	PCON=0x00;//电源控制寄存位
	
	ES=1;//串口通信运行允许位
	TR1=1;//定时器1运行


//void sendbyte(uchar c)
//
//	SBUF=c;//发送数据
//	
//	while(!TI);//没有发送完一直执行这个空语句
//	/*发送字节完成后TI 变成1,则需要最后把他置零;RI也一样*/
//	TI=0;//发送串口中断判断位
//

void uart_interrupt() interrupt 4

	if(RI)//串口中断允许位
	
		temp=SBUF;//取出数据
		RI=0;//取出数据后RI变为1,需要最后把他置零
		
	    quick();
		slow();
	


void quick()//蓝牙加速

	speedA*=2;
	speedB*=2;


void slow()//蓝牙减速

	speedA%=2;
	speedB%=2;


小车的主程序

#include "reg52.h"
#include "xunji.h"
#include "bluetooth.h"

extern uchar temp;//用于切换模式和蓝牙指令

void start();

void main()

	Timer0_init();
	uart_init();
	
	while(1)
	
		start();
	
	


void start()

	switch(temp)
	
		case 'e':bizhan();break;
		case 'f':forward1(); break;
		case 'a':quick();break;
		case 'b':backward2(); break;
		case 'c':slow();break;
		case 'r':turnleft(); break;
		case 'l':turnright(); break;
		case 's':stop(); break;
		case 'k':bizh();break;
		default :stop();break;//如果传输了一个这些之外的字母,则stop()
	

最后

程序只是作为一个参考,真正调试还需要根据实际情况为准。比如PWM的调试,循迹模块程序的简化等。另外上边展示的主要是一些重要的模块程序,详细的可以点击下面的连接自己提取。最后,希望大家都能做出自己满意的小车。

链接:https://pan.baidu.com/s/11-6rN-bxYrJlRpDWrP0K4g 
提取码:armc

以上是关于51蓝牙红外循迹避障小车+代码的主要内容,如果未能解决你的问题,请参考以下文章

IoT红外循迹避障小车

基于单片机多功能循迹避障无线遥控蓝牙智能小车-设计资料

基于单片机的智能循迹避障小车STC89C52红外对管L298N驱动PWM波控制速度

基于单片机智能灯光光控照明系统设计基于单片机HX711电子秤自动计价系统设计基于单片机GPRS远程测控系统设计基于单片机多功能循迹避障无线遥控蓝牙智能小车-设计资料

小车(蓝牙,红外,超声波,循迹)

基于stm32f103循迹避障遥控车