51单片机——循迹小车源码

/***********************头文件*************************/
#include <REGX52.H>
#include <intrins.h>


/***********************单片机初始化引脚****************/
sbit IN1 = P1^4;
sbit IN2 = P1^3;
sbit IN3 = P1^2;
sbit IN4 = P1^1;
sbit ENA = P1^5;       //调速引脚
sbit ENB = P1^0;       //调速引脚
sbit Lsen = P2^7;
sbit Rsen = P2^4;
/****************初始化变量(标志位)***********************/
unsigned int compareA = 80,compareB = 80;    //小车左轮的速度compareA与右轮的速度compareB(0~100)
unsigned int counter = 0;    //卡定时次数的标志位
unsigned int a = 0;    //卡循迹同时扫到黑线的标志位


/***********************要用到的自定义函数******************/
void Delay(unsigned int xms)		//@11.0592MHz,延时函数(多少毫秒)
{
	while(xms)
	{
		unsigned char i, j;
		_nop_();

		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}


void go_ahead()
{
	compareA = 80;
	compareB = 80;
	IN1 = 0;
	IN2 = 1;
	IN3 = 1;
	IN4 = 0;
}

/**********速度慢的执行函数****************/
//void go_ahead_1()
//{
//	compareA = 10;
//	compareB = 10;
//	IN1 = 0;
//	IN2 = 1;
//	IN3 = 1;
//	IN4 = 0;
//}
/************等到最后停不住启动***********/



void turn_left()    //左转函数
{
	compareA = 80;
	compareB = 80;
	IN1 = 0;
	IN2 = 1;
	IN3 = 0;
	IN4 = 1;
}

void turn_right()   //右转函数
{
	compareA = 80;
	compareB = 80;
	IN1 = 1;
	IN2 = 0;
	IN3 = 1;
	IN4 = 0;

}

void stop()    //停止函数
{
	ENA = 0;
	ENB = 0;
}

void xunji()  //循迹函数
{
		if(Lsen == 1 && Rsen == 0)   //这里是循迹扫到黑为1,白为0;也有可能相反,自己去试
		{
			turn_left();   //普通与直角弯
		}
		else if(Lsen == 0 && Rsen == 1)
		{
			turn_right();   //普通与直角弯
		}
		else if( a == 0 && Lsen == 1 && Rsen == 1)
		{
			turn_left();   //“T”字形,右拐也行
			a++;
		}
		else if( a == 1 && Lsen == 1 && Rsen == 1)
		{
			go_ahead();  //也可重新定义一个速度慢的执行函数go_ahead_1()
			a++;
		}
		else if(a == 2 && Lsen == 1 && Rsen == 1)
		{
			stop();
			Delay(200);//调用延时函数
			turn_right(); 
			Delay(500);//调用延时函数,自己调节最后的转角,可能不是500,不触及边线即可
			stop();
			Delay(1000);//保证小车停稳
		}
		else
		{
			go_ahead();//除了以上特殊情况,直行即可
		}
}

/**************************************用于小车调速的定时器*********************************/
void Timer0_Init(void)		//每100微秒进一次中断
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x9C;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;	//定时器0开始计时
	EA = 1;
	ET0 = 1;
	PT0 = 0;
}


void Timer0_Routine() interrupt 1   //中断服务函数
{
	TL0 = 0x9C;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	counter++;
	if(counter == 100)  //100次为一个周期,即100*100=10000us=10ms为一个PWM周期
	{
		counter = 0;
	}
	if(counter > compareA)  
	{
		ENA = 0;
	}
	else if(counter <= compareA)
	{
		ENA = 1;
	}
	else if(counter > compareB)
		{
			ENB = 0;
		}
	else if(counter <= compareB)
		{
			ENB = 1;
		}	
	
}

/****************主函数(程序开始的地方)***********************/
void main()
{
	Timer0_Init();//初始化定时器0
	while(1)
	{
		xunji();
	}

}


 

  • 28
    点赞
  • 142
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值