51单片机寻迹寻迹小车新手教程

        大家在做寻迹小车的时候可能会遇到许许多多的问题,比如小车该如何组装?组装之后该如何接线?接线之后又该如何编程,电源应该给多少右才能驱动电机呢?那么本次我将以三个方面给大家讲解(讲的不对可以辱骂,没必要放过)

        

                         (a)  四路寻迹模块                                       (b)L298N电机驱动模块

一、小车的组装&接线

        我们会用到三个模块51单片机最小系统板、四路寻迹模块、L298N电机驱动模块,这些根据这些名字在淘宝上都能购买(窝没钱只能买两个轮的)线太杂,嫌麻烦就没理了。

(1)L298N常见问题讲解

     (1.)  L298N这款芯片,如果你跟我一样只玩这种两个轮的小电机话只需要7.4v的电压就可以了,通过L298N给单片机供5v的电,然后从单片机再供5v的电给寻迹模块。至于为什么是7v?因为7v是L298n的一个突破口,如果你低于这个电压电机也能驱动,但会有点问题比如用着用着电池就没电了需要换电池,驱动也不稳定,四个电池只能玩2个小时左右。所以我们用两个18650电池变成7.4v(记得买带充电的)

1.供电控制:
        只需要在12V供电处接上7-12V电压,供电GND处与单片机共地即可,5V供电处会输出一个5V的电压,可以用于给单片机供电,做小车时最常用的就是这种方式。使用这种方式时,板载5V使能不用管。 

2.引脚功能:
  
           输出A、B:接受电流的输出使其前进后退(输出直流随便你怎么接)

           12V供电:接7V~12V电压,最高可承受30多V的电压(你小子别接反就不会坏的那种)

           供电GND:单片机接一根用于给单片机进行供地,给电源接一根用于造成电流回路

           5V供电:给单片机接一根进行供电,可以输出一个相对较稳定5v的电压

           通道使能端A、B:到这里你可能需要学习一个叫PWM的东西(会的话当我没说)

使能A控制左边电机反之则右边,只有当 “A或B使能” 为1的时候 “输出A或B” 才能输出所以你可以在适当的时间给他们“零”或者“一”来实现调速。(注意!每个使能都有两个插线口接前面一排就行了接单片机引脚)

           逻辑输入IN1、2、3、4:1~2为左边 3~4为右边 1和3是前进 2和4是后退。接在单片机的引脚上面控制左转右转

(2.)四路寻迹模块

四路寻迹模块供3.5v~5v电压利用单片机供电,按下图接就完了(这个就不过多讲自己学习一下下) 红外循迹模块原理还是很简单的,和许多光电传感器原理一样,当发射器发射出去的光被接收器接收到后,模块上对应的LED灯点亮,此时相应的输出引脚输出低电平;如果发射器发射的光没有被接收器接收到的话,那么LED灯不点亮,此时相应的输出引脚输出高电平。

灯没亮就是检测到你的 “黑胶布” 了或者距离太远没检测到东西,通过旋钮调距离(嘿嘿,看到那个黑胶布了没?是的,光滑的黑胶布可以让你的红外寻迹返回不了数据,买一个吧~)

灯亮就是检测到东西(自己去看看就不细讲了还是很好理解的,链接在下面)

http://t.csdnimg.cn/irh4N

二.小车代码讲解

 1.这是第一部分的代码这个代码是利用8421法去判断红外传感器他是不是检测到黑线。这里怕有的兄弟不是特别理解,那么我就举个栗子这个是重点自己看一下

