自动循迹小车毕业设计 下载本文

自动循迹小车

旦检测到某个I/O口有信号,即进入判断处理程序,先确定4个探测器中的哪一个探测到了黑线,如果左面第一级传感器或者左面第二级传感器探测到黑线,即小车左半部分压到黑线,车身向右偏出,此时应使小车向左转;如果是右面第一级传感器或右面第二级传感器探测到了黑线,即车身右半部压住黑线,小车向左偏出了轨迹,则应使小车向右转。在经过了方向调整后,小车再继续向前行走,并继续探测黑线重复上述动作。循迹流程图如图4-2所示

启动循迹模式 探测黑线 N 是否检测到黑线 Y 判断处理程序 向左转 Turn _left2 向左转 Turn _left1 向右转 Turn_ right1 向右转 Turn_ Lright2 继续前进

图4-2循迹流程图

由于第二级方向控制为第一级的后备,则两个等级间的转向力度必须相互配合。第二级通常是在超出第一级的控制范围的情况下发生作用,它也是最后一层保护,所以它必须要保证小车回到正确轨迹上来,则通常使第二级转向力度大于第一级,即Turn_left2 > Turn_left1,Turn_right2 > Turn_right1 (其中

20

自动循迹小车

Turn_left2,Turn_left1, Turn_right2 , Turn_right1为小车转向力度,其大小通过改变单片机输出的占空比的大小来改变),具体数值在实地实验中得到。

4.4中断程序流程图

这里利用的是51单片机的T0定时计数器,从而让单片机P0口的P0.4和P0.5引脚输出占空比不同的方波, 然后经驱动芯片放大后控制直流电机。定时计数器若干时间(比如0.1ms)比如中断一次, 就使P0.4或P0.5产生一个高电平或低电平。中断程序流程图如图4-3所示

开始 定时器赋初值 技术变量赋值t=0 Y 计数值t<占空比? N P0.4和P0.5 输出高电平 P0.4和P0.5 输出低电平 计数变量t加1

结束 图4-3中断程序流程图

21

自动循迹小车

4.5单片机测序

#include

#define uchar unsigned char #define uint unsigned int

unsigned char zkb1=0 ; //**左边电机的占空比**// unsigned char zkb2=0 ; //**右边电机的占空比**// unsigned char t=0; //**定时器中断计数器**// sbit RSEN1=P1^0; sbit RSEN2=P1^1; sbit LSEN1=P1^2; sbit LSEN2=P1^3; sbit IN1=P0^0; sbit IN2=P0^1; sbit IN3=P0^2; sbit IN4=P0^3; sbit ENA=P0^4; sbit ENB=P0^5;

//****************延时函数****************// void delay(int z) { while (z--); }

//**********初始化定时器,中断***********// void init() { TMOD=0x01;

TH0=(65536-100)/256; TL0=(65536-100)%6; EA=1; ET0=1; TR0=1; }

22

自动循迹小车

//***********中断函数+脉宽调制***********// void timer0() interrupt 1 { if(t

t++;

if(t>=100) {t=0;} }

//******************直行******************// void qianjin() { zkb1=30; zkb2=30; }

//***************左转函数1***************// void turn_left1() { zkb1=0; zkb2=50; }

//***************左转函数2***************// void turn_left2() { zkb1=0; zkb2=60; }

//***************右转函数1***************// void turn_right1()

23

自动循迹小车

{ zkb1=50; zkb2=0; }

//***************右转函数2***************// void turn_right2() { zkb1=60; zkb2=0; }

//***************循迹函数*****************// void xunji() { uchar flag;

if((RSEN1==1)&&(RSEN2==1)&&(LSEN1==1)&&(LSEN2==1)) { flag=0; }//*******直行*******//

else if((RSEN1==0)&&(RSEN2==1)&&(LSEN1==1)&&(LSEN2==1)) { flag=1;} //***左偏1,右转1***//

else if((RSEN1==0)&&(RSEN2==0)&&(LSEN1==1)&&(LSEN2==1)) { flag=2;} //***左偏2,右转2***//

else if((RSEN1==1)&&(RSEN2==1)&&(LSEN1==0)&&(LSEN2==1)) { flag=3; }//***右偏1,左转1***//

else if((RSEN1==1)&&(RSEN2==1)&&(LSEN1==0)&&(LSEN2==0)) { flag=4; }//***右偏2,左转2***// switch (flag)

{ case 0:qianjin(); break;

case 1:turn_right1(); break; case 2:turn_right2(); break; case 3:turn_left1(); break; case 4:turn_left2();

24