#includereg51.h#defineMAXFLOOR6//定义一个最大层数为6层的电梯unsignedcharcodeLEDCODES[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d};//LED数码管发光数组/******************电梯外对应的上下按键*************************/sbitFLOOR6DOWN=P1^0;//6楼下对应的P1^0,IO口sbitFLOOR5UP=P1^1;//5楼上对应的P1^1,IO口sbitFLOOR5DOWN=P1^2;//5楼下对应的P1^2,IO口sbitFLOOR4UP=P1^3;//4楼上对应的P1^3,IO口sbitFLOOR4DOWN=P1^4;//4楼下对应的P1^4,IO口sbitFLOOR3UP=P1^5;//3楼上对应的P1^5,IO口sbitFLOOR3DOWN=P1^6;//3楼下对应的P1^6,IO口sbitFLOOR2UP=P1^7;//2楼上对应的P1^7,IO口sbitFLOOR2DOWN=P2^0;//2楼下对应的P2^0,IO口sbitFLOOR1UP=P2^1;//1楼上对应的P2^1,IO口/******************电梯内对应各层楼的按键***********************/sbitFLOOR1=P2^2;//1楼对应的P2^2IO口sbitFLOOR2=P2^3;//2楼对应的P2^3IO口sbitFLOOR3=P2^4;//3楼对应的P2^4IO口sbitFLOOR4=P2^5;//4楼对应的P2^5IO口sbitFLOOR5=P2^6;//5楼对应的P2^6IO口sbitFLOOR6=P2^7;//6楼对应的P2^7IO口/*********************电梯上下运行指示灯************************/sbitLEDUP=P3^6;//LED上对应的P3^6IO口sbitLEDDOWN=P3^7;//LED下对应的P3^7IO口bitDIRECTION=1,STOP=0;//电梯运行方向位,电机运行停止与否标志位unsignedcharCURFLOOR=1;//当前楼层处于1楼unsignedcharDESTFLOOR=1;//目地楼层处于1楼unsignedcharRUN=0;//运行状态标志位,RUN=1表示正在运行unsignedinttimer1=0,timer2=0;//timer1为楼层间运行时间计数值,timer2为等待计数值unsignedcharCALLFLOORUP[7]={0,0,0,0,0,0,0};//呼叫楼层上对应的数组,存储每层楼的信息,1为有人呼叫或者有人前往unsignedcharCALLFLOORDOWN[7]={0,0,0,0,0,0,0};//呼叫楼层下对应的数组,存储每层楼的信息,1为有人呼叫或者有人前往unsignedcharCALLFLOOR[7]={0,0,0,0,0,0,0};//呼叫楼层对应的数组,存储每层楼的信息,1为有人呼叫或者有人前往/*************自定义函数的声明*******************/voidSELECTNEXT();voidstep(bitDIRECTION);voidDELAY(unsignedintZ);voidJUDGESIT();/********************主函数**********************/voidmain(void){P0=LEDCODES[1];//点亮第一层对应的LEDTH0=0x3C;//定时器1的初值TL0=0xB0;TMOD=0x01;//开启定时器0工作方式1ET0=1;//开启定时器0EA=1;//开放总中断EX0=1;//开放外中断0IT0=1;//外中断0置1while(1){if(!RUN&&!STOP)//如果电梯没有处于运行状态并且处于停止状态{SELECTNEXT();//选择下一楼层函数,决定电梯去哪一层step(DIRECTION);//电梯启动函数}//电梯运行计时elseif(STOP)//如果处于停止状态{timer2=0;//定时值2标志位置0TR0=1;//开启定时器0while(timer2100&&STOP);//如果定时值2小于100并且stop位为1TR0=0;//关闭定时器0timer2=0;//定时值2标志位置0STOP=0;//停止位置0}}}/******************选择下一个楼层的函数*******************/voidSELECTNEXT(){charn;if(CURFLOOR==MAXFLOOR)//如果当前楼层等于最大楼层,方向转为向下方向,0表示向下运行,{DIRECTION=0;}elseif(CURFLOOR==1)//否则,如果当前处于1楼,方向为向上,1代表向上方向{DIRECTION=1;}if(DIRECTION==0)//如果方向是0,表明当前楼层处于最高层,为向下方向{if(CALLFLOORDOWN[CURFLOOR])//如果在下的过程中,有下面楼层的呼叫请求{//要去的为当前层,即需延时5sCALLFLOORDOWN[CURFLOOR]=0;//把当前楼层置0STOP=1;//停止位置1return;}//向下运行时查找下一个要去的楼层for(n=CURFLOOR-1;n=1;n--)//如果在下的过程中有低于当前楼层的楼层发出向下请求if(CALLFLOORDOWN[n])//如果下到当前楼层{DESTFLOOR=n;return;//把当前楼层的楼层数赋值给目地楼层}//没有人发出向下走的请求,即反向运行for(n=0;nCURFLOOR;n++)//如果在下的过程中有低于当前楼层的楼层发出向上请求if(CALLFLOORUP[n]){DESTFLOOR=n;//经过上面的判断此处表示电梯没有人,默认停在n楼return;}DIRECTION=1;//如果楼层方向为上for(n=CURFLOOR+1;n=MAXFLOOR;n++)//如果在上的过程中有高于当前楼层的楼层发出向上请求if(CALLFLOORUP[n]){DESTFLOOR=n;return;}for(n=MAXFLOOR;nCURFLOOR;n--)//上到最高层的时候,有向下的请求if(CALLFLOORDOWN[n]){DESTFLOOR=n;return;}}else//否则,如果方向为向上{if(CALLFLOORUP[CURFLOOR]){CALLFLOORUP[CURFLOOR]=0;STOP=1;return;}for(n=CURFLOOR+1;n=MAXFLOOR;n++)//还没有到达最高楼层的时候有向上请求if(CALLFLOORUP[n]){DESTFLOOR=n;return;}for(n=MAXFLOOR;nCURFLOOR;n--)//上到最高层的时候,有向下的请求if(CALLFLOORDOWN[n]){DESTFLOOR=n;return;}DIRECTION=0;//有低于当前楼层的向下请求for(n=CURFLOOR-1;n=1;n--)if(CALLFLOORDOWN[n]){DESTFLOOR=n;return;}for(n=1;n=CURFLOOR;n++)//有低于当前楼层的向上请求if(CALLFLOORDOWN[n]){DESTFLOOR=n;return;}}}/*******************方向处理函数**********************/voidstep(bitDIRECTION){if(DESTFLOOR==CURFLOOR)//如果当前楼层等于目地楼层,则返回return;elseif(!RUN)//否则,如果运行了{RUN=1;//运行位置1DELAY(50);//延时50if(DIRECTION==1)//如果反方向为向上{LEDUP=0;//向上的LED灯亮LEDDOWN=1;//向下的LED灯灭}else//否则为向下方向{LEDUP=1;//向上的LED灯灭LEDDOWN=0;//向下的LED灯亮}timer1=0;TR0=1;//开定时器0}}/*************************延时函数****************************/voidDELAY(unsignedintZ){unsignedintX,Y;for(X=Z;X0;X--)for(Y=125;Y0;Y--);}/*********************定时器0中断服务函数*******************************************定时0中断,可利用此发送电机PWM脉冲信号***/voidtimer0_int()interrupt1{TH0=0x3C;//赋予定时器初值TL0=0xB0;timer1++;//定时值1标志位自加timer2++;//定时值2标志位自加if(RUN)//如果处于运行状态{if(timer1==20)//如果定时值1自加到20,表示到达一个楼层延时1s{timer1=0;//定时值1赋值为0if(DIRECTION)//如果电梯为向上方向运行{CURFLOOR++;//当前楼层自加CALLFLOORUP[CURFLOOR]=0;//楼层向上请求赋值为0}else//否则,楼层为向下方向运行{CURFLOOR--;//楼层数自减CALLFLOORDOWN[CURFLOOR]=0;//楼层向下请求赋值为0}RUN=0;//运行标志位为0TR0=0;//关闭定时器0P0=LEDCODES[CURFLOOR];//点亮当前楼层的LED发光数码管//到达呼叫楼层,关电机if(DESTFLOOR==CURFLOOR)//如果当前楼层等于目地楼层,到达预定楼层了{TR0=0;//关闭定时器0LEDUP=1;//关闭向上LED灯LEDDOWN=1;//关闭向下LED灯STOP=1;//停止位置0return;}}}}/***********************外中断0中断服务函数**********************/voidint0()interrupt0{if(FLOOR6DOWN==0)//如果6楼没有向下运行CALLFLOORDOWN[6]=1;//6楼向下请求信号置1elseif(FLOOR5DOWN==0)//如果5楼没有向下运行CALLFLOOR[5]=1;//5楼向下请求信号置1elseif(FLOOR4DOWN==0)//如果4楼没有向下运行CALLFLOORDOWN[4]=1;//4楼向下请求信号置1elseif(FLOOR3DOWN==0)//如果3楼没有向下运行CALLFLOORDOWN[3]=1;//3楼向下请求信号置1elseif(FLOOR2DOWN==0)//如果2楼没有向下运行CALLFLOORDOWN[2]=1;//2楼向下请求信号置1elseif(FLOOR1UP==0)//如果1楼没有向上运行CALLFLOORUP[1]=1;//1楼向上请求信号置1elseif(FLOOR2UP==0)//如果2楼没有向上运行CALLFLOORUP[2]=1;//2楼向上请求信号置1elseif(FLOOR3UP==0)//如果3楼没有向上运行CALLFLOORUP[3]=1;//3楼向上请求信号置1elseif(FLOOR4UP==0)//如果4楼没有向上运行CALLFLOORUP[4]=1;//4楼向上请求信号置1elseif(FLOOR5UP==0)//如果5楼没有向上运行CALLFLOORUP[5]=1;//5楼向上请求信号置1elseif(FLOOR6==0)//如果6楼等于0{CALLFLOOR[6]=1;/