if(count10us>=5)
	{	
			if((accept_left==0) && (accept_far_left==0) &&(accept_right==0)&&(accept_far_right==0)) //全部为零
			{
		testnum=3;
			}
			else if((accept_left==0) && (accept_far_left==0) &&(accept_right==0)&&(accept_far_right==1)) 
			{
		testnum=6;
			}
			else if((accept_left==0) && (accept_far_left==0) &&(accept_right==1)&&(accept_far_right==0)) 
			{
		testnum=6;
			}
			else if((accept_left==0) && (accept_far_left==0) &&(accept_right==1)&&(accept_far_right==1)) 
			{
		testnum=2;
			}
		  else 	if((accept_left==0) && (accept_far_left==1) &&(accept_right==0)&&(accept_far_right==0)) 
			{
		testnum=7;
			}
	  	else	if((accept_left==0) && (accept_far_left==1) &&(accept_right==0)&&(accept_far_right==1))
			{
		testnum=7;
			}
			else if((accept_left==0) && (accept_far_left==1) &&(accept_right==1)&&(accept_far_right==0)) 
			{
		testnum=3;
			}
			else if((accept_left==0) && (accept_far_left==1) &&(accept_right==1)&&(accept_far_right==1)) 
			{
		testnum=2;
			}
			else if((accept_left==1) && (accept_far_left==0) &&(accept_right==0)&&(accept_far_right==0)) 
			{
		testnum=7;
			}
			else if((accept_left==1) && (accept_far_left==0) &&(accept_right==0)&&(accept_far_right==1)) 
			{
		testnum=3;
			}
			else if((accept_left==1) && (accept_far_left==0) &&(accept_right==1)&&(accept_far_right==0)) 
			{
		testnum=6;
			}
			else if((accept_left==1) && (accept_far_left==0) &&(accept_right==1)&&(accept_far_right==1)) 
			{
		testnum=2;
			}
			else if((accept_left==1) && (accept_far_left==1) &&(accept_right==0)&&(accept_far_right==0)) 
			{
		testnum=1;
			}
			else if((accept_left==1) && (accept_far_left==1) &&(accept_right==0)&&(accept_far_right==1)) 
			{
		testnum=1;
			}
			else if((accept_left==1) && (accept_far_left==1) &&(accept_right==1)&&(accept_far_right==0)) 
			{
		testnum=1;
			}
			else if((accept_left==1) && (accept_far_left==1) &&(accept_right==1)&&(accept_far_right==1)) 
			{
		testnum=3;
			}
			else 
			{
			advance();
			}	
			count10us=0;
	}
		return testnum;
}

以上这个代码就是利用8421法来编写的,剩下的就是利用定时器控制使能端

三、全部代码的过程

都封装好了自己拿过去用吧,使能端自己在调一下我全部改了。

#include <reg52.h>
#include <Delay.h>
//小车轮胎
sbit IN1=P1^0;  //左轮 请进
sbit IN2=P1^1;  //左轮 后退
sbit IN3=P1^2;  //右轮 前进
sbit IN4=P1^3;	//右轮 后退
sbit ENA=P1^4;  //左使能端1
sbit ENA1=P1^5; //右使能端2
 //传感器检测
sbit accept_left=P2^0;  		//左侧检测
sbit accept_far_left=P2^1;  //极左边检测
sbit accept_right=P2^2;  		//右侧检测
sbit accept_far_right=P2^3; //极右侧检测

unsigned char num1;
unsigned int  Count_ENA,Count_ENA1,count10us,countsete=65534;
//检测输入
void stop() //全部停止 
{
			Count_ENA=80;
			Count_ENA1=80; //可以适当调节减少误差
			IN1=0;
			IN2=0;
			IN3=0;
			IN4=0;
		Delay100us(1);
}
void min_left() //小转左边检测
{
			Count_ENA=60;
			Count_ENA1=60;
			IN1=1;
			IN2=0;
			IN3=0;
			IN4=0;
}
void min_right() //小转右边检测
{
	Count_ENA=60;
			Count_ENA1=60;
			IN1=0;
			IN2=0;
			IN3=1;
			IN4=0;
}
void left() //大转左边检测
{	
			Count_ENA=70;
			Count_ENA1=70;
			IN1=0;
			IN2=1;
			IN3=1;
			IN4=0;
		
}

void right() //大转右边检测
	{
			Count_ENA=70;
			Count_ENA1=70;
			IN1=1;
			IN2=0;
			IN3=0;
			IN4=1;
			
}
	
void advance() //前进检测
{
			Count_ENA=80;
			Count_ENA1=80;
			IN1=1;
			IN2=0;
			IN3=1;
			IN4=0;
		Delay100us(1);
}

