89C52RC单片机学习-循迹小车

寻迹小车

关键原理:寻迹小车跟随黑线行驶,在小车头两边各自安装一个红外模块,利用的车头的红外传感器(TCRT5000)遇到深色物体无法正常返回信号的特性,有返回信号时红外模块输出高电平指示灯不亮,无信号返回输出低电平指示灯亮起。
TCRT5000 模块如下图
TCRT5000

下面是自己的代码

关键子程序trackcar.c


#include "reg52.h"
#include "motor.h"

sbit LeftSersor =P2^6;
sbit RightSersor =P2^7;


void TrackCar()
{
//左边探测器和右边探测器都返回信号,保持直线。
		if (LeftSersor==0&&RightSersor==0)	
		{
	    ForWard();
		}	
//如果左边有黑线,右边没有黑线,左转。
		else if(LeftSersor==1&&RightSersor==0)
		{
				RightWard();
		}
//如果左边没有黑线,右边有黑线,右转。		
		else if(LeftSersor==0&&RightSersor==1)
		{
		LeftWard();
		}
		//如果两边都是黑线停止
		else if(LeftSersor==1&&RightSersor==1)
		{
			Stop();
		}
}

主程序中还添加了一个发送数据控制小车的功能

main.c

//该程序中新增了两个红外模块,这两个模块安装在车头,模块探测方向是在地面,利用红外模块遇到黑色输出低电平的特性,设计出令小车跟随黑线的程序。

#include "motor.h"
#include "reg52.h"
#include "Usart_Init.h"
#include "delay.h"
#include "intrins.h"
#include "string.h"
#include "follow.h"
#include "trackcar.h" 

#define bufferlen 12
char buffer[12];

void uart_Init()//串口初始化
{
SCON=0X50;//设置串口的寄存器工作模式

TMOD &=0X0F;//定时器1的工作模式
TMOD |=0X2F;
TH1=0XFD;//设置波特率9600
TL1=TH1;
TR1=1;//定时器开始计时
EA=1;//总中断
ES=1;//串口中断
}

void main ()
{
		//串口的初始化设置
		uart_Init();
		//开启中断
		interrupt_START();
	
	 // InitTimer0();
   // Timer1Init();
		//LeftSpeed=33;
	  //RightSpeed=40;
 		while(1)
		{
		  TrackCar();
		}
}


//由模块Tx发出的有两种指令,1,AT功能设置指令的反馈 2,服务器串口发送的数据传到WiFi模块,再由模块发给单片机
void uart_Interrupt () interrupt 4   //中段函数。每次接收到WiFi模块发过来的数据进入中断
{
  static int i=0; //只在开始的时候执行一次
  if (RI)//当串口中断事件为接收到数据
		{
	  RI=0;
	  if(i==12)//不超过十二个字符
		{
			i=0;
		}
		buffer[i++]=SBUF;//全局变量接收WiFi模块Tx发送过来的数据
		
		if(buffer[i-1]=='M')//第一个数据M
		{
			buffer[0] =buffer[i-1];//buffer[i-1]才是刚才接收的数据
			i=1;
		}
		if (buffer[1]=='F')	//当接受的数据为“MF”
		{
		    ForWard();
			Delay500ms()	;
			memset(buffer, '\0', bufferlen);
		}
		if (buffer[1]=='B')//当接受的数据为“MB”
		{
			BackWard();
		    Delay500ms()	;
			memset(buffer, '\0', bufferlen);
		}

		if (buffer[1]=='L')//当接受的数据为“ML”
		{
	  	    LeftWard();
			Delay200ms();;
			memset(buffer, '\0', bufferlen);
		}
		if (buffer[1]=='R')//当接受的数据为“MR”
		{
	  	    RightWard();
		    Delay200ms();;
			memset(buffer, '\0', bufferlen);
		}	
		}
 	
}

下面是电机的子程序,因为电机的速度太快,程序中用了软件延时的方式控制PWM,比较粗暴,比较高级的办法是用T0和T2
分别控制左右轮,T1继续用于串口。
motor.c

//通过软件延时控制电机PWM,减少电机的供电时间

#include "reg52.h"
#include "intrins.h"
#include "delay.h"
//管脚配置
//右轮
sbit RightA=P3^3;
sbit RightB=P3^2;
//左轮
sbit LeftA=P3^4;
sbit LeftB=P3^5;

void ForWard()//前进
{
	  	RightA=0;
		  RightB=0;
			LeftA=0;
			LeftB=0;
      Delay50ms();
	    Delay50ms();
			RightA=1;
			RightB=0;
			LeftA=1;
			LeftB=0;
	    Delay50ms();
		
}
void BackWard()//后退
{
			RightA=0;
			RightB=1;
			LeftA=0;
			LeftB=1;
}

void LeftWard()//左转
{
			RightA=0;
			RightB=0;
			LeftA=0;
			LeftB=0;
			Delay50ms();
	    Delay50ms();
			RightA=1;
			RightB=0;
			LeftA=0;
			LeftB=0;
	    Delay50ms();
}
void RightWard()
{
			RightA=0;
			RightB=0;
			LeftA=0;
			LeftB=0;
			Delay50ms();
	    Delay50ms();
			RightA=0;
			RightB=0;
			LeftA=1;
			LeftB=0;
	    Delay50ms();
}

void Stop()
{
			RightA=0;
			RightB=0;
			LeftA=0;
			LeftB=0;
}

下面是软件延时子程序
delay.c

# include "intrins.h"

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

	i = 180;
	j = 73;
	do
	{
		while (--j);
	} while (--i);
}

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

	_nop_();
	i = 15;
	j = 2;
	k = 235;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

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

	_nop_();
	i = 4;
	j = 129;
	k = 119;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

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

	_nop_();
	i = 2;
	j = 103;
	k = 147;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

头文件:
trackcar.h

void TrackCar();

motor.h

void ForWard();
void BackWard();
void LeftWard();
void RightWard();
void Stop();

delay.h

void Delay2000ms();
void Delay50ms();
void Delay200ms();
void Delay100ms();

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值