51循迹小车(蓝牙+循迹+超声波+舵机+避障L298N)

基本驱动

L298N电机驱动模块负责供电和控制电机驱动

将电池12V供电接到12V供电上,作为输入。单片机及其他器件供电可以使用5V供电,这里的GND都接到一起。

输出A和输出B接到电机上,负责给电机供电和控制电机。

通道A使能和通道B使能以及逻辑输入部分都接到单片机上,在这里通道A使能和通道B使能接高电平使能,接PWM信号可以控制输出A和输出B的转速。

IN1 和 IN2 控制输出A
IN1=1,IN2=0,对应电机A正转
IN1=0,IN2=1,对应电机A反转
IN1、IN2同时输入高电平HIGH或低电平LOW,对应电机A停止转动

IN3 和 IN4 控制输出B
IN3=1,IN4=0,对应电机B正转
IN3=0,IN4=1,对应电机B反转
IN3、IN4同时输入高电平HIGH或低电平LOW,对应电机B停止转动

这里还要注意,如果电机堵转可能会烧毁其他器件,要注意不要让电机堵转。

代码参考

// 定义电机控制引脚  

#include<REG52.H>

sbit IN1=P1^1;    //左后轮
sbit IN2=P1^2; //左前轮
sbit IN3=P1^3;   //右后轮
sbit IN4=P1^4;//右前轮


void L_motor_go()//左轮前进   
{
	IN2=1; 
	IN1=0;	
}
void L_motor_back()//左轮后退        
{
	 IN2=0; 
	 IN1=1;	  
}
	void R_motor_go() //右轮前进        
{  
	 IN4=1; 
	 IN3=0;
}
void R_motor_back() //右轮后退      
{		
	 IN4=0; 
	 IN3=1;
}
void L_motor_stop() //左轮停止    
{
	IN2=0; 
	IN1=0;	
}
	void R_motor_stop() //右轮停止 
{
	IN4=0; 
	IN3=0;	
}
#include <REGX52.H>
#include "motor.h"
#include "CAR.H"

sbit ENA=P1^5;      //左使能端
sbit ENB=P1^6;     //右使能端

unsigned char speed=50;//小车速度

void timer0_Init() //100微秒@11.0592MHz
{
	  TMOD &= 0xF0;		//设置定时器模式
		TMOD |= 0x01;		//设置定时器模式 
    TH0 = 0xff;  
    TL0 = 0xa4; 
    TF0 = 0;  
    TR0 = 1; // 启动定时器0  
    ET0 = 1; // 允许定时器0中断  
    EA = 1; // 总中断允许   
}
  
void timer0() interrupt 1  
{
		static unsigned char count=0;
	  TH0 = 0xff;  
    TL0 = 0xa4; 
	  count++;
	 if(count >=100)
	 {
		 count = 0;
	 }
	 if(count < speed)//小车PWM
	 {
		 ENA = 1;
		 ENB = 1;
	 }
	 else
	 {
		 ENA = 0;
		 ENB = 0;
	 }
}
void car_go()
{
	R_motor_go();
	L_motor_go();		
}
void car_back()
{
	R_motor_back();
	L_motor_back();		
}
void car_left()
{
	R_motor_back();
	L_motor_go();	
}
void car_right()
{
	R_motor_go();
	L_motor_back();		
		
}
void car_stop()
{
	R_motor_stop();
	L_motor_stop();		
}

蓝牙模块

TXD:发送端,一般表示为自己的发送端,正常通信必须接另一个设备的RXD。
RXD:接收端,一般表示为自己的接收端,正常通信必须接另一个设备的TXD。

只当作串口来用接VCC、GND、TXD、RXD就够了,使用前先测试以下,使用手机蓝牙调试器连接蓝牙,电脑使用USB转TTL接到蓝牙模块上,然后用串口助手测试收发是否正常。正常波特率9600,如果不知道可以使用AT指令修改或查询。

先按住HC05蓝牙模块上面的按键,再给蓝牙模块通电。蓝牙模块上面的LED进入慢闪模式(约1秒钟闪烁一次),即可进行AT命令测试

AT命令格式为:波特率38400,8个数据位,1个停止位,无校验。每条指令输入完成后,必须按一下回车键再发送!

例如:输入AT,按一下回车键发送,蓝牙模块会返回OK

HC06在未连接蓝牙时可直接发送AT指令。

参考代码,主要实现控制小车和调试功能

