基于单片机的四层电梯控制系统设计

目录
4层电梯单片机控制设计 4

  1. 设计任务 4
  2. 整体方案设计 5
  3. 系统硬件电路设计 6
    3.1 单片机最小系统电路 6
    图3-1 单片机最小系统电路图 6
    3.2 开关控制电路 7
    图3-2 开关控制电路设计图 7
    3.3 显示电路 8
    3.3.1 led楼层触发显示灯电路 8
    3.3.2 当前楼层显示电路 9
    图3-3-2 当前楼层显示电路 9
    3.4 8155串行口扩展电路 10
    3.5 总设计图 12
    图3-5 总设计图 12
  4. 系统程序设计 12
    4.1 主程序流程图 12
    系统工作流程:(1)用菊阳仿真器使程序处于连续运行状态 13
    4.2 定时器子程序流程图 13
    4.3 扫描子程序流程图 13
    4.4 显示子程序流程图 14
    4.5 延时流程图 15
    图4-5 延时程序流程图 15
  5. 系统调试 15
    5.1 Proteus软件仿真调试 15
    5.2 硬件调试 16
    1上(4键)2上(0键)3上(RG键) 16
  6. 程序清单 16
    7.小结 29
  7. 设计任务
    结合实际情况,基于AT89C52单片机设计一个四层电梯单片机控制系统。该系统应满足的功能要求为:
    4层电梯运行控制,轿内外呼叫,运行状态显示。独立键盘、LED显示楼层、指示灯。
    (1) 电梯运行控制系统为四层控制系统。
    (2) 电梯能够轿内外呼叫,并显示运行的状态。
    (3) 设计系统具有独立键盘控制,并有LED显示楼层与指示灯。
    主要硬件设备:AT89C52单片机: AT89C52是一个低电压,高性能CMOS 8位单片机,片内含8k bytes的可反复擦写的Flash只读程序存储器和256 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,AT89C52单片机在电子行业中有着广泛的应用。
    AT89C52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2 个读写口线,AT89C52可以按照常规方法进行编程,也可以在线编程。其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的 Flash存储器可有效地降低开发成本。
    AT89C52有PDIP、PQFP/TQFP及PLCC等三种封装形式,以适应不同产品的需求。
  8. 整体方案设计
    本设计采用AT89C52单片机作为核心,配以适当接口作为输入输出通道。采用三行按键矩阵开关电路作为外呼内选呼叫控制。实际电梯控制系统每层装有一个传感器,从而判断车厢所在位置,本模型由10个独立按键作为楼层到达信号传输给单片机,而后通过内部电路从串口驱动数码管显示楼层数。当电梯到达所选层,电梯开门延时等待进人并选层,然后延时关门执行请求,若无请求则停在本层等待请求。软件部分使用C语言,利用查询方式来检测用户请求的按键信息。
    在这里插入图片描述

图2-1 基于单片机的四层电梯控制总原理图
本系统硬件主要由复位模块、显示系统、扩展部分、矩阵控制模块几部分组成。各模块的主要功能如下:
(1) 复位的功能其一用于程序初始化,其二也用于摆脱互锁和跑飞。
(2) 显示系统的功能分为显示led灯显示触发楼层数和数码管显示当前楼层数的两个部分,用于显示电梯系统此时正在运行的状态。
(3) 扩展部分:因为单片机芯片的接口有限,故使用8155扩展串行口用以连接更多功能。
(4) 矩阵控制模块:即内呼外叫控制程序,用于控制电梯内外电路。

 #include "reg52.h"
#include "absacc.h"
#define uint unsigned int
#define uchar unsigned char
#define COM XBYTE[0xFF20]					//定义8155地址
#define PA XBYTE[0xFF21]
#define PB XBYTE[0xFF22]
#define PC XBYTE[0xFF23]

sbit lup1=P1^0;	      //L1	//定义led控制端口
sbit lup2=P1^1;       //L2
sbit ldown2=P1^2;       //L3
sbit lup3=P1^3;       //L4
sbit ldown3=P1^4;       //L5
sbit ldown4=P1^5;     //L6
sbit lopen=P1^7;      //L8


uchar state;		//当前电梯状态
uchar statepre;		//之前电梯状态
uchar flag;		//电梯上下标志,0下,1上
bit flag1;		//定时时间到标志
uchar counter;		//计数器
bit in1=0, in2=0, in3=0, in4=0, up1=0, up2=0, up3=0, down2=0, down3=0, down4=0;	//KEY
uchar code table[]={
    
    0xf9, 0xa4,0xb0,0x99,  0xa1, 0xc1, 0xff};        //楼层显示码表,一共是四层

