51单片机——智能小车

文章目录

  • 一.小车需要的材料
  • 二.小车电机与L298N电机驱动的接线以及单片机接线
  • 三.L298N驱动电机的方法和代码
    • 3.1 L298N驱动电机方法
    • 3.2 L298N驱动电机代码
  • 四.串口或者蓝牙点击方式(HC_08)控制小车代码
  • 五.循迹小车基本原理
    • 5.1五路循迹模块图片
    • 5.2 循迹模块介绍
    • 5.3 循迹模块的原理
    • 5.4 赛道的宽度
    • 5.5 循迹小车代码
    • 5.6 循迹小车效果
  • 六.跟随小车
    • 6.1 红外避障模块图片
    • 6.2 红外避障模块原理
    • 6.3 跟随小车代码
    • 6.4 跟随小车效果

一.小车需要的材料

一个超声波模块,一个180度舵机模块,3节串联的18650电池盒和电池,一个L298N电机驱动模块,一个小面包板,51单片机,小车的模板 ,一个五路循迹循迹模块,两个红外避障模块。

二.小车电机与L298N电机驱动的接线以及单片机接线

图一中电机靠里面的线我称为电机上,靠地板那面我称为电机下,图2中是驱动电机与电机的连接方式,图3是单片机的接线,图4是连接实物图,图5是驱动电机的介绍图,电源的线尽量用硅胶线,不然容易烧。

图1
51单片机——智能小车_第1张图片

图2
51单片机——智能小车_第2张图片

图3
51单片机——智能小车_第3张图片

图4
51单片机——智能小车_第4张图片

图5
51单片机——智能小车_第5张图片

三.L298N驱动电机的方法和代码

3.1 L298N驱动电机方法

下图1的IN1——IN4分别对应OUT1——OUT4,IN1——IN4分别接在51单片机的P32,P33,P34,P35的IO口;L298N不调速情况下,是全速运行的,如果需要调速度,则使用PWM调速,占空比(高电平)越高,则速度越快,因为电机的转速不可能完全一样,会有摩擦力等等的干扰,所以如果不使用pid进行调速就只能用PWM,这个阶段用PWM即可,上图的L298N介绍图中,通道A使能对应的是IN1和IN2,通道使能B对应的是IN3和IN4,如下图2红圈位置接到单片机P05和P04的IO口中。

图1
51单片机——智能小车_第6张图片
图2
51单片机——智能小车_第7张图片

3.2 L298N驱动电机代码

//小车前进代码
#include 
#include "INTRINS.H"

sbit IN1=P3^2;
sbit IN2=P3^3;
sbit IN3=P3^4;
sbit IN4=P3^5;

void Go_Head()
{
	IN1=1;
	IN2=0;
	
	IN3=1;
	IN4=0;
}

void main()
{
	
	while(1)
	{
		Go_Head();
	}
}
//小车后退
#include 
#include "INTRINS.H"

sbit IN1=P3^2;
sbit IN2=P3^3;
sbit IN3=P3^4;
sbit IN4=P3^5;

void Go_Back()
{
	IN1=0;
	IN2=1;
	
	IN3=0;
	IN4=1;
}

void main()
{
	
	while(1)
	{
		Go_Back();
	}
}
//小车左转
#include 
#include "INTRINS.H"

sbit IN1=P3^2;
sbit IN2=P3^3;
sbit IN3=P3^4;
sbit IN4=P3^5;

void Go_Left()
{
	IN1=0;
	IN2=0;
	
	IN3=1;
	IN4=0;

}

void main()
{
	
	while(1)
	{
		Go_Left();
	}
}
//小车右转
#include 
#include "INTRINS.H"

sbit IN1=P3^2;
sbit IN2=P3^3;
sbit IN3=P3^4;
sbit IN4=P3^5;

void Go_Right()
{
	IN1=1;
	IN2=0;
	
	IN3=0;
	IN4=0;

}

void main()
{
	
	while(1)
	{
		 Go_Right();
	}
}
//使用PWM进行调速
#include 
#include "INTRINS.H"

sbit IN1=P3^2;
sbit IN2=P3^3;
sbit IN3=P3^4;
sbit IN4=P3^5;
sbit ENA=P0^5;
sbit ENB=P0^4;

unsigned char count,compare1,compare2;

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 Timer0Init(void)		//100微秒@11.0592MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xA4;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	EA=1;
	ET0=1;
	PT0=0;
}


void Go_Head()
{
	IN1=1;
	IN2=0;
	
	IN3=1;
	IN4=0;
}

void main()
{
	
	Timer0Init();
	while(1)
	{
		Go_Head();
	}
}