#include <REGX52.H>
#include "CAR.H"
#include "BLE.H"
#include "CHAOSHENGBO.H"

unsigned char U_data;     //接受数据存放
unsigned char str[]=" Speed: ";//发送数据存放
unsigned char str1[]=" Length: ";
extern unsigned char flag1;

void UartInit(void)        //9600bps@11.0592MHz
{
    PCON &= 0x7F;            //波特率不倍速
    SCON = 0x50;            //8位数据,可变波特率
    TMOD &= 0x0F;             //设置定时器模式
    TMOD |= 0x20;             //设置定时器模式
    TL1 = 0xFD;                //设置定时初始值
    TH1 = 0xFD;                //设置定时重载值
    ET1 = 0;                     //禁止定时器中断
    TR1 = 1;                  //定时器1开始计时
    EA  = 1;
    ES  = 1;
	
}
 
void receive(unsigned char m)//接受数据
{

    switch(m)
    {
        case  'W':      //前进
            car_go();
        break;
        case  'A':
            car_left();    // 左转
        break;
        case  'D':
            car_right();     // 右转
        break;
        case 'S':
            car_back();   //  后退
        break;
        case 'I':      // 停止
            car_stop();
        break;
				case 'Q':      // 速度加
            speed+=5;
				uart_send_string(str);
				uart_send_byte(speed/10+'0');
				uart_send_byte(speed%10+'0');
        break;
				case 'E':      // 速度减
            speed-=5;
				uart_send_string(str);
				uart_send_byte(speed/10+'0');
				uart_send_byte(speed%10+'0');
        break;
				case 'B':      // 显示信息
				showInfo();
        break;
				case 'N':      // 舵机角度加
				angle++;
				if(angle>25)angle=25;
        break;
				case 'M':      // 舵机角度减
				angle--;
				if(angle<5)angle=5;
        break;
				case 'P':      //循迹模式切换
				flag1=!flag1;
				uart_send_byte(flag1);
        break;
				default:
					break;        
    }
        
}


//发送一个字符
void uart_send_byte(unsigned char byte_data)
{
 	SBUF = byte_data;
	while(!TI);
	TI=0;
}

//发送一串字符串
void uart_send_string(unsigned char *str)
{
 	while(*str)
	{
	 	uart_send_byte(*str++);	
	}
}

//显示信息
void showInfo()
{
	uart_send_string(str);
	uart_send_byte(speed/10+'0');
	uart_send_byte(speed%10+'0');
	uart_send_string(str1);
	uart_send_byte(Length/100+'0');
	uart_send_byte(Length/10%10+'0');
	uart_send_byte(Length%10+'0');
}

//***************************************************************************   
void UartInit_seve() interrupt 4
{
    if(RI==1)
		{
			RI = 0;                  //清除接受中断标志位
			U_data = SBUF;                    //接受数据
			receive(U_data);
		}
       
}

循迹模块

调节可调电阻设置测量距离,做到测到地板上黑线灯灭,没测到黑线灯亮的状态,通过排列所有情况组合可以达到循迹的效果

参考代码

#include <REGX52.H>
#include "CAR.H"
sbit left1=P2^0;
sbit left2=P2^1;
sbit right3=P2^2;
sbit right4=P2^3;
/*循迹情况分析*/
void xunji()
{  
unsigned char a;                                 
if(left1==0 &&left2==0 &&right3==0 &&right4==0)       //0000 
a = 1;
else if(left1==0 &&left2==0 &&right3==0 &&right4==1)  //0001 
a = 3;
else if(left1==0 &&left2==0 &&right3==1 &&right4==0)  //0010
a = 1;
else if (left1==0 &&left2==0 &&right3==1 &&right4==1) //0011 
a = 3;
else if(left1==0 &&left2==1 &&right3==0 &&right4==0)  //0100 
a = 1;
else if(left1==0 &&left2==1 &&right3==0 &&right4==1)  //0101 
a = 3;
else if(left1==0 &&left2==1 &&right3==1 &&right4==0)  //0110 
a = 1;
else if(left1==0 &&left2==0 &&right3==1 &&right4==1)  //0111 
a = 3;
else if(left1==1 &&left2==0 &&right3==0 &&right4==0)  //1000 
a = 2;
else if(left1==1 &&left2==0 &&right3==0 &&right4==1)  //1001 
a = 1;
else if(left1==1 &&left2==0 &&right3==1 &&right4==0)  //1010 
a = 2;
else if(left1==1 &&left2==0 &&right3==1 &&right4==1)  //1011 
a = 1;
else if(left1==1 &&left2==1 &&right3==0 &&right4==0)  //1100
a = 2;
else if(left1==1 &&left2==1 &&right3==0 &&right4==1)  //1101
a = 1;
else if(left1==1 &&left2==1 &&right3==1 &&right4==0)  //1110 
a = 2;
else if(left1==1 &&left2==1 &&right3==1 &&right4==1)  //1111 
a = 1;

  switch (a)
  {
  case 1:car_go();break;
  case 2:car_left();break;
  case 3:car_right();break;
  case 4:car_stop();break;
  default:break;
  }
}

