4层电梯单片机控制设计 在1901年的上海,美国奥的斯公司安装了中国最早的一座电梯,而今,我国电梯业已进入了高速发展的时期,商场、医院、宾馆、仓库、住宅大楼等地方的电梯都被广泛应用着,直接与人们的生活息息相关,给人们的生活带来了极大的便利,是一种必不可少的垂直运输交通工具。 抛开一些复杂的概念,单片机在我们的生活中触手可及,尤其是在智能仪表,实时控制,机电一体化,办公机械,家用电器等方面拥有广泛的应用领域。这次课设注重对单片机的理解应用,明白单片机的工作原理,掌握单片机的接口技术,中断技术,存储技术,时钟方式和控制方式,这样才能更好地利用单片机来做有效的设计,提高自己的综合能力。 1. 设计任务 结合实际情况,基于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等三种封装形式,以适应不同产品的需求。 2. 整体方案设计 本设计采用AT89C52单片机作为核心,配以适当接口作为输入输出通道。采用三行按键矩阵开关电路作为外呼内选呼叫控制。实际电梯控制系统每层装有一个传感器,从而判断车厢所在位置,本模型由10个独立按键作为楼层到达信号传输给单片机,而后通过内部电路从串口驱动数码管显示楼层数。当电梯到达所选层,电梯开门延时等待进人并选层,然后延时关门执行请求,若无请求则停在本层等待请求。软件部分使用C语言,利用查询方式来检测用户请求的按键信息。 图2-1 基于单片机的四层电梯控制总原理图 本系统硬件主要由复位模块、显示系统、扩展部分、矩阵控制模块几部分组成。各模块的主要功能如下: (1) 复位的功能其一用于程序初始化,其二也用于摆脱互锁和跑飞。 (2) 显示系统的功能分为显示led灯显示触发楼层数和数码管显示当前楼层数的两个部分,用于显示电梯系统此时正在运行的状态。 (3) 扩展部分:因为单片机芯片的接口有限,故使用8155扩展串行口用以连接更多功能。 (4) 矩阵控制模块:即内呼外叫控制程序,用于控制电梯内外电路。 系统的整体设计方案设计图如图2-2所示。 图2-2 系统的整体方案设计图 3. 系统硬件电路设计 3.1 单片机最小系统电路 图3-1 单片机最小系统电路图 单片机最小系统包括复位电路和时钟电路。具体电路如图3-1所示。 复位电路虽然简单,但其作用非常重要。一个单片机系统能否正常运行,首先要检查是否能复位成功。初步检查可用于示波器探头监视RST引脚,按下复位键,观察是否有足够幅度的波形输出(瞬时的),还可以通过改变复位电路阻容值进行试验。本复位电路采用上电自动复位和手动复位组合。上电自动复位是在加电瞬间电容通过充电来实现的,在通电瞬间,电容C3通过R1K电阻充电,RST端出现正脉冲,用以复位。只要电源Vcc的上升时间不超过1ms,就可以实现自动上电复位,即接通电源就完成了系统的复位初始化。手动复位是通过按下S111后,通过电阻RR直接给服务端一个高电平使之复位。编程初始化设置数码管显示为1,并且等待楼层模拟传感器读取数据。 单片机最小系统包括复位电路。具体电路如图3所示。 复位电路虽然简单,但其作用非常重要。一个单片机系统能否正常运行,首先要检查是否能复位成功。初步检查可用于示波器探头监视RST引脚,按下复位键,观察是否有足够幅度的波形输出(瞬时的),还可以通过改变复位电路阻容值进行试验。本复位电路采用上电自动复位和手动复位组合。上电自动复位是在加电瞬间电容通过充电来实现的,在通电瞬间,电容C3通过R1K电阻充电,RST端出现正脉冲,用以复位。只要电源Vcc的上升时间不超过1ms,就可以实现自动上电复位,即接通电源就完成了系统的复位初始化。手动复位是通过按下S111后,通过电阻RR直接给服务端一个高电平使之复位。编程初始化设置数码管显示为1,并且等待楼层模拟传感器读取数据。 3.2 开关控制电路 图3-2 开关控制电路设计图实际上即为一个内呼外叫系统,现以呼叫信号的输入为例,来说明信号输入及单片机识别原理。如图3所示,采 用P0口外接上拉电阻的并行输入形式,来输入外呼叫信号,本电路采用4×4中的10个矩阵键盘,行扫描法识别键值的原理,具体原理如下: a) 判断键盘中有无键按下 将全部行线PC.0-PC.3置低电平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。 b) 判断闭合键所在的位置 在确认有键按下后,即可进入确定具体闭合键的过程。其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。 由于没有电梯控制硬件模型,只能用按键来模拟电梯到达位置的触发信号。本电路采用独立式按键非编码键盘接口查询方式。当任何一个键按下时,与之相连的输入数据线即被清0(低电平),而平时该线为1(高电平)。要判断是否有键按下,用单片机的位处理指令十分方便。这种键盘结构的优点是电路简单;缺点是当键数较多时要占用较多的I/O口。 查询方式键盘的处理程序比较简单。本处理程序中没有使用散转指令,并且省略了软件去抖动措施,只包括键查询、键功能程序转移。 3.3 显示电路 3.3.1 led楼层触发显示灯电路 
图3-3-1 led楼层触发显示灯电路 本设计所用A/D转换电路采用通用的ADC0809模数转换芯片,它是一种8位数字输出的逐次逼近式A/D转换器件,转换时间为100us。…… 其主要特性有…… ADC0809的工作原理为…… 使用ADC0809应该注意…… 其与单片机的接口电路如图3-1所示。 3.3.2 当前楼层显示电路 图3-3-2 当前楼层显示电路 运用7SEG-MPX-4CA来实现输出楼层信息和当前楼层上下信息,7seg-mpx8-ca是共阳极数码管显示器,它左下侧的abcdefg dp是LED数码管显示器的I/O口,是段选信号,右下侧的12345678是它的位选信号,就是从左到右分别是第一位到第八位,段选信号与位选信号分别接到单片机的不同输出口,例如段选信号可以接到P0口,位选信号可以接到P2口,共阳极的字形显示代码为: Uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}.位选信号代码为:uchar Digits[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};当选中第一位时,段选信号就执行从0到九的显示。 3.4 8155串行口扩展电路 图3-4 串行口扩展电路图本次实验所用的试验箱内部已经接好8155的扩展电路,8155是一个有40引脚的塑封芯片,功能较强,广泛的应用在计算机电路中。它有两个8位口A、B和一个6位口C,总共可以扩展出22条接线。它含一个可预置的计数器,计数范围从2到16383,可用于延时、计数或分频。它内部还有256字节的RAM,可以补充CPU内存的不足。为了能够设置芯片的工作方式和了解芯片的状态,内部还有命令寄存器和状态寄存器。图1为8155的引脚图。其中,与 CPU相连的引脚有:CE是片选信号,当CE=0时,芯片才与CPU交换信息。CE接到地址译码器上,由整个系统分配给高位地址,以保证任何时刻只有一个芯片可与CPU交换信息,不发生地址冲突;IO/M是接口或内部RAM寄存器的选择线。当IO/M=1时,CPU是对I/O接口操作,当IO/M=0时,CPU 是对RAM进行操作,它一般接到CPU的地址线A8上;AD0~AD7为地址数据总线;ALE 是地址锁存信号输入线;RD、WR分别是读、写控制线;RESET是复位线。当RESET=1时,8155被复位。与外部设备连接的引脚有:TMRIN(timerin)是计数输入线;接到待测的脉冲源;TMROUT(timerout)是计数输出线;PA0~PA7为A口的8位输入/输出线;PB0~PB7为B口的8位输入/输出线;PC0~PC5为C口的6位输入/输出线。各接口的工作方式由控制命令决定。 8155各引脚功能说明如下:RST:复位信号输入端,高电平有效。复位后,3个I/O口均为输入方式。AD0~AD7:三态的地址/数据总线。与单片机的低8位地址/数据总线(P0口)相连。单片机与8155之间的地址、数据、命令与状态信息都是通过这个总线口传送的。RD:读选通信号,控制对8155的读操作,低电平有效。WR:写选通信号,控制对8155的写操作,低电平有效。CE:片选信号线,低电平有效。IO/M :8155的RAM存储器或I/O口选择线。当IO/M =0时,则选择8155的片内RAM,AD0~AD7上地址为8155中RAM单元的地址(00H~FFH);当IO/M =1时,选择 8155的I/O口,AD0~AD7上的地址为8155 I/O口的地址。ALE:地址锁存信号。8155内部设有地址锁存器,在ALE的下降沿将单片机P0口输出的低8位地址信息及 ,IO/ 的状态都锁存到8155内部锁存器。因此,P0口输出的低8位地址信号不需外接锁存器。PA0~PA7:8位通用I/O口,其输入、输出的流向可由程序控制。PB0~PB7:8位通用I/O口,功能同A口。PC0~PC5:有两个作用,既可作为通用的I/O口,也可作为PA口和PB口的控制信号线,这些可通过程序控制。TIMER IN:定时/计数器脉冲输入端。TIMER OUT:定时/计数器输出端。VCC:+5V电源。(1) 压力传感器的选定 3.5 总设计图 图3-5 总设计图4. 系统程序设计 4.1 主程序流程图 
图4-1 主程序流程图 系统工作流程:(1)用菊阳仿真器使程序处于连续运行状态 (2)显示模块显示当前楼层,主程序不断地执行键盘扫描程序,当有键盘输入时,主程序调用定时器中断程序,并通过行列扫描方式读取到是哪个键盘输入。 (3)读取到键盘之后,主程序调用显示子程序,通过显示上下和当前楼层信息和LED输出当前按下键的信息以及开关门的信息向操作人员传递信息。 系统主程序流程图如图4-1所示。 4.2 定时器子程序流程图 图4-1 定时器程序流程图 定时器子程序主要任务是完成3秒的定时,使显示模块能保持一段时间,使人能够观察到具体信息。如果没有这一模块,靠系统时钟来控制,一些中间过程根本看不出来,也给软件仿真和硬件仿真带来不小的困难。 4.3 扫描子程序流程图 扫描子程序主要任务是通过行列扫描方式确定具体键盘的输入,先让PA口输出低电平,逐行扫描,直到能确定哪行有输入,然后读取PC口的信息,再与设定值进行比较,最后通过选择环节,确定最终的键盘号,如proteus图中所示,PC0-PC3作为行线,PA0-PA2作为列线,相互配合完成扫描确认工作,最终转到输出子程序并将所输入的信息转化为具体的上下和数字输出,完成键盘扫描子程序的基本任务。 
图4-2 键盘扫描流程图 控制子程序流程图如图4-2所示。 4.4 显示子程序流程图 
图4-4 显示子程序流程图 4.5 延时流程图 图4-5 延时程序流程图 5. 系统调试 5.1 Proteus软件仿真调试 系统初始状态在意、1楼等候,以下为遇到的情况: (1)当按下2楼上,显示栏会显示上和上到2楼的信息,同时到2楼之后,开门LED会同时点亮。上楼按法和显示同上。 (2)当楼层上升到4楼,按下下楼按键,显示栏会显示经过的楼层以及到达楼层,同时LED在开门时会点亮,下楼按法和显示同上。 (3)当在电梯外部按完,开门LED点亮之后,接下来按你所要去的楼层,到达目标楼层之后,开门LED会点亮,同时显示上下和楼层信息。 调试中所遇到的问题: ( 1 )键盘不能被键盘扫描程序读取,最终发现是没有接上拉电阻,接上上拉电阻模块之后,键盘可以可靠地被扫描 (2)8155不能正常扩展电路,8155片选端要接低电平才能有效片选。 5.2 硬件调试 内1(7键)内2(1键)内3(TV键)内4(F1键) 1上(4键)2上(0键)3上(RG键) 2下(2键)3下(EX键)4下(SETP键)按下相应键盘显示上下及楼层信息。
7.小结
通过此次电梯控制系统的设计,我收获颇丰。设计的核心内容就是利用单片机C51的编程来实现控制外围各电路的运行。通过本次设计,我熟练掌握了程控系统设计的一般步骤,熟悉了编程软件的用法,并对编程能力起到了一定的提高作用。
感谢学校给我们这次机会,锻炼了我们的动手能力及运用专业软件的能力。通过这次课设让我明白了理论和实际操作之间差距,而且也让我很明确得意识到自己在数电上有很多的知识漏洞,以后应该多钻研一下。这次课程设计我主要负责文论撰写,在写论文过程中积极和同组同学探讨电梯的基本原理,每个模块的功能及如何实现。对Office套件的使用更熟悉,为以后毕业论文的撰写奠定了一定基础。最后再次感谢这次课程设计。
6. 程序清单 - #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){
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
全部资料51hei下载地址(内附仿真图与源程序+word格式的完整报告文档):
四层电梯最终版11.zip
(1.07 MB, 下载次数: 856)
|