void  retreat()		//后退检测
{
			Count_ENA=65;
			Count_ENA1=65;
			IN1=0;
			IN2=1;
			IN3=0;
			IN4=1;
	Delay100us(1);
}

unsigned char test_trolley(unsigned char	testnum)    //寻迹判断 
{ 
	if(count10us>=5)
	{	
			if((accept_left==0) && (accept_far_left==0) &&(accept_right==0)&&(accept_far_right==0)) //全部为零
			{
		testnum=3;
			}
			else if((accept_left==0) && (accept_far_left==0) &&(accept_right==0)&&(accept_far_right==1)) 
			{
		testnum=6;
			}
			else if((accept_left==0) && (accept_far_left==0) &&(accept_right==1)&&(accept_far_right==0)) 
			{
		testnum=6;
			}
			else if((accept_left==0) && (accept_far_left==0) &&(accept_right==1)&&(accept_far_right==1)) 
			{
		testnum=2;
			}
		  else 	if((accept_left==0) && (accept_far_left==1) &&(accept_right==0)&&(accept_far_right==0)) 
			{
		testnum=7;
			}
	  	else	if((accept_left==0) && (accept_far_left==1) &&(accept_right==0)&&(accept_far_right==1))
			{
		testnum=7;
			}
			else if((accept_left==0) && (accept_far_left==1) &&(accept_right==1)&&(accept_far_right==0)) 
			{
		testnum=3;
			}
			else if((accept_left==0) && (accept_far_left==1) &&(accept_right==1)&&(accept_far_right==1)) 
			{
		testnum=2;
			}
			else if((accept_left==1) && (accept_far_left==0) &&(accept_right==0)&&(accept_far_right==0)) 
			{
		testnum=7;
			}
			else if((accept_left==1) && (accept_far_left==0) &&(accept_right==0)&&(accept_far_right==1)) 
			{
		testnum=3;
			}
			else if((accept_left==1) && (accept_far_left==0) &&(accept_right==1)&&(accept_far_right==0)) 
			{
		testnum=6;
			}
			else if((accept_left==1) && (accept_far_left==0) &&(accept_right==1)&&(accept_far_right==1)) 
			{
		testnum=2;
			}
			else if((accept_left==1) && (accept_far_left==1) &&(accept_right==0)&&(accept_far_right==0)) 
			{
		testnum=1;
			else if((accept_left==1) && (accept_far_left==1) &&(accept_right==0)&&(accept_far_right==1)) 
			{
		testnum=1;
			}
			else if((accept_left==1) && (accept_far_left==1) &&(accept_right==1)&&(accept_far_right==0)) 
			{
		testnum=1;
			}
			else if((accept_left==1) && (accept_far_left==1) &&(accept_right==1)&&(accept_far_right==1)) 
			{
		testnum=3;
			}
			else 
			{
			advance();
			}	
			count10us=0;
	}
		return testnum;
}
unsigned char select(unsigned char num2)
{
	num1=test_trolley(num1);
		switch(num1)
			{
			case 1:left();break; //左转
			case 2:right();break; //右转
			case 3:advance();break;//前进
			case 4:retreat();break;//后退
			case 5:stop(); break; //停止
			case 6:min_left(); break; //小左转检测
			case 7:min_right();break; //小右转检测
	}
			return num2;
}

void Timer0Init(void)		//1毫秒@11.0592MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x66;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;
	PT0=0;
	EA=1;
}

void timer0_routine() interrupt 1 //定时器里面在加一个变量分别用来表示ENA1和ENA2
{
	static unsigned int j,y,countnum;
	TL0 = 0x66;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	countnum++;
	countsete++;
		if(countnum>=2) //小车靠Pid误差运行 误差越大小车抖动的越快
{
	j++;
	y++;	
	if(j>=Count_ENA) {ENA=1;}
		else {ENA=0;}
	if(y>=Count_ENA1) {ENA1=1;}
		else {ENA1=0;}
		if(j==100)
	{
		j=0;
	}
		if(y==100)
	{
		y=0;
	}
	countnum=0;
}
	if(countsete>=65535)
	{
		countsete=65525;
		count10us++;
	}
}

  • 14
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值