超声波模块

给Trlg引脚至少10us高电平,之后Echo引脚就会返回高电平,通过计算高电平时间即可完成测距,如果需要测距更精确可加入温度补偿。

参考代码

#include <REGX52.H>
#include <intrins.h> 
#include "car.h"
#include "BLE.H"


sbit Trig = P2^7;
sbit Echo = P2^6; 

unsigned char Length; //测距结果
unsigned char mindistance = 10; //小车与障碍物的距离

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
void Delay20us()		//@11.0592MHz
{
	unsigned char i;

	_nop_();
	i = 6;
	while (--i);
}

void chaoshengbo()
{

	T2MOD = 0;		//初始化模式寄存器
	T2CON = 0;		//初始化控制寄存器
	TL2 = 0;		//设置定时初值
	TH2 = 0;		//设置定时初值
	RCAP2L = 0;		//设置定时重载值
	RCAP2H = 0;		//设置定时重载值
	
	Trig = 1;
	Delay20us();
	Trig = 0;
	
	while(!Echo);
	TR2 = 1;
	while(Echo);
	TR2 = 0;
	
	Length = ((TH2*256+TL2)*0.034)/2+1;
	if(mindistance > Length)
	{
		car_stop();
	}
}

舵机驱动

型号:SG90  重量13克 角度0度-180度

信号线(黄线)红线(电源线)棕色(地线)

舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。以180度角度伺服为例,那么对应的控制关系是这样的:

   0.5ms--------------0度;

   1.0ms------------45度;

   1.5ms------------90度;

   2.0ms-----------135度;

   2.5ms-----------180度;

参考代码

#include <REGX52.H>

sbit servo=P2^5 ;
unsigned char angle=13;//舵机角度,5-25对应0-180度

void timer0_Init() //100微秒@11.0592MHz
{
	  TMOD &= 0xF0;		//设置定时器模式
		TMOD |= 0x01;		//设置定时器模式 
    TH0 = 0xff;  
    TL0 = 0xa4; 
    TF0 = 0;  
    TR0 = 1; // 启动定时器0  
    ET0 = 1; // 允许定时器0中断  
    EA = 1; // 总中断允许   
}

void timer0() interrupt 1  
{
	static unsigned char count=0;
	TH0 = 0xff;  
    TL0 = 0xa4; 
	count++;
	 if(count >=200)
	 {
		 count = 0;
	 }
	 
	 if(count < angle)//舵机PWM
	 {
		 servo = 1;
	 }
	 else
	 {
		 servo = 0;
	 }
}

避障模块

该传感器模块对环境光线适应能力强,其具有一对红外线发射与接收管,发射管发射出一定频率的红外线,当检测方向遇到障碍物(反射面)时,红外线反射回来被接收管接收,经过比较器电路处理之后,绿色指示灯会亮起,同时信号输出接回输出数字信号(一个低电平信号),可通过电位器旋钮调节检测距离,有效距离范围2~30cm,工作电压为3.3v-5v。该传感器的探测距离可以通过电位器调节、具有干扰小、便于装配、使用方便等特点,可以广泛应用于机器人避障、避障小车、流水线计数及黑白线循迹等众多场合。
当模块检测到前方障碍物信号时,电路板上绿色指示灯点亮,同时OUT端口持续输出低电平信号

该模块测距离2~~30cm,检测角度35°,检测距离可以通过电位器进行调节,顺时针调电位器,检测距离增加;逆时针调电位器,检测距离减少。

传感器主动红外线反射探测,因此目标的反射率和形状是探测距离的关键。其中黑色探测距离小,白色大;小面积物体距离小,大面积距离大。

  • 17
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值