void Timer0_Rountime() interrupt 1
{
	TL0 = 0xA4;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	compare1=87;//左轮,100则速度最大
	compare2=89;//右轮,100则速度最大
	count++;
	if(count>=100) //10ms
	{
		count=0;
	}
	if(count<compare1)
	{
		ENA=1;
	}
	else
	{
		ENA=0;
	}
	if(count<compare2)
	{
		ENB=1;
	}
	else
	{
		ENB=0;
	}
}

四.串口或者蓝牙点击方式(HC_08)控制小车代码

如果用51最小开发板,车运行的时候,晶振可能抖动有问题会松,小车也运行不了。

Timer0.h

#ifndef TIMER0__H__
#define TIMER0__H__

void Timer0Init(void);

#endif

Timer0.c

#include 

sbit ENA=P0^5;
sbit ENB=P0^4;

unsigned char count;
unsigned char speed=100;

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

void Timer0_Rountime() interrupt 1
{
	TL0 = 0xA4;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	count++;
	if(count==100) //10ms
	{
		count=0;
	}
	if(count<speed)
	{
		ENA=1;
		ENB=1;
	}
	if(count>=speed)
	{
		ENA=0;
		ENB=0;
	}
	
}

Uart.h

#ifndef __MOTOR_H__
#define __MOTOR_H__

void UartInit(void);		//[email protected]


#endif

Uart.c

#include 
#include "Motor.h"
#include 

sfr AUXR=0X8E;

char buffer[3];



void UartInit()
{
	AUXR  =0x01;
	SCON  = 0x50;//配置串口1,REN使能不接收,串口模式
	TMOD &= 0x0F;//定时器模式
	TMOD |= 0x20;
	TH1   = 0xFD;//9600波特率的初值
	TL1   = 0xFD;
	TR1   = 1;//开始计时
	ET1   = 0;//禁止定时器中断
	ES    =1;//串口中断开启
	EA    =1;
}

void Uart_Rountime() interrupt 4
{
	static int i=0;
	char temp;
	
	if(RI==1)//中断处理函数,对于接收中断的响应
	{
		RI=0;
		temp=SBUF;
		
		if(temp=='M')
		{
			i=0;
		}
		buffer[i++]=temp;
		
		if(buffer[0]=='M')
		{
			switch(buffer[1])//第一次buffer[0]='M',还没到buffer[1],所以不执行switch,第二次上面赋予buffer[1]值的时候才进入switch
			{
				case '1':Go_Head();break;   
				case '2':Go_Back();break;
				case '3':Go_Left();break;
				case '4':Go_Right();break;
				case '5':Stop();break;
				case '6':increase();break;
				case '7':reduce();break;
			}
		}
		
		if(i==3)
		{
			i=0;
			memset(buffer,'\0',3);
		}
		
	}
}

Motor.h

#ifndef __MOTOR_H__
#define __MOTOR_H__

void Go_Left(void);
void Go_Right(void);
void Go_Back(void);
void Go_Head(void);
void Stop(void);
void increase(void);
void reduce(void);

#endif

Motor.c

#include 
#include "Timer0.h"

sbit IN1=P3^2;
sbit IN2=P3^3;
sbit IN3=P3^4;
sbit IN4=P3^5;

extern unsigned char speed;

void Go_Left()
{
	IN1=0;
	IN2=0;
	
	IN3=1;
	IN4=0;
	
}

void Go_Right()
{
	IN1=1;
	IN2=0;
	
	IN3=0;
	IN4=0;


}

void Go_Back()
{
	IN1=0;
	IN2=1;
	
	IN3=0;
	IN4=1;
	
	
}

void Go_Head()
{
	IN1=1;
	IN2=0;
	
	IN3=1;
	IN4=0;
	

}

void Stop()
{
	IN1=0;
	IN2=0;
	
	IN3=0;
	IN4=0;
}

void increase(void)//加速
{
	speed += 5; // 每次增加5
	if(speed >= 100) // 上限是100
	{
		speed = 100;
	}
}
	
void reduce(void)//减速
{
	speed -= 5; // 每次减少5
	if(speed <= 0) // 下限是0
	{
		speed = 0;
	}
}

main.c

#include 
#include "Uart.h"
#include "Motor.h"
#include "Timer0.h"



void main()
{
	UartInit();
	Timer0Init();
	while(1)
	{
		
	}
}