void delay(uint xms)	   //简单延时0.1ms
{
    
    
	uint o,j;
	for(o=xms;o>0;o--)
		for(j=11;j>0;j--);
}
/***********************************************************/
void display(){
    
    
		PB=0xff;
		PA=0xfe;
		PB=table[state-1];
                delay(2);

                PB=0xff;
                PA=0xfd;
                PB=table[flag+4];
                delay(2);
}
void keyscan(){
    
    					//扫描键盘
		uchar pctemp;
		PB=0xff;
		PA=~0x01;				//PA0口输出低电平
		pctemp=PC;
		switch(pctemp&0x0f){
    
    	//PC高位置0
			case(0x0e):{
    
    
				in1=1;			//被按下后标记,亮灯,下同
				

				break;
			}
			case(0x0d):{
    
    
				in2=1;
				

				break;
			}
			case(0x0b):{
    
    
				in3=1;
				

				break;
			}
			case(0x07):{
    
    
				in4=1;
				

				break;
			}
			default: break;
		}
		PA=~0x02;				 //PA1口低电平扫描第二行
		delay(1);
		pctemp=PC;
		switch(pctemp&0x0f){
    
    
			case(0x0e):{
    
    
				up1=1;
				lup1=0;

				break;
			}
			case(0x0d):{
    
    
				up2=1;
				lup2=0;

				break;
			}
			case(0x0b):{
    
    
				up3=1;
				lup3=0;

				break;
			}

			default: break;
		}
		PA=~0x04;
		delay(1);				//PA2口低电平扫描第三行
		pctemp=PC;
		switch(pctemp&0x0f){
    
    			

			case(0x0d):{
    
    
				down2=1;
				ldown2=0;

				break;
			}
			case(0x0b):{
    
    
				down3=1;
				ldown3=0;

				break;
			}
			case(0x07):{
    
    
				down4=1;
				ldown4=0;

				break;
			}
			default: break;
		}
}


