这是我一个星期完成的电梯设计,内含上下行电梯、电梯紧急停止、内部故障报警系统等内容。
内部包含电路设计图(含注释),电路源代码等,请大家多多指教。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <REG51.H>
- #include <INTRINS.H>
- unsigned char ucMotorDrvPuls;
- unsigned char FORREV=1;
- unsigned char STOPCUR=0;
- unsigned char CURFLR=1;
- unsigned char count=0;
- #define UCTIMES 8
- #define OUTPUT P2
- #define COUNT 8
- sbit UP1=P3^4;
- sbit DOWN2=P3^3;
- sbit UP2=P3^2;
- sbit DOWN3=P3^1;
- sbit UP3=P3^0;
- sbit DOWN4=P1^7;
- sbit FLOOR1=P1^0;
- sbit FLOOR2=P1^1;
- sbit FLOOR3=P1^2;
- sbit FLOOR4=P1^3;
- sbit START=P1^4;
- sbit STOP=P1^5;
- sbit ALARM=P1^6;
- sbit alarmBit=P0^4;
- sbit upLight=P0^5;
- sbit downLight=P0^6;
- void time(unsigned int ucMs);
- void outPress();
- unsigned char inPress();
- unsigned char elevator();
- void storeUP(unsigned char);
- void storeDOWN(unsigned char);
- void time (unsigned int ucMs);
- void initLights(void);
- void setFloor(int floor);
- void setUpLight();
- void setDownLight();
- void setStopLight();
- void setAlarmLight();
- void setAlarmLight();
- void offAlarmLight();
- int alarmSwitch=1;
- unsigned char UP_req[5]={0,0,0,0,0};
- unsigned char DOWN_req[5]={0,0,0,0,0};
- void position(void)
- {
- OUTPUT=0x01|(P2&0xf0);time(200);
- OUTPUT=0x02|(P2&0xf0);time(200);
- OUTPUT=0x04|(P2&0xf0);time(200);
- OUTPUT=0x08|(P2&0xf0);time(200);
- ucMotorDrvPuls=0x11;
- OUTPUT=0x01|(P2&0xf0);
- }
- void main(void)
- {
- time(100);
- initLights();
- position();
- ucMotorDrvPuls=0x11;
- OUTPUT=0x00|(P2&0xf0);
- setFloor(CURFLR);
- setUpLight();
- time(100);
-
- while(1)// 主循环
- {
- outPress();//按下电梯外按钮
- while(STOPCUR==1)
- {
- outPress();
- inPress();
- }
-
- if(inPress()) //按下电梯内楼层按钮
- {
- while(START) //等待启动按键按下
- {
- outPress();
- inPress();
- }
- }
-
- while(1) //电机运转循环
- {
- if(UP_req[1]==0&&UP_req[2]==0&&UP_req[3]==0&&
- DOWN_req[2]==0&&DOWN_req[3]==0&&DOWN_req[4]==0)
- {
- break;
- }
-
- if(FORREV) //上
- {
- setUpLight(); //上行灯亮
-
- if(STOPCUR==1){break;}
-
- if(elevator()) //往上到达某一层
- {
- if(CURFLR==4) {setDownLight();break;} //到达四层
- }
- OUTPUT=(ucMotorDrvPuls&0x0f)|(P2&0xf0);
- ucMotorDrvPuls=_crol_(ucMotorDrvPuls,1);
- }
- if(!FORREV) //下
- {
- setDownLight(); //下行灯亮
-
- if(STOPCUR==1){break;}
-
- if(elevator()) //往下到达某一层
- {
- if(CURFLR==1){setUpLight();break;}//到达一楼
- }
- OUTPUT=(ucMotorDrvPuls&0x0f)|(P2&0xf0);
- ucMotorDrvPuls=_cror_(ucMotorDrvPuls,1);
- }
-
- outPress(); //按下电梯外按钮
- //if(inPress()) //按下电梯内楼层按钮
- //{
- //while(START) //等待启动按键按下
- //{
- // outPress();
- inPress(); //电梯运行时,内部按钮按下,无需按启动按钮
- //}
- //}
-
- time(380-UCTIMES*16);
-
- } //end while-电机运转循环
-
- OUTPUT=0x00|(P2&0xf0); //电机停止
-
- }//end while-主循环
- }
-
- //按下电梯外按钮
- void outPress()
- {
- //FORREV=1;
- if(!UP1) //1楼上
- {
- storeUP(1);
- if(CURFLR>1&&STOPCUR==1)
- {
- FORREV=0; //向下运行
- STOPCUR=0;
- }
- if(CURFLR==1)
- {
- STOPCUR=1;//电梯停留在当前层
- }
- }
- if(!UP2) //2楼上
- {
- storeUP(2);
- if(CURFLR>2&&STOPCUR==1) //电梯在二楼以上
- {
- FORREV=0;
- STOPCUR=0;
- }
- if(CURFLR<2&&STOPCUR==1)
- {
- FORREV=1;
- STOPCUR=0;
- }
- if(CURFLR==2)
- {
- STOPCUR=1;
- }
- }
- if(!UP3) //3楼上
- {
- storeUP(3);
- if(CURFLR>3&&STOPCUR==1) //电梯在三楼以上
- {
- FORREV=0;
- STOPCUR=0;
- }
- if(CURFLR<3&&STOPCUR==1)
- {
- FORREV=1;
- STOPCUR=0;
- }
- if(CURFLR==3)
- {
- STOPCUR=1;
- }
- }
- if(!DOWN2) //2楼下
- {
- storeDOWN(2);
- if(CURFLR>2&&STOPCUR==1)//电梯在二楼以上
- {
- FORREV=0;
- STOPCUR=0;
- }
- if(CURFLR<2&&STOPCUR==1)
- {
- FORREV=1;
- STOPCUR=0;
- }
- if(CURFLR==2)
- {
- STOPCUR=1;
- }
- }
- if(!DOWN3)//3楼下
- {
- storeDOWN(3);
- if(CURFLR>3&&STOPCUR==1)//电梯在三楼以上
- {
- FORREV=0;
- STOPCUR=0;
- }
- if(CURFLR<3&&STOPCUR==1)
- {
- FORREV=1;
- STOPCUR=0;
- }
- if(CURFLR==3)
- {
- STOPCUR=1;
- }
- }
- if(!DOWN4)//4楼下
- {
- storeDOWN(4);
- if(CURFLR<4&&STOPCUR==1)
- {
- FORREV=1;
- STOPCUR=0;
- }
- if(CURFLR==4)
- {
- STOPCUR=1;
- }
- }
- }
-
- //按下电梯内楼层按钮
- unsigned char inPress()
- {
- int i;
- int flag=0;
-
- if(!FLOOR1)
- {
- if(1<CURFLR)
- {
- STOPCUR=0;
- UP_req[1]=1;
- }
- if(1==CURFLR)
- {
- STOPCUR=1;
- }
- return 1;
- }
- if(!FLOOR2)
- {
- if(2>CURFLR)//请求层大于当前层
- {
- UP_req[2]=1;
- STOPCUR=0;
- }
- if(2<CURFLR)
- {
- DOWN_req[2]=1;
- STOPCUR=0;
- }
- if(2==CURFLR)
- {
- STOPCUR=1;
- }
- return 1;
-
- }
- if(!FLOOR3)
- {
- if(3>CURFLR)//请求层大于当前层
- {
- UP_req[3]=1;
- STOPCUR=0;
- }
- if(3<CURFLR)
- {
- DOWN_req[3]=1;
- STOPCUR=0;
- }
- if(3==CURFLR)
- {
- STOPCUR=1;
- }
- return 1;
- }
-
- if(!FLOOR4)
- {
- if(4>CURFLR)
- {
- DOWN_req[4]=1;
- STOPCUR=0;
- }
- if(4==CURFLR)
- {
- STOPCUR=1;
- }
- return 1;
- }
- if(!START)
- {
- STOPCUR=0;
- return 1;
- }
- if(!STOP)//紧急停止
- {
- while(START)//不响应其他按钮
- {
- //亮灯
- setStopLight();
- }
- return 1;
- }
- if(!ALARM)
- {
- //while(START)
- //{
- //亮灯
- setAlarmLight();
- //time(800);
- //灯灭
- //offAlarmLight();
- //}
- return 1;
- }
-
- if(FORREV==1)
- {
- //请求上行而进去电梯内选择的是下层
- for(i=CURFLR+1;i<4;i++)
- {
- if(UP_req[i]==1||DOWN_req[i]==1){flag=1;}
- }
- if(flag==0)//上层没有请求
- {
- FORREV=0;
-
- }
- }
- if(FORREV==0)
- {
- //请求下行而进去电梯内选择的是上层
- for(i=CURFLR-1;i>=1;i--)
- {
- if(UP_req[i]==1||DOWN_req[i]==1){flag=1;}
- }
- if(flag==0)//
- {
- FORREV=1;
- }
- }
- return 0;
- }
- unsigned char elevator()
- {
- count++;
- if (count==COUNT)
- {
-
- if(FORREV==1)
- {
- CURFLR++;
- setUpLight();//上行灯亮
- if(CURFLR==2)//到达二楼
- {
- count=0;
- setFloor(2);//显示数字
- if(UP_req[2]==1)//二楼有上行请求,优先处理
- {
- setUpLight();
- UP_req[2]=0;
- OUTPUT=0x00|(P2&0xf0);//电机停止
- STOPCUR=1;
- return 1;
- }
- if(DOWN_req[2]==1&&UP_req[3]==0&&DOWN_req[3]==0
- &&DOWN_req[4]==0)//二楼有下请求,上面两层没有请求,不再往上
- {
- setDownLight();
- DOWN_req[2]=0;
- STOPCUR=1;
- OUTPUT=0x00|(P2&0xf0);//电机停止
- FORREV=0;
- return 1;
- }
- }
- if(CURFLR==3)//到达三楼
- {
- setFloor(3);//显示数字
- count=0;
- if(UP_req[3]==1)//三楼有上行请求,优先处理
- {
- setUpLight();
- UP_req[3]=0;
- OUTPUT=0x00|(P2&0xf0);//电机停止
- STOPCUR=1;
- return 1;
- }
- if(DOWN_req[3]==1&&UP_req[4]==0)//三楼有下请求,四楼没有请求,不再往上
- {
- setDownLight();
- FORREV=0;
- DOWN_req[3]=0;
- STOPCUR=1;
- OUTPUT=0x00|(P2&0xf0);//电机停止
- return 1;
- }
- }
- if(CURFLR==4)//到达四楼
- {
- setFloor(4);//显示数字
- setDownLight();
- count=0;
- if(DOWN_req[4]==1)//四楼有上行请求,四楼的请求只用向下的情况
- {
- DOWN_req[4]=0;
- FORREV=0;
- OUTPUT=0x00|(P2&0xf0);//电机停止
- STOPCUR=1;
- }
- }
- }
- else//判断下行是否到达请求层,下行请求优先处理
- {
- CURFLR--;
- setDownLight();//下行灯亮
-
-
-
- if(CURFLR==1)//到达一楼
- {
- setFloor(1);//显示数字
- count=0;
- if(UP_req[1]==1)//一楼没有请求,一楼的请求只有向上的情况
- {
- setUpLight();
- UP_req[1]=0;
- FORREV=1;
- OUTPUT=0x00|(P2&0xf0);//电机停止
- STOPCUR=1;
- }
- }
- if(CURFLR==2)//到达二楼
- {
- setFloor(2);//显示数字
- count=0;
- if(DOWN_req[2]==1)//二楼有下行请求,优先处理
- {
- setDownLight();
- DOWN_req[2]=0;
- OUTPUT=0x00|(P2&0xf0);//电机停止
- STOPCUR=1;
- return 1;
- }
- if(UP_req[2]==1&&UP_req[1]==0)//一楼无请求,不再往下
- {
- setUpLight();
- FORREV=1;
- UP_req[2]=0;
- STOPCUR=1;
- OUTPUT=0x00|(P2&0xf0);//电机停止
- }
- }
- if(CURFLR==3)//到达三楼
- {
- setFloor(3);//显示数字
- count=0;
- if(DOWN_req[3]==1)//三楼有下行请求,优先处理
- {
- setDownLight();
- DOWN_req[3]=0;
- OUTPUT=0x00|(P2&0xf0);//电机停止
- STOPCUR=1;
- return 1;
- }
- if(UP_req[1]==0&&DOWN_req[2]==0&&UP_req[2]==0&&UP_req[3]==1)
- {
- setUpLight();
- FORREV=1;
- UP_req[3]=0;
- STOPCUR=1;
- OUTPUT=0x00|(P2&0xf0);//电机停止
- }
- }
- }//end if-FORREV
-
- return 1;
- }
- else
- {
- return 0;
- }//end if-count
- }
- void storeUP(unsigned char x)
- {
- UP_req[x]=1;
- }
- void storeDOWN(unsigned char x)
- {
- DOWN_req[x]=1;
- }
- void initLights()
- {
- P0=0x11;
- }
- //设置楼层显示
- void setFloor(int floor)
- {
- switch(floor)
- {
- case 1:
- {
- P0&=0xf0;//清零
- P0|=0x01;break;
- }
- case 2:
- {
- P0&=0xf0;//清零
- P0|=0x02;break;
- }
- case 3:
- {
- P0&=0xf0;//清零
- P0|=0x03;break;
- }
- case 4:
- {
- P0&=0xf0;//清零
- P0|=0x04;break;
- }
- default:
- {
- P0=0x06;break;
- }
- }
- }
- //设置电梯向上运行灯
- void setUpLight()
- {
- upLight=1;
- downLight=0;
- }
- //设置电梯向下运行灯
- void setDownLight()
- {
- upLight=0;
- downLight=1;
- }
-
- //设置电梯停止运行灯
- void setStopLight()
- {
- upLight=0;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
Keil代码与Proteus8.13仿真下载:
仿真程序.7z
(101.02 KB, 下载次数: 47)
|