基于单片机的电梯控制系统(八楼控制+LCD1602+L298N+点击+按键+原理图、源代码、proteus仿真、动画)

基于单片机的电梯控制系统,可实现八楼的电梯控制。并通过LCD显示电梯状态,通过蜂鸣器提示楼层到达。

/*
*  基于单片机的电梯控制模块设计
*  CPU:STC89C52RC
*  晶振:11.0592MHZ
*  算法核心:
*    电梯如果停在四楼, 一楼和七楼如果同时有人按了,
*    这种情况下, 取决于前一次的状态,
*    如果处于向下的过程中, 则继续向下, 先到达一楼,
*    即 保持电梯之前的状态不变.
*  程序特色:
*    1.支持同时按下多个楼层
*    2.支持取消楼层
*/

#include "main.h"
#include "LCD1602.h"
#include "Key.h"
#include "L298N.h"
#include "Timer.h"

// 代表电梯当前所在的楼层,初始在1楼
uchar currentFloor=1;

// 存储每楼层的状态,代表是否需要开门
uchar floorStatus[9] = {0};

// 存储楼层对应的按键码,第i层的按键码为FloorData[i]
uchar code FloorData[] = {Floor_No,Floor_1,Floor_2,Floor_3,Floor_4,Floor_5,Floor_6,Floor_7,Floor_8};

// 电梯当前的状态
enum FloorDirection floorDir=Stop;

// 电梯之前的状态
enum FloorDirection lastDir=UP;

// 系统计时时钟
extern unsigned char clock;

// 延时 z ms
void delay_ms(uint z)
{
    uint x, y;
    for (x = z; x>0; x--)
        for (y = 114; y>0; y--);
}

// 主函数
void main()
{
    int keyStatus=Floor_No;
    int i=0;
    
    // 初始化液晶
    init_LCD();
    
    // 初始化定时
    InitTimer0();
    while(1)
    {
        keyStatus = keyScan();
        
        // 判断当前是否有楼层被按下, 支持多个楼层同时按下
        for(i=1; i<=8; i++)
        {
            // 解析按下的楼层数据, 将对应楼层被按下的标志取反, 相当于 提供取消按键的功能
            if ((keyStatus|FloorData[i]) == FloorData[i])
                floorStatus[i] = !floorStatus[i];
        }
        // 在液晶的第一行显示
        write_com(0x80);
        
        // 显示当前所在的楼层
        LCD_ShowStr("Floor:");
        write_date(currentFloor+'0');
        write_date(' ');
        
        for(i=1; i<=8; i++)
        {
            // 显示需要开门的楼层
            if (floorStatus[i])
                write_date(i+'0');
        }
        LCD_ShowStr("              ");
        
        // 如果前一次处于上升状态 判断当前楼层到顶楼之中是否有楼层按下
        if ((lastDir == UP || floorDir == Stop) && (lastDir != Down))
        {
            for(i=currentFloor; i<=8; i++)
            {
                // 有楼层被按下
                if(floorStatus[i] == 1)
                {
                    // 当前所在的楼层需要开门
                    if (i == currentFloor)
                    {
                        if (clock == 0)
                        {
                            floorDir = Open;
                            break;
                        }
                    }
                    else
                    {
                        floorDir = UP;
                        lastDir  = UP;
                        break;
                    }
                }
            }
            // 如果没有高楼层被按下
            if (i >= 9)
                lastDir = Down;
        }
        // 如果前一次处于下降状态 判断当前楼层到底楼之中是否有楼层按下
        if ((lastDir == Down || floorDir == Stop) && (lastDir != UP))
        {
            for(i=currentFloor; i>=1; i--)
            {
                // 有楼层被按下
                if(floorStatus[i] == 1)
                {
                    // 当前所在的楼层需要开门
                    if (i == currentFloor)
                    {
                        if (clock == 0)
                        {
                            floorDir = Open;
                            break;
                        }
                    }
                    else
                    {
                        floorDir = Down;
                        lastDir  = Down;
                        break;
                    }
                }
            }
            // 如果没有高楼层被按下
            if (i <= 0)
                lastDir = UP;
        }
        // 在液晶的第二行显示
        write_com(0x80+0x40);
        switch(floorDir)
        {
        case UP:    // 0-向上
            TR0 = 1;    // 定时器0 打开
            LCD_ShowStr("Up   ");

            // 电梯上升
            L298N_UP();
            break;
        
        case Down:   // 1-向下
            TR0 = 1;    // 定时器0 打开
            LCD_ShowStr("Down ");

            // 电梯下降
            L298N_Down();
            break;
        
        case Stop:   // 2-停止
            TR0 = 0;    // 定时器0 打开
            LCD_ShowStr("Stop ");

            // 电梯停止
            L298N_Stop();
            break;

        case Open:   // 3-开门
            TR0 = 1;    // 定时器0 打开
            LCD_ShowStr("Open ");

            // 电梯停止
            L298N_Stop();
            if (clock == 0)
            {
                // 蜂鸣器响
                Beep = 0;
                delay_ms(300);
                Beep = 1;
            }

            // 关门后,将对应的标志置0,表示不再需要开门
            floorStatus[currentFloor] = 0;
            break;
        
        case Close:  // 4-关门
            TR0 = 1;    // 定时器0 打开
            LCD_ShowStr("Close");
            // 电梯停止
            L298N_Stop();
            break;
        }
    }
}
 

  • 19
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cqtianxingkeji

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值