智能小车程序完整.docx
《智能小车程序完整.docx》由会员分享,可在线阅读,更多相关《智能小车程序完整.docx(14页珍藏版)》请在冰豆网上搜索。
智能小车程序完整
智能小车程序
---------超长完整版---------
#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};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(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.5ms elsedelay(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);//N delay(2000); Display(cntIorn); delay(2000); Display(11);//A delay(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; else if(mType==2) sY-=det_Dist; } elseif(Direction==1) //向左 { if(mType==0)sX+=det_Dist; else if(mType==2) sX-=det_Dist; } elseif(Direction==2) //向下 { if(mType==0)sY-=det_Dist; else if(mType==2) sY+=det_Dist; } elseif(Direction==3)//向右 { if(mType==0)sX-=det_Dist; else if(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};
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;
else if(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