下面四张图就是蓝牙控制小车,先打开设置方向按钮,设置好后,再关闭,小车动的过程,如果是最小开发板,晶振很可能抖动出问题,容易点没反应,在插一次晶振就好了,用最小开发板串口进行通信的话,电池需要拆下来一个,等通信完成在插上去。
51单片机——智能小车_第8张图片
51单片机——智能小车_第9张图片
51单片机——智能小车_第10张图片
51单片机——智能小车_第11张图片

五.循迹小车基本原理

5.1五路循迹模块图片

51单片机——智能小车_第12张图片

5.2 循迹模块介绍

五路循迹模块探测距离短,所以调试的时候让他对着白色区域看看led全部是否亮着,亮着说明距离合适,传感器放的位置也很重要,尽量在下图照片位置,放很出的话效果不好。
51单片机——智能小车_第13张图片

5.3 循迹模块的原理

当探头的红外发射管发射光线经地面反射进入接收管。输出端输出(out)高电平,主板对应的led灯亮(OUT1-OUT4分别对应D1-D4的led灯)。如果地面有黑色区域将吸收光线,接收管接收不到光线输出端就会输出低电平,主板的led灯会不点亮。

5.4 赛道的宽度

除了买的赛道,如果想自己做的话,建议黑线两个手指的宽度大小,不然传感器容易反应不过来跑飞出去,然后电压的大小也会影响小车循迹效果,可以买个充电器给电池充电,充满了在调试。
51单片机——智能小车_第14张图片

5.5 循迹小车代码

如果用51最小开发板,车运行的时候,晶振可能抖动有问题会松,小车也运行不了

main.c

#include 
#include "Motor.h"
#include "Timer0.h"
#include	"xunji.h"



void main()
{
	Timer0Init();
	while(1)
	{
			xunji();
	}
}

Timer0.h

#ifndef TIMER0__H__
#define TIMER0__H__

void Timer0Init(void);

#endif

Timer0.c

#include 

sbit ENA=P0^5;
sbit ENB=P0^4;


unsigned char i,j;
unsigned char PWMA,PWMB;//A是左轮,B是右轮

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

void Timer0_Rountime() interrupt 1
{
	TL0 = 0xA4;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	i++;
	j++;
	if(i<PWMA)
	{
		ENA=1;
	}
	else
	{
		ENA=0;
		if(i>=100)
		{
			i=0;
		}
	}
	if(j<PWMB)
	{
		ENB=1;
	}
	else
	{
		ENB=0;
		if(j>=100)
		{
			j=0;
		}
	}
}

Motor.h

#ifndef __MOTOR_H__
#define __MOTOR_H__

void Go_Left(void);
void Go_Left1(void);
void Go_Right(void);
void Go_Right1(void);
void Go_Head(void);
void Stop(void);

#endif

Motor.c

#include 
#include "Timer0.h"

sbit IN1=P3^2;
sbit IN2=P3^3;
sbit IN3=P3^4;
sbit IN4=P3^5;

extern unsigned char PWMA,PWMB;

void Go_Left()//正转的速度大于反转
{
	IN1=0;
	IN2=1;//左轮反转
	PWMA=35;
	
	IN3=1;
	IN4=0;
	PWMB=50;//右轮正转
}

void Go_Left1()
{
	IN1=0;
	IN2=1;
	PWMA=50;
	
	IN3=1;
	IN4=0;
	PWMB=65;
}

void Go_Right()
{
	IN1=1;
	IN2=0; //左轮正转
	PWMA=50;//左边速度
	
	IN3=0;
	IN4=1; //右轮反转
	PWMB=35;//右边速度
}

void Go_Right1()
{
	IN1=1;
	IN2=0;
	PWMA=65;
	
	IN3=0;
	IN4=1;
	PWMB=50;
}

void Go_Head()
{
	IN1=1;
	IN2=0;
	PWMA=25;
	
	IN3=1;
	IN4=0;
	PWMB=25;
}

void Stop()
{
	IN1=0;
	IN2=0;
	PWMA=0;
	
	IN3=0;
	IN4=0;
	PWMB=0;
}

xunji.h

#ifndef __XUNJI_H__
#define __XUNJI_H__

void xunji(void);

#endif

xunji.c

#include 
#include "Motor.h"

sbit D1=P1^1;
sbit D2=P1^2;
sbit D3=P1^3;
sbit D4=P1^4;
sbit D5=P1^5;


