51巡线小车

开写

使用51单片机制作一个简单的巡线小车,这个很多人都有制作过,废话不多说,直接上电路图。
51巡线小车

模块介绍

5个模块,逐一介绍。
控制模块,没什么好说的,都知道巡线小车,应该都懂。晶振就不说,P1口接拨码开关,是控制车速。P0口接红外的反馈。P2口控制电机与舵机。
红外模块,识别黑白线,小车自动巡线的前提。红外传感器识别黑白线时输出变压不同,可以以此调整电压来判断小车有无跑偏。
电机模块,控制两个后轮的转动,可以用占空比来调速。
舵机模块,控制小车装弯。
稳压模块,输出稳定5v,确保4个模块稳定工作。

使用讲解

舵机使用

舵机是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。目前,在高档遥控玩具,如飞机、潜艇模型,遥控机器人中已经得到了普遍应用。
舵机就是使用占空比来控制,在一段20ms的周期中,使用不同的脉冲宽度来控制舵机在0~180度之间转动。

脉冲宽度(20ms) 舵机输出轴转角(单位:度)
0.5ms 0
1ms 45
1.5ms 90
2ms 135
2.5ms 180

由于51单片机没有专门的pwn输出功能,只能自行用定时器设置一个脉冲周期。这只是控制一个舵机,简单。直接上程序。
定时器1初始化设置。

	unsigned int angle=10;	//定义角度
	TMOD = 0x10;		//定时器1工作模式1
	TL1 = 0xd2;		 //定时50us进入中断
	TH1 = 0xff;			
	TR1 = 1;			
	IE=0X88;

中断函数设置,400次为20ms,一个舵机控制周期,motor为舵机信号线位,其中angle=10,就是0.5ms,角度=0,按照上表可以自行设数控制角度,这里说一下,这里是50us一次中断,那换算来就是精度只是5度,angle加一只能是增加5度。如果需要提高精度,可以改变每次中断时间。还有不要设置度数超过180度,这样会损害舵机。

	TL1 = 0xd2;		 
	TH1 = 0xff;
	if(count<angle)
	motor=1;
	else
	motor=0;
	count++;
	if(count>400)
	count=0;

电机使用

电机,是指依据电磁感应定律实现电能转换或传递的一种电磁装置。电机在电路中是用字母M表示,它的主要作用是产生驱动转矩,作为用电器或各种机械的动力源,发电机在电路中用字母G表示,它的主要作用是利用机械能转化为电能。
小时候玩四驱车的时候,把马达拆下来用电池去接的时候,已经知道怎样使用。正接正转,反接就反转。不可能在使用的时候,想他正反转就把线换过来,过于愚蠢。这里使用L298N驱动模块实现这个功能,还增加一个使能端,可以设置来调速。也可以使单片机能驱动电机。一个L298N模块可以控制两个电机。这里介绍一个的使用,另一个同理。

part1 1 0 x 1 0
paet2 0 1 x 1 0
ENA 1 1 0 1 1
舵机 正转 反转 停止 停止 停止

注x表示不管什么情况!
上程序讲解一波:
三个都已经位定义,下面就是电机正转程序,想要反转,就是part1=0;part2=1;ENA=1;

	ENA=1;
	part1=1;
	part2=0;

红外模块使用

这个没有什么说的,按照电路图焊好基本没有什么问题,就还剩下调基准。那个红外传感器有几点注意事项,两个红外传感器之间最好为0.5cm,因为黑线宽度不大,如果,间距太大会造成识别精度下降,小车行驶不稳。红外传感器尽量离黑线,就是地,距离小点,太大会受环境光线影响较大,导致识别出错。还有个人给个建议,传感器离小车远一点,这个可以通过生活场景讲解,司机行驶时,眼睛是往远处看,然后做出判断,传感器就是“眼睛”。所以传感器不要离前轮太近。建议不怕多,再来一个,传感器可以和前轮一起转动,这样小车会稳定点,识别也会增加实时性,小车转动幅度也可以大点。
51巡线小车
51巡线小车

上图为调基准方法,其他传感器同理调整。
ok,硬件到此已经完成,那究竟如何使用红外传感器来让小车自动巡线,看看下面程序就基本明白。

void A_TURN()	   //自动转弯
{
	date=P0;
	if(date==0x08|date==0x10|date==0x18)	 //直走
		angle=30;
	else if(date==0x04|date==0x0a)		 //左转5度
		angle=25;
	else if(date==0x20|date==0x30)		 //右转5度
		angle=35;
	else if(date==0x02|date==0x06)		 //左转10度
		angle=20;
	else if(date==0x40|date==0x60)		 //右转10度
		angle=40;
  	else if(date==0x01|date==0x03)		 //左转15度
		angle=15;
	else if(date==0x80|date==0xa0)		 //右转15度
		angle=45;
}
P0.0 P0.1 P0.2 P0.3 P0.4 P0.5 P0.6 P0.7 舵机
1 直走
1 直走
1 1 直走
1 左转5°
1 1 左转5°
1 右转5°
1 1 右转5°
1 左转10°
1 1 左转10°
1 右转10°
1 1 右转10°
1 左转15°
1 1 左转15°
1 右转15°
1 1 右转15°

上图程序就是根据上表编写而成,注意空格为0,就是低电平。1为高电平,在黑线上方,根据不同情况舵机不同反应。上图程序是在舵机顺时针转动(小车面向前方,舵机0°在左边,180°在右边)的情况下成立,舵机左右转动幅度不够30°可以酌情改变角度。
主体部分完工,还有调速简单说明,驱动不是有两个使能端,高电平起作用。只要在一个周期内控制电机作用时间,不就完成调速功能。

void adjust_speed()
{
	unsigned int count=600;
	if(P1=0xff)
	{
		for(;count>0;count--)
		{
			if(count>100){
			ENA=1;				   //两个驱动后轮
			ENB=1;
			}
			else 
			ENA=0;
			ENB=0;
		}
	}

	else if(P1=0xcf)
	{
		for(;count>0;count--)
		{
			if(count>300){
			ENA=1;
			ENB=1;
			}
			else {
			ENA=0;
			ENB=0;
			}
		}
	}
	else if(P1=0xbf)
	{
		for(;count>0;count--)
		{
			if(count>500){
			ENA=1;
			ENB=1;
			}
			else {
			ENA=0;
			ENB=0;
			}
		}
	}
}

最后的最后

所有模块的使用与程序样例都已经贴出来,如果还不会,那就是自己的问题,这已经是最详细的教程。最后的整合就不贴出来,自行整合。就是不断重复自动巡线,自行思考,不是很难。
51巡线小车