智能小车程序.docx
《智能小车程序.docx》由会员分享,可在线阅读,更多相关《智能小车程序.docx(13页珍藏版)》请在冰豆网上搜索。
智能小车程序
#include"reg52.h"
#definedet_Dist2.55//单个脉冲对应的小车行走距离,其值为车轮周长/4
#defineRD9//小车对角轴长度
#definePI3.1415926
#defineANG_9090
#defineANG_90_T102
#defineANG_180189
/*============================全局变量定义区============================*/
sbitP10=P1^0;//控制继电器的开闭
sbitP11=P1^1;//控制金属接近开关
sbitP12=P1^2;//控制颜色传感器的开闭
sbitP07=P0^7;//控制声光信号的开启
sbitP26=P2^6;//接收颜色传感器的信号,白为0,黑为1
sbitP24=P2^4;//左
sbitP25=P2^5;//右接收左右光传感器的信号,有光为0
unsignedcharmType=0;//设置运动的方式,0向前1向左2向后3向右
unsignedcharDirection=0;//小车的即时朝向0朝上1朝左2朝下3朝右
unsignedsX=50;unsignedcharsY=0;//小车的相对右下角的坐标CM(sX,sY)
unsignedcharStartTask=0;//获得铁片后开始执行返回卸货任务,StartTask置一
unsignedcharInter_EX0=0;//完成一个完整的任务期间只能有一次外部中断
//Inter_EX0记录外部中断0的中断状态
//0动作最近的前一次未中断过,
//1动作最近的前一次中断过
unsignedcharcntIorn=0;//铁片数
unsignedcharbkAim=2;//回程目的地,0为A仓库,1为B仓库,2为停车场,
//(在MAIN中接受铁片颜色判断传感器的信号来赋值)
unsignedcharLight_Flag=0;//进入光引导区的标志
(1)
unsignedintcntTime_5Min=0;//时间周期数,用于T0精确定时
unsignedintcntTime_Plues=0;//霍尔开关产生的脉冲数
/*------------------------------------------------*/
/*-----------------通用延迟程序-------------------*/
voiddelay(unsignedinttime)//time*0.5ms延时
{
unsignedinti,j;
for(j=0;j{for(i=0;i<60;i++){;}}}/*-----------------------------------------------*//*-------------------显示控制模块----------------*//*-----------------------------------------------*//*数码管显示,显示铁片的数目(设接在P0,共阴)*/voidDisplay(unsignedcharn){charNumb[12]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x37,0x77};//0,1,2,3,4,5,6,7,8,9P0=Numb[n];}/*-----------------------------------------------*//*-------------------传感器模块------------------*//*-----------------------------------------------*//*光源检测程序:*//*用于纠正小车运行路线的正确性*/unsignedcharLightSeek(){voidDisplay(unsignedchar);bitl,r;l=P24;r=P25;if(l==0&&r==1){//Display(1);return(3);//偏左,向右开}if(r==0&&l==1){//Display(3);return(1);//偏右,向左开}if((l==1&&r==1)||(l==0&&r==0)){//Display(9);return(0);//没有偏离,前进}}/*铁片检测程序:*//*判断铁片的颜色,设定bkAim,0为A仓库,1为B仓库,2为停车场*/voidIornColor(){delay(4000);bkAim=(int)(P26);Display((int)(P26)+2);}/*-----------------------------------------------*//*------------------运动控制模块-----------------*//*-----------------------------------------------*//*====基本动作层:完成基本运动动作的程序集====*//*运动调整程序:*//*对小车的运动进行微调*/voidctrMotor_Adjust(unsignedchart){if(t==0){P2=P2&240|11;//用来解决两电机不对称的问题delay(6);}if(t==3){P2=P2&250;//向左走delay(1);}if(t==1){P2=(P2&245);delay(1);//向右走}P2=((P2&240)|15);delay(10);}/*直走程序:*//*控制小车运动距离,dist为运动距离(cm),type为运动方式(02)*//*只改变小车sX和sY的值而不改变Direction的值.*/voidctrMotor_Dist(floatdist,unsignedchartype){unsignedchart=0;mType=type;P2=((P2&240)|15);cntTime_Plues=(int)(dist/det_Dist);while(cntTime_Plues){if(Inter_EX0==1&&StartTask==0){cntTime_Plues=0;break;}if(Light_Flag==1)t=LightSeek();if(type==0)//向前走{P2=P2&249;delay(40);ctrMotor_Adjust(t);}if(type==2)//向后退{P2=P2&246;delay(50);ctrMotor_Adjust(t);}P2=((P2&240)|15);if(mType==2)delay(60);//刹车制动0.5mselsedelay(75);}}/*拐弯程序:*//*控制小车运动角度,type为运动方式(13)*//*只改变小车Direction的值而不改变sX和sY的值*/voidctrMotor_Ang(unsignedcharang,unsignedchartype,unsignedchardir){unsignedchari=0;mType=type;P2=((P2&240)|15);cntTime_Plues=(int)((PI*RD*90/(180*det_Dist)*1.2)*ang/90);while(cntTime_Plues){if(Inter_EX0==1&&StartTask==0){cntTime_Plues=0;break;}if(type==1)//向左走{P2=P2&250;delay(100);ctrMotor_Adjust(0);}if(type==3)//向右走{P2=P2&245;delay(100);ctrMotor_Adjust(0);}P2=((P2&240)|15);delay(50);//刹车制动0.5ms}if(!(Inter_EX0==1&&StartTask==0)){Direction=dir;}}/*====基本路线层:描述小车基本运动路线的程序集====*//*当小车到达仓库或停车场时,放下铁片或停车(0,1为仓库,2为停车场)*/voidrchPlace(){unsignedinttime,b,s,g;time=(int)(cntTime_5Min*0.065535);//只有一个数码管时,轮流显示全过程秒数个十百b=time%100;s=(time-b*100)%100;g=(time-b*100-s*10)%10;if(bkAim==2){//到达停车场了,停车EA=0;P2=((P2&240)|15);while(1){Display(10);//Ndelay(2000);Display(cntIorn);delay(2000);Display(11);//Adelay(2000);Display(b);delay(2000);Display(s);delay(2000);Display(g);delay(2000);}}else{if(Inter_EX0==1&&StartTask==1)P10=0;//到达仓库,卸下铁片}}/*无任务模式:*//*设置小车的固定运动路线,未发现铁片时的运动路线*/voidBasicRoute(){//Light_Flag=1;ctrMotor_Dist(153,0);//Light_Flag=0;ctrMotor_Ang(ANG_90,1,1);ctrMotor_Dist(100-sX,0);ctrMotor_Dist(125,2);ctrMotor_Dist(73,0);ctrMotor_Ang(ANG_90,1,2);//Light_Flag=1;ctrMotor_Dist(153,0);//Light_Flag=0;ctrMotor_Ang(ANG_180,1,0);rchPlace();}/*任务模式:*//*设置小车的发现铁片后的运动路线*/voidTaskRoute(){//基本运行路线表,记载拐弯0向前1左拐2向后3右拐,正读去A区;反读去B区StartTask=1;ctrMotor_Ang(ANG_90_T,1,2);if(bkAim==1)//仓库A{ctrMotor_Dist(10,0);P2=((P2&240)|15);delay(60);ctrMotor_Ang(ANG_90_T,1,3);ctrMotor_Dist(100-sX,2);ctrMotor_Ang(ANG_90_T,1,2);Light_Flag=1;ctrMotor_Dist(153,2);Light_Flag=0;//ctrMotor_Ang(208,1,0);}elseif(bkAim==0)//仓库B{ctrMotor_Dist(10,0);P2=((P2&240)|15);delay(60);ctrMotor_Ang(ANG_90_T,1,3);ctrMotor_Dist(100-sX,0);ctrMotor_Ang(ANG_90_T,1,0);Light_Flag=1;ctrMotor_Dist(153,2);Light_Flag=0;//ctrMotor_Ang(208,1,0);}delay(5000);rchPlace();}/*---------------------------------------------*//*-------------------主程序段------------------*//*---------------------------------------------*/voidmain(){delay(4000);P2=0xff;//初始化端口P07=0;P1=0;TMOD=0x01;//初始化定时器0/1及其中断TL0=0;TH0=0;TR0=1;ET0=1;ET1=1;IT0=1;//初始化外部中断EX0=1;IT1=1;EX1=1;EA=1;P11=1;while(1){Display(cntIorn);bkAim=2;BasicRoute();if(Inter_EX0==1){TaskRoute();//按获得铁片后的路线运动IE0=0;EX0=1;}Inter_EX0=0;}}/*----------------------------------------------------*//*----------------------中断程序段--------------------*//*----------------------------------------------------*//*定时器0中断程序:*//*当时间过了5分钟,则就地停车并进入休眠状态*/voidtmOver(void)interrupt1{cntTime_5Min++;TL0=0;TH0=0;if(cntTime_5Min>=4520){Display(5);P2=((P2&240)|15);EA=0;//停车程序P07=1;delay(4000);PCON=0X00;while(1);}}/*外部中断0中断程序:*//*发现铁片,发出声光信号并将铁片吸起,发光二极管和蜂鸣器*//*并联在一起(设接在P07).0为A仓库,1为B仓库,2为停车场*/voidfndIorn(void)interrupt0{unsignedchari;P10=1;P2=((P2&240)|15);//停车P07=1;delay(1000);//刹车制动0.5msP07=0;Inter_EX0=1;cntIorn++;Display(cntIorn);for(i=0;i<40;i++){P2=P2&249;delay(2);P2=((P2&240)|15);delay(2);}P2=P2&249;delay(100);P2=((P2&240)|15);//停车IornColor();//判断铁片黑白,设置bkAimfor(i=0;i<95;i++){P2=P2&249;delay(3);P2=((P2&240)|15);delay(2);}P2=((P2&240)|15);//停车delay(4000);//把铁片吸起来EX0=0;}/*外部中断1中断程序:*//*对霍尔开关的脉冲记数,对小车的位置进行记录,以便对小车进行定位*/voidstpMove(void)interrupt2{cntTime_Plues--;if(Direction==0)//向上{if(mType==0)sY+=det_Dist;elseif(mType==2)sY-=det_Dist;}elseif(Direction==1)//向左{if(mType==0)sX+=det_Dist;elseif(mType==2)sX-=det_Dist;}elseif(Direction==2)//向下{if(mType==0)sY-=det_Dist;elseif(mType==2)sY+=det_Dist;}elseif(Direction==3)//向右{if(mType==0)sX-=det_Dist;elseif(mType==2)sX+=det_Dist;}
for(i=0;i<60;i++)
{;}
}
/*-----------------------------------------------*/
/*-------------------显示控制模块----------------*/
/*数码管显示,显示铁片的数目(设接在P0,共阴)*/
voidDisplay(unsignedcharn)
charNumb[12]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x37,0x77};//0,1,2,3,4,5,6,7,8,9
P0=Numb[n];
/*-------------------传感器模块------------------*/
/*光源检测程序:
*/
/*用于纠正小车运行路线的正确性*/
unsignedcharLightSeek()
{voidDisplay(unsignedchar);
bitl,r;
l=P24;
r=P25;
if(l==0&&r==1)
//Display
(1);
return(3);//偏左,向右开
if(r==0&&l==1)
//Display(3);
return
(1);//偏右,向左开
if((l==1&&r==1)||(l==0&&r==0))
{//Display(9);
return(0);//没有偏离,前进
/*铁片检测程序:
/*判断铁片的颜色,设定bkAim,0为A仓库,1为B仓库,2为停车场*/
voidIornColor()
delay(4000);
bkAim=(int)(P26);
Display((int)(P26)+2);
/*------------------运动控制模块-----------------*/
/*====基本动作层:
完成基本运动动作的程序集====*/
/*运动调整程序:
/*对小车的运动进行微调*/
voidctrMotor_Adjust(unsignedchart)
if(t==0)
P2=P2&240|11;//用来解决两电机不对称的问题
delay(6);
if(t==3)
P2=P2&250;//向左走
delay
if(t==1)
P2=(P2&245);
(1);//向右走
P2=((P2&240)|15);
delay(10);
/*直走程序:
/*控制小车运动距离,dist为运动距离(cm),type为运动方式(02)*/
/*只改变小车sX和sY的值而不改变Direction的值.*/
voidctrMotor_Dist(floatdist,unsignedchartype)
{unsignedchart=0;
mType=type;
cntTime_Plues=(int)(dist/det_Dist);
while(cntTime_Plues)
if(Inter_EX0==1&&StartTask==0)
cntTime_Plues=0;
break;
if(Light_Flag==1)t=LightSeek();
if(type==0)//向前走
P2=P2&249;
delay(40);
ctrMotor_Adjust(t);
if(type==2)//向后退
P2=P2&246;
delay(50);
if(mType==2)delay(60);//刹车制动0.5ms
elsedelay(75);
/*拐弯程序:
/*控制小车运动角度,type为运动方式(13)*/
/*只改变小车Direction的值而不改变sX和sY的值*/
voidctrMotor_Ang(unsignedcharang,unsignedchartype,unsignedchardir)
unsignedchari=0;
cntTime_Plues=(int)((PI*RD*90/(180*det_Dist)*1.2)*ang/90);
if(type==1)//向左走
P2=P2&250;
delay(100);
ctrMotor_Adjust(0);
if(type==3)//向右走
P2=P2&245;
delay(50);//刹车制动0.5ms
if(!
(Inter_EX0==1&&StartTask==0))
Direction=dir;
/*====基本路线层:
描述小车基本运动路线的程序集====*/
/*当小车到达仓库或停车场时,放下铁片或停车(0,1为仓库,2为停车场)*/
voidrchPlace()
{unsignedinttime,b,s,g;
time=(int)(cntTime_5Min*0.065535);//只有一个数码管时,轮流显示全过程秒数个十百
b=time%100;
s=(time-b*100)%100;
g=(time-b*100-s*10)%10;
if(bkAim==2)
//到达停车场了,停车
EA=0;
while
Display(10);//N
delay(2000);
Display(cntIorn);
Display(11);//A
Display(b);
Display(s);
Display(g);
else
if(Inter_EX0==1&&StartTask==1)P10=0;//到达仓库,卸下铁片
/*无任务模式:
/*设置小车的固定运动路线,未发现铁片时的运动路线*/
voidBasicRoute()
{//Light_Flag=1;
ctrMotor_Dist(153,0);
//Light_Flag=0;
ctrMotor_Ang(ANG_90,1,1);
ctrMotor_Dist(100-sX,0);
ctrMotor_Dist(125,2);
ctrMotor_Dist(73,0);
ctrMotor_Ang(ANG_90,1,2);
//Light_Flag=1;
ctrMotor_Ang(ANG_180,1,0);
rchPlace();
/*任务模式:
/*设置小车的发现铁片后的运动路线*/
voidTaskRoute()
//基本运行路线表,记载拐弯0向前1左拐2向后3右拐,正读去A区;反读去B区
StartTask=1;
ctrMotor_Ang(ANG_90_T,1,2);
if(bkAim==1)//仓库A
ctrMotor_Dist(10,0);
delay(60);
ctrMotor_Ang(ANG_90_T,1,3);
ctrMotor_Dist(100-sX,2);
Light_Flag=1;
ctrMotor_Dist(153,2);
Light_Flag=0;
//ctrMotor_Ang(208,1,0);
elseif(bkAim==0)//仓库B
ctrMotor_Ang(ANG_90_T,1,0);
delay(5000);
/*---------------------------------------------*/
/*-------------------主程序段------------------*/
voidmain()
P2=0xff;//初始化端口
P07=0;
P1=0;
TMOD=0x01;//初始化定时器0/1及其中断
TL0=0;
TH0=0;
TR0=1;
ET0=1;
ET1=1;
IT0=1;//初始化外部中断
EX0=1;
IT1=1;
EX1=1;
EA=1;
P11=1;
bkAim=2;
BasicRoute();
if(Inter_EX0==1)
TaskRoute();//按获得铁片后的路线运动
IE0=0;
Inter_EX0=0;
/*----------------------------------------------------*/
/*----------------------中断程序段--------------------*/
/*定时器0中断程序:
/*当时间过了5分钟,则就地停车并进入休眠状态*/
voidtmOver(void)interrupt1
cntTime_5Min++;
if(cntTime_5Min>=4520)
Display(5);
EA=0;//停车程序
P07=1;
PCON=0X00;
/*外部中断0中断程序:
/*发现铁片,发出声光信号并将铁片吸起,发光二极管和蜂鸣器*/
/*并联在一起(设接在P07).0为A仓库,1为B仓库,2为停车场*/
voidfndIorn(void)interrupt0
unsignedchari;
P10=1;
P2=((P2&240)|15);//停车
delay(1000);//刹车制动0.5ms
Inter_EX0=1;
cntIorn++;
for(i=0;i<40;i++)
(2);
IornColor();//判断铁片黑白,设置bkAim
for(i=0;i<95;i++)
delay(3);
delay(4000);//把铁片吸起来
EX0=0;
/*外部中断1中断程序:
/*对霍尔开关的脉冲记数,对小车的位置进行记录,以便对小车进行定位*/
voidstpMove(void)interrupt2
cntTime_Plues--;
if(Direction==0)//向上
if(mType==0)sY+=det_Dist;
elseif(mType==2)
sY-=det_Dist;
elseif(Direction==1)//向左
if(mType==0)sX+=det_Dist;
sX-=det_Dist;
elseif(Direction==2)//向下
if(mType==0)sY-=det_Dist;
sY+=det_Dist;
elseif(Direction==3)//向右
if(mType==0)sX-=det_Dist;
sX+=det_Dist;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1