void xunji()
{
	unsigned char flag =0;
	if(D1 ==1 && D2 == 1 && D3==0 && D4 ==1 && D5 ==1)//中间检测到黑线
	{
		flag=0;
	}
	if(D1 ==1 && D2 == 1 && D3==1 && D4 ==1 && D5 ==1)//全部未检测到黑线
	{
		flag=0;
	}
	if(D1 ==1 && D2 == 0 && D3 ==1 && D4 ==1 && D5==1)//左边内测侧检测到黑线,小车缓慢向左移动
	{
		flag=1;
	}
	if(D1 ==1 && D2 == 0 && D3 ==0 && D4 ==1 && D5==1)//左边内测和中间侧检测到黑线,小车缓慢向左移动
	{
		flag=1;
	}
	if(D1 ==0 && D2 == 1 && D3 ==1 && D4 ==1 && D5==1)//左边外测侧检测到黑线,小车大幅度向左移动
	{
		flag=2;
	}
	if(D1 ==0 && D2 == 0 && D3 ==1 && D4 ==1 && D5 == 1)//左边内外侧检测到黑线,小车大幅度向左移动
	{
		flag=2;
	}
	if(D1 ==0 && D2 == 0 && D3 ==0 && D4 ==1 && D5 == 1)//左边内外侧和中间检测到黑线,小车大幅度向左移动
	{
		flag=2;
	}
	if(D1 ==1 && D2 == 1 && D3 ==1 && D4 ==0 && D5 ==1)//右边内测侧检测到黑线,小车缓慢向右移动
	{
		flag=3;
	}
	if(D1 ==1 && D2 == 1 && D3 ==0 && D4 ==0 && D5 ==1)//右边内测和中间侧检测到黑线,小车缓慢向右移动
	{
		flag=3;
	}
	if(D1 ==1 && D2 ==1 && D3 ==1 && D4 ==1 && D5 ==0)//右边外侧检测到黑线,小车大幅度向右移动
	{
		flag=4;
	}
	if(D1 ==1 && D2 == 1 && D3 ==1 && D4 ==0 && D5 ==0)//右侧内外检测到黑线,小车大幅度右转
	{
		flag=4;
	}
	if(D1 ==1 && D2 == 1 && D3 ==0 && D4 ==0 && D5 ==0)//右侧内外和中间检测到黑线,小车大幅度右转
	{
		flag=4;
	}
	if(D1 ==0 && D2 == 0 && D3 ==0 && D4 ==0 && D5 ==0)//全部检测到黑线时,停车
	{
		flag=5;
	}
	switch(flag)
	{
	case 0:Go_Head();break;
	case 1:Go_Left();break;
	case 2:Go_Left1();break;
	case 3:Go_Right();break;
	case 4:Go_Right1();break;
	default:Stop();break;
	}
}

5.6 循迹小车效果

六.跟随小车

6.1 红外避障模块图片

51单片机——智能小车_第15张图片

6.2 红外避障模块原理

(1).上面有旋转按钮可以调节红外避障的灵敏度(红外发射距离),当发出红外线时,返回红外线的话,模块输出低电平,当发射红外线时,没有返回红外线的话,模块输出高电平。
(2).左边跟随模块能返回红外,输出低电平,右边不能返回,输出高电平,说明物体在左边,需要左转,右边跟随模块能返回红外,输出低电平,左边不能返回,输出高电平,说明物体在右边,需要右转。

6.3 跟随小车代码

mian.c

#include 
#include "Motor.h"

sbit leftsensor=P1^7; //左边红外模块
sbit rightsensor=P1^6;//右边红外模块


void main()
{
	while(1)
	{
		if(leftsensor == 0 && rightsensor == 0)
		{
			Go_Head();
		}	
		if(leftsensor == 1 && rightsensor == 0)
		{
			Go_Right();
		}
		if(leftsensor == 0 && rightsensor == 1)
		{
			Go_Left();
		}
		if(leftsensor == 1 && rightsensor == 1)
		{
			Stop();
		}
	}
}

Motor.c

#include 

sbit IN1=P3^2;
sbit IN2=P3^3;
sbit IN3=P3^4;
sbit IN4=P3^5;


void Go_Left()
{
	IN1=0;
	IN2=0;
	
	IN3=1;
	IN4=0;
	
}

void Go_Right()
{
	IN1=1;
	IN2=0;
	
	IN3=0;
	IN4=0;


}

void Go_Head()
{
	IN1=1;
	IN2=0;
	
	IN3=1;
	IN4=0;
	

}

void Stop()
{
	IN1=0;
	IN2=0;
	
	IN3=0;
	IN4=0;
}

Motor.h

#ifndef __MOTOR_H__
#define __MOTOR_H__

void Go_Left(void);
void Go_Right(void);
void Go_Head(void);
void Stop(void);

#endif

6.4 跟随小车效果


待更新…

你可能感兴趣的:(51单片机,mongodb,嵌入式硬件)