void iniclock()      //start clock
{
    
    
		TH0=60;		//TH0=(65536-50000)/256 TL0=(65536-50000)%256   50ms初值
		TL0=176;
		ET0=1;	   //开定时器
		TR0=1;	  //启动定时器T0
}
void run(){
    
    
		iniclock();			//开定时
		while(~flag1){
    
    		//时间未到扫描键盘
			keyscan();
			display();
		}
		flag1=0;			//时间到了,清标志位,关定时器
		TR0=0;
		ET0=0;
}
void main()
{
    
    
 		state=1;
		statepre=1;
		flag=1;
		flag1=0;
		COM=0x43;			//intialize 8155
		TMOD=0x01;		   //定义定时器0/1为定时器模式
		//TH0=(65536-50000)/256;//50ms初值
		//TL0=(65536-50000)%256;
		//ET0=1;				  //开定时器
		//TR0=1;				  //启动定时器T0
		EA=1;				  //开中断


        	while(1){
    
    
			switch(state){
    
    				//扫描电梯所在位置
				case(1):{
    
    
					//up1=0;			//一楼的按键灯都熄灭
					//in1=0;
					//lup1=1;
					//lin1=1;
					//keyscan;
					//display();
					if(state!=statepre){
    
    	//上次的状态和本次不一样说明电梯 需要开门
						lopen=0;
						run();			//按键扫描三秒钟
						lopen=1;
						in1=0;		//如果in1和up1被按下则无效
					
						up1=0;
						lup1=1;
					}
                    else{
    
    
                        if(up1){
    
    
                                up1=0;
                                lup1=1;
                                lopen=0;
                                run();
                                lopen=1;
                                }
                         }
                      in1=0;
                                       
					if(up2|down2|up3|down3|down4|in2|in3|in4){
    
    
						flag=1;			//说明上行
						run();				//按键扫描三秒钟
						state=2;			//更新状态
						statepre=1;
					}
					else{
    
    
						statepre=state;
                        flag=2;
						keyscan();
						display();
					}
					break;
				}
				case(2):{
    
    					  //电梯到2楼
					//in2=0;				//电梯内部2楼指示灯灭
					//lin2=1;
					//if(flag==1){				//如果上行,电梯外上行指示灯灭
						//up2=0;
						//lup2=1;
					//}
					//else{					//如果下行,电梯外下行指示灯灭
						//down2=0;
					       //	ldown2=1;
					//}
					//keyscan;
					//display();
					if(state!=statepre)
                    {
    
                              //如果前后两次状态不一样则可能需要开门
                     	if(!(
							((flag==1)&&(in3|up3|down3)&&(~up2)&&(~in2))		   //去三楼
							||((flag==1)&&(in4|down4)&&(~up2)&&(~in2))		   //去四楼
                            ||((flag==0)&&(in1||up1)&&(~down2)&&(~in2))		   //去一楼
                            )
                          )
                           {
    
    			
								lopen=0;
								run();				//按键扫描三秒钟
								lopen=1;
								in2=0;				//如果in2被按下则无效
						
								if(flag==1){
    
    			//如果上行,电梯外上行指示灯按下无效
								up2=0;
								lup2=1;
								}
								else{
    
    				//如果下行,电梯外下行指示灯按下无效
								down2=0;
								ldown2=1;
								}
                         	}
					}
                                        else{
    
    									//在二楼停
                                        	if(down2|up2){
    
    
                                                	down2=0;
                                                        up2=0;
                                                        lopen=0;
                                                        run();
                                                        lopen=1;
                                                        ldown2=1;
                                                        lup2=1;
                                                	}
                                        	}
                                        in2=0;
                                       
                                        if(flag)
                                        	up2=0;
                                        else
                                        	down2=0;
					if(flag==1){
    
    
						if(down3|in3|up3|down4|in4){
    
    
							flag=1;
							run();
							state=3;
							statepre=2;
						}
						else if(in1|up1){
    
    
							flag=0;
							run();
							state=1;
							statepre=2;
						 }
						 else{
    
    
						 	statepre=state;
                                                        flag=2;
						 	keyscan();
						 	display();
						 }
					}
					else {
    
    
						if(up1|in1){
    
    
							flag=0;
							run();
							state=1;
							statepre=2;
						}
						else if(in3|down3|up3|in4|down4){
    
    
							flag=1;
							run();
							state=3;
							statepre=2;
						}
						else{
    
    

							statepre=state;
                                                        flag=2;
							keyscan();
							display();
						}
					}
					break;
				}
				case(3):{
    
    				//电梯到3楼
					//in3=0;				//电梯内部3楼指示灯灭
					//lin2=1;
					//if(flag==1){				//如果上行,电梯外上行指示灯灭
						//up3=0;
						//lup3=1;
					//}
					//else{					//如果下行,电梯外下行指示灯灭
						//down3=0;
					       //	ldown2=1;
					//}
					//keyscan;
					//display();
					if(state!=statepre)
                    {
    
                              //如果前后两次状态不一样则可能需要开门
                     	if(!(
							((flag==0)&&(in2|up2|down2)&&(~up3)&&(~in3))		   //去二楼
							||((flag==1)&&(in4|down4)&&(~up3)&&(~in3))		   //去四楼
                            ||((flag==0)&&(in1||up1)&&(~down3)&&(~in2))		   //去一楼
                            )
                          )
                           {
    
    			
								lopen=0;
								run();				//按键扫描三秒钟
								lopen=1;
								in3=0;				//如果in3被按下则无效
						
								if(flag==1){
    
    			//如果上行,电梯外上行指示灯按下无效
								up3=0;
								lup3=1;
								}
								else{
    
    				//如果下行,电梯外下行指示灯按下无效
								down3=0;
								ldown2=1;
								}
                         	}
					}
                                        else{
    
    									//在三楼停
                                        	if(down3|up3){
    
    
                                                	down3=0;
                                                        up3=0;
                                                        lopen=0;
                                                        run();
                                                        lopen=1;
                                                        ldown3=1;
                                                        lup3=1;
                                                	}
                                        	}
                                        in3=0;
                                       
                                        if(flag)
                                        	up3=0;
                                        else
                                        	down3=0;
					if(flag==1){
    
    
						if(down4|in4){
    
    
							flag=1;
							run();
							state=4;
							statepre=3;
						}
						else if(in1|up1|in2|up2|down2){
    
    
							flag=0;
							run();
							state=2;
							statepre=3;
						 }
						 else{
    
    
						 	statepre=state;
                                                        flag=2;
						 	keyscan();
						 	display();
						 }
					}
					else {
    
    
						if(up1|in1|up2|in2|down2){
    
    
							flag=0;
							run();
							state=2;
							statepre=3;
						}
						else if(in4|down4){
    
    
							flag=1;
							run();
							state=4;
							statepre=3;
						}
						else{
    
    

							statepre=state;
                                                        flag=2;
							keyscan();
							display();
						}
					}
					break;
				}
				case(4):{
    
    					//case4和case1类似
					//down4=0;
					//in4=0;
					//ldown4=1;
					//lin4=1;
					keyscan();
					display();
					if(state!=statepre){
    
    
						lopen=0;
						run();
						lopen=1;
						in4=0;				//如果in4和down4被按下则无效
					
						down4=0;
						ldown4=1;
					}
                                        else{
    
    
                                        	if(down4){
    
    
                                                	down4=0;
                                                        ldown4=1;
                                                        lopen=0;
                                                        run();
                                                        lopen=1;
                                                }
                                        }
                                        in4=0;
                                      
					if(in1|up1|up2|down2|in2|in3|up3|down3){
    
    
						flag=0;				//说明下行
						run();
						state=3;			//更新状态
						statepre=4;
					}
					else{
    
    
						statepre=state;
                                                flag=2;
						keyscan();
						display();
					}
					break;
				}
				default: break;
			}
		}
}

void T0_time()interrupt 1
{
    
    
	TH0=(65536-50000)/256; 	TL0=(65536-50000)%256; //重赋初值
	counter++;		   //定时器中断次数加1
	if(counter==60)	 //三秒钟执行一次
	{
    
    
        	counter=0;
			flag1=1;          //三秒钟定时到标志
        }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/newlw/article/details/130039813
今日推荐