• 硬件课程设计 代码备份


    版本V1.0

    1. 实现电梯可以多个人 上下不同楼层, 如果先按照 1 - 9 - 6 则电梯会在6层停靠后继续上升到9层

    2. 使电梯运转更为流畅 

      #include <stdio.h>
    #include <conio.h>
    #include "ApiExusb.h"
    #pragma comment(lib, "ApiExusb.lib")
    
    #define Max(a,b) ((a>b)?a:b)
    #define Min(a,b) ((a<b)?a:b)
    
    int keyword[10]={126, 0134, 138, 140, 190, 198, 202, 204, 222, 230};
    char lcd2[16]={0xb5, 0xb1, 0xc7, 0xb0, 0xc2, 0xa5, 0xb2, 0xe3, 0xa3, 0xba};
    
    char lcdup[10]={0xb5, 0xe7, 0xcc, 0xdd, 0xc9, 0xcf, 0xc9, 0xfd, 0xa1, 0xfc};
    char lcddown[10]={0xb5, 0xe7, 0xcc, 0xdd, 0xcf, 0xc2, 0xbd, 0xb5, 0xa1, 0xfd};
    
    char lcdNum[18]={0xa2, 0xb1, 0xa2, 0xb2, 0xa2, 0xb3, 0xa2, 0xb4, 0xa2, 0xb5,
                        0xa2, 0xb6, 0xa2, 0xb7,0xa2, 0xb8, 0xa2, 0xb9};
    
    int port_8255a, port_8255b, port_8255c, port_8255ctl;
    
    bool vis[10];
    
    // 获取当前数组中的最大值,如若没有就是-1
    int getMax()
    {
        int res = -1;
        for(int i=0; i<10; i++) {
            if(vis[i]) 
                res = Max(i, res);
        }
        return res;
    }
    
    // 获取当前数组中的最大值,如若没有就是-1
    int getMin()
    {
        int res = 10;
        for(int i=0; i<10; i++) {
            if(vis[i])
                res = Min(i, res);
        }
        if(i == res) 
            return -1;
        return res;
    }
    
    // 初始化端口 
    void initPortAndArray()
    {
        port_8255a = 0x288;
        port_8255b = 0x289;
        port_8255c = 0x28a;
        port_8255ctl = 0x28B;
        for(int i=0; i<10; i++) 
            vis[i] = 0;
    }
    
    // 获取按键的键值 
    int getKey(int data)
    {
        for(int i=0; i<10; i++) {
            if(keyword[i] == data) {
                return i;
            }
        }
        return -1;
    }
    
    // 返回按键值  如果为-1 则读取失败 否则成功返回按的键盘
    int pressKey()
    {
        if(!PortWriteByte(port_8255ctl, 0x81)) { //c 0-3 in   4-7 out
            puts("控制字没有写成功");
            return -1;
        }
        byte data;
        if(!PortWriteByte(port_8255c, 0x0F)) {
            printf("写C口数据失败
    ");
            return -1;
        }
        if(!PortReadByte(port_8255c, &data)) {
            printf("读取数据失败
    ");
            return -1;
        }
        //printf("data: %d
    ", data);
        
        if(data == 0x0F) {
               //puts("还没有按键");
               return -1;
        }
        byte col = data;
        if(!PortWriteByte(port_8255ctl, 0x88)) { //c 0-3 out   4-7 in
            puts("控制字没有写成功");
            return -1;
        }
        PortWriteByte(port_8255c, col);
        byte row;
        PortReadByte(port_8255c, &row);
        // printf("row %d  col %d
    ", row, col);
        data = row + col;
        // printf("data : %d 
    ", data);
        int c = getKey(data);
        if(c == -1) {
            return -1; 
        }
        printf("pressKey value:%d
    ", c);
        return c;
    }
    
    // lcd128写命令 
    void cmdsetup()
    {
        PortWriteByte(port_8255b,0x00);
        Sleep(1);
        PortWriteByte(port_8255b,0x04);
        Sleep(1);
        PortWriteByte(port_8255b,0x00);
        Sleep(1);
    }
    
    // lcd128写数据 
    void datasetup()
    {
        PortWriteByte(port_8255b,0x01);
        Sleep(1);
        PortWriteByte(port_8255b,0x05);
        Sleep(1);
        PortWriteByte(port_8255b,0x01);
        Sleep(1);
    }
    
    // lcd清屏 
    void clear()
    {
        PortWriteByte(port_8255a,0x0c);
        cmdsetup();
    }
    
    //显示器 显示当前楼层 如果为-1则 显示失败 否则 显示成功
    void printFloor(int now)
    {    
        PortWriteByte(port_8255ctl, 0x80);
        clear();
        PortWriteByte(port_8255a,0x90);
        cmdsetup();
        Sleep(10);
        for (int i=0;i<10;i++){
            PortWriteByte(port_8255a,lcd2[i]);
            datasetup();
        };
        byte c1 = lcdNum[2* (now - 1)];
        byte c2 = lcdNum[2* now - 1];
        PortWriteByte(port_8255a,c1);
        datasetup();  
        PortWriteByte(port_8255a,c2);
        datasetup();  
        //PortWriteByte(port_8255a,0x88);
        //cmdsetup();
        Sleep(10);
        
        printf("当前楼层 %d
    ",now);      
        return ;
    }
    
    int buf = 0x33;
    // 电机正反转 flag为true时 反转, 否则正转
    void zhuan(bool flag) 
    {
        // PortWriteByte(port_8255ctl, 0x80); //B口输出 10000000 
        int cnt = 70;
        if(!flag) cnt = 50;
        int d = 20;
        while(cnt--) {
            Sleep(d);
            if(flag) 
                buf = ((buf&1)<<7)|(buf>>1);
            else  // 正转 
                buf = ((buf&128)>>7)|(buf<<1);
            PortWriteByte(port_8255b, buf);       
        }
    }
    
    // 电机停止转动 
    void stop_dianji()
    {
        PortWriteByte(port_8255b,0xff);
    }
    
    // 显示器输出从from到to的上升过程 
    void up_print(int from, int to) 
    {
        PortWriteByte(port_8255ctl, 0x80);
        int step = to - from;
        for(int i=0; i<step; i++) {
            // 电机正转
            
            clear();
            PortWriteByte(port_8255a, 0x90);
            cmdsetup();
            Sleep(10);
            for (int j=0; j<10; j++){
                PortWriteByte(port_8255a, lcdup[j]);
                datasetup();
            };
            int nxt = from+i+1;
            byte c1 = lcdNum[2* (nxt - 1)];
            byte c2 = lcdNum[2* nxt - 1];
            PortWriteByte(port_8255a,c1);
            datasetup();  
            PortWriteByte(port_8255a,c2);
            datasetup();  
            PortWriteByte(port_8255a,0x88);
            cmdsetup();
            Sleep(10);
            printf("当前楼层 %d
    ", nxt);
            //Sleep(300);
            zhuan(false);
        }
        return ;
    } 
    
    //从from到to的下降过程
    void down_print(int from, int to) 
    {
        PortWriteByte(port_8255ctl, 0x80);
        int step = -(to - from);
        for(int i=0; i<step; i++) {
            // Sleep(1000); 换成步进电机
            clear();
            PortWriteByte(port_8255a, 0x90);
            cmdsetup();
            Sleep(10);
            for (int j=0; j<10; j++){
                PortWriteByte(port_8255a, lcddown[j]);
                datasetup();
            };
            int nxt = from-i-1;
            byte c1 = lcdNum[2* (nxt - 1)];
              byte c2 = lcdNum[2* nxt - 1];
              PortWriteByte(port_8255a,c1);
                datasetup();  
                PortWriteByte(port_8255a,c2);
            datasetup();  
            PortWriteByte(port_8255a,0x88);
            cmdsetup();
            Sleep(10);
            printf("当前楼层 %d
    ", nxt);
            zhuan(true);
        }
        //stop_dianji();
        return ;
    } 
    
    void main()
    {
        if(!Startup()) {
            puts("启动失败,请检查设备情况");
            return ;
        }
        // 初始化端口以及vis数组
        initPortAndArray();
        // 定义当前楼层 并且打印当前楼层
        int now = 1;
        printFloor(now);
        // 判断方向上升还是下降 为0 表示不动 为1表示上升  为-1表示下降
        int dir = 0; 
        // 判断电梯是否在运行,刚开始没运行
        bool running = false;
        while(!kbhit()) {
            // 定义按下的键值
            int nxt = pressKey();
            // 当前电梯没有运行下的情况
            if(running == false) {
                if(nxt == -1 || now == nxt) {
                    continue;
                }
                else {
                    vis[nxt] = 1;
                    dir = ((now > nxt) ? -1 : 1);
                    running = true; 
                    if(dir > 0) {
                        up_print(now, now+1);
                        now++;
                    }
                    else if(dir < 0){
                        down_print(now, now-1);
                        now--;
                    }
                }
            } // 电梯当前正在运行过程中
            else {
                // 当前已经到目标了
                if(vis[now] == 1) {
                    vis[now] = 0;
                    printFloor(now);
                    printf("已经到达楼层%d了
    ", now);
                    Sleep(1500);
                if(dir > 0) {
                        int mx = getMax();
                        if(mx == -1) {
                            running = false;
                            dir = 0;
                        }
                        else if(mx != -1 && mx < now) {
                            running = false;
                            dir = 0;
                        }
                    }
                    else if(dir < 0) {
                        int mn = getMin();
                        if(mn == -1) 
                            running = false;
                        else if(mn != -1 && mn > now) 
                            running = false;
                        if(running == false)
                            dir = 0;
                    }
                    
                } 
                // 电梯正在上升
                if(dir > 0) {
                    if(nxt != -1 && nxt > now) {
                        vis[nxt] = 1;
                    }
                    up_print(now, now+1);
                    now++;
    
                } //电梯正在下降
                else if(dir < 0) {
                    if(nxt != -1 && nxt < now) {
                        vis[nxt] = 1;
                    }
                    down_print(now, now-1);
                    now--;
                }
            }
        }
        Cleanup();
        return ;
    }
    电梯 v1.0

    版本V1.1

    1. 实现电梯 即时响应(即运行时按任何键 都能响应相应的键值)

    2. 增加电梯优化, 运行更为流畅

      #include <stdio.h>
    #include <conio.h>
    #include "ApiExusb.h"
    #pragma comment(lib, "ApiExusb.lib")
    
    #define Max(a,b) ((a>b)?a:b)
    #define Min(a,b) ((a<b)?a:b)
    
    int keyword[10]={126, 0134, 138, 140, 190, 198, 202, 204, 222, 230};
    char lcd2[16]={0xb5, 0xb1, 0xc7, 0xb0, 0xc2, 0xa5, 0xb2, 0xe3, 0xa3, 0xba};
    
    char lcdup[10]={0xb5, 0xe7, 0xcc, 0xdd, 0xc9, 0xcf, 0xc9, 0xfd, 0xa1, 0xfc};
    char lcddown[10]={0xb5, 0xe7, 0xcc, 0xdd, 0xcf, 0xc2, 0xbd, 0xb5, 0xa1, 0xfd};
    
    char lcdNum[18]={0xa2, 0xb1, 0xa2, 0xb2, 0xa2, 0xb3, 0xa2, 0xb4, 0xa2, 0xb5,
                        0xa2, 0xb6, 0xa2, 0xb7,0xa2, 0xb8, 0xa2, 0xb9};
    
    int port_8255a, port_8255b, port_8255c, port_8255ctl;
    
    bool vis[10];
    
    // 获取当前数组中的最大值,如若没有就是-1
    int getMax()
    {
        int res = -1;
        for(int i=0; i<10; i++) {
            if(vis[i]) 
                res = Max(i, res);
        }
        return res;
    }
    
    // 获取当前数组中的最大值,如若没有就是-1
    int getMin()
    {
        int res = 10;
        for(int i=0; i<10; i++) {
            if(vis[i])
                res = Min(i, res);
        }
        if(i == res) 
            return -1;
        return res;
    }
    
    // 初始化端口 
    void initPortAndArray()
    {
        port_8255a = 0x288;
        port_8255b = 0x289;
        port_8255c = 0x28a;
        port_8255ctl = 0x28B;
        for(int i=0; i<10; i++) 
            vis[i] = 0;
    }
    
    // 获取按键的键值 
    int getKey(int data)
    {
        for(int i=0; i<10; i++) {
            if(keyword[i] == data) {
                return i;
            }
        }
        return -1;
    }
    
    // 返回按键值  如果为-1 则读取失败 否则成功返回按的键盘
    int pressKey()
    {
        if(!PortWriteByte(port_8255ctl, 0x81)) { //c 0-3 in   4-7 out
            puts("控制字没有写成功");
            return -1;
        }
        byte data;
        if(!PortWriteByte(port_8255c, 0x0F)) {
            printf("写C口数据失败
    ");
            return -1;
        }
        if(!PortReadByte(port_8255c, &data)) {
            printf("读取数据失败
    ");
            return -1;
        }
        //printf("data: %d
    ", data);
        
        if(data == 0x0F) {
               //puts("还没有按键");
               return -1;
        }
        byte col = data;
        if(!PortWriteByte(port_8255ctl, 0x88)) { //c 0-3 out   4-7 in
            puts("控制字没有写成功");
            return -1;
        }
        PortWriteByte(port_8255c, col);
        byte row;
        PortReadByte(port_8255c, &row);
        // printf("row %d  col %d
    ", row, col);
        data = row + col;
        // printf("data : %d 
    ", data);
        int c = getKey(data);
        if(c == -1) {
            return -1; 
        }
        printf("pressKey value:%d
    ", c);
        return c;
    }
    
    // lcd128写命令 
    void cmdsetup()
    {
        PortWriteByte(port_8255b,0x00);
        Sleep(1);
        PortWriteByte(port_8255b,0x04);
        Sleep(1);
        PortWriteByte(port_8255b,0x00);
        Sleep(1);
    }
    
    // lcd128写数据 
    void datasetup()
    {
        PortWriteByte(port_8255b,0x01);
        Sleep(1);
        PortWriteByte(port_8255b,0x05);
        Sleep(1);
        PortWriteByte(port_8255b,0x01);
        Sleep(1);
    }
    
    // lcd清屏 
    void clear()
    {
        PortWriteByte(port_8255a,0x0c);
        cmdsetup();
    }
    
    //显示器 显示当前楼层 如果为-1则 显示失败 否则 显示成功
    void printFloor(int now)
    {    
        PortWriteByte(port_8255ctl, 0x80);
        clear();
        PortWriteByte(port_8255a,0x90);
        cmdsetup();
        Sleep(10);
        for (int i=0;i<10;i++){
            PortWriteByte(port_8255a,lcd2[i]);
            datasetup();
        };
        byte c1 = lcdNum[2* (now - 1)];
        byte c2 = lcdNum[2* now - 1];
        PortWriteByte(port_8255a,c1);
        datasetup();  
        PortWriteByte(port_8255a,c2);
        datasetup();  
        //PortWriteByte(port_8255a,0x88);
        //cmdsetup();
        Sleep(10);
        
        printf("当前楼层 %d
    ",now);      
        return ;
    }
    
    int buf = 0x33;
    // 电机正反转 flag为true时 反转, 否则正转
    void zhuan(bool flag) 
    {
        // PortWriteByte(port_8255ctl, 0x80); //B口输出 10000000 
        int cnt = 70;
        if(!flag) cnt = 50;
        int d = 20;
        while(cnt--) {
            Sleep(d);
            if(flag) 
                buf = ((buf&1)<<7)|(buf>>1);
            else  // 正转 
                buf = ((buf&128)>>7)|(buf<<1);
            PortWriteByte(port_8255b, buf);       
        }
    }
    
    // 电机停止转动 
    void stop_dianji()
    {
        PortWriteByte(port_8255b,0xff);
    }
    
    // 显示器输出从from到to的上升过程 
    void up_print(int from, int to) 
    {
        PortWriteByte(port_8255ctl, 0x80);
        int step = to - from;
        for(int i=0; i<step; i++) {
            // 电机正转
            
            clear();
            PortWriteByte(port_8255a, 0x90);
            cmdsetup();
            Sleep(10);
            for (int j=0; j<10; j++){
                PortWriteByte(port_8255a, lcdup[j]);
                datasetup();
            };
            int nxt = from+i+1;
            byte c1 = lcdNum[2* (nxt - 1)];
            byte c2 = lcdNum[2* nxt - 1];
            PortWriteByte(port_8255a,c1);
            datasetup();  
            PortWriteByte(port_8255a,c2);
            datasetup();  
            PortWriteByte(port_8255a,0x88);
            cmdsetup();
            Sleep(10);
            printf("当前楼层 %d
    ", nxt);
            //Sleep(300);
            zhuan(false);
        }
        return ;
    } 
    
    //从from到to的下降过程
    void down_print(int from, int to) 
    {
        PortWriteByte(port_8255ctl, 0x80);
        int step = -(to - from);
        for(int i=0; i<step; i++) {
            // Sleep(1000); 换成步进电机
            clear();
            PortWriteByte(port_8255a, 0x90);
            cmdsetup();
            Sleep(10);
            for (int j=0; j<10; j++){
                PortWriteByte(port_8255a, lcddown[j]);
                datasetup();
            };
            int nxt = from-i-1;
            byte c1 = lcdNum[2* (nxt - 1)];
              byte c2 = lcdNum[2* nxt - 1];
              PortWriteByte(port_8255a,c1);
                datasetup();  
                PortWriteByte(port_8255a,c2);
            datasetup();  
            PortWriteByte(port_8255a,0x88);
            cmdsetup();
            Sleep(10);
            printf("当前楼层 %d
    ", nxt);
            zhuan(true);
        }
        //stop_dianji();
        return ;
    } 
    
    void main()
    {
        if(!Startup()) {
            puts("启动失败,请检查设备情况");
            return ;
        }
        // 初始化端口以及vis数组
        initPortAndArray();
        // 定义当前楼层 并且打印当前楼层
        int now = 1;
        printFloor(now);
        // 判断方向上升还是下降 为0 表示不动 为1表示上升  为-1表示下降
        int dir = 0; 
        // 判断电梯是否在运行,刚开始没运行
        bool running = false;
        while(!kbhit()) {
            // 定义按下的键值
            int nxt = pressKey();
            // 当前电梯没有运行下的情况
            if(running == false) {
                if(nxt == -1 || now == nxt) {
                    continue;
                }
                else {
                    vis[nxt] = 1;
                    dir = ((now > nxt) ? -1 : 1);
                    running = true; 
                    if(dir > 0) {
                        up_print(now, now+1);
                        now++;
                    }
                    else if(dir < 0){
                        down_print(now, now-1);
                        now--;
                    }
                }
            } // 电梯当前正在运行过程中
            else {
                // 当前已经到目标了
                if(vis[now] == 1) {
                    vis[now] = 0;
                    printFloor(now);
                    printf("已经到达楼层%d了
    ", now);
                    Sleep(1500);
                }
                // 当前按键 可达 
                if(nxt != -1 && nxt != now) {
                    vis[nxt] = 1;
                }
                
                // 电梯向上 
                if(dir > 0) {
                    int mx = getMax();
                    // 当前没有需要响应的楼层了,等待键盘监听 
                    if(mx == -1) {
                        running = false;
                        dir = 0;
                    }// 当前有比当前更高的楼层  因此继续往上 
                    else if(mx != -1 && mx > now) {
                        running = true;
                        dir = 1;
                    }// 当前没有比当前更高的楼层了   但有比当前楼层低的楼层需要到达  因此往上走 
                    else if(mx != -1 && mx < now) {
                        running = true;
                        dir = -1;
                    }
                } //电梯向下 
                else if(dir < 0) {
                    int mn = getMin();
                    // 当前没有需要响应的楼层了,等待键盘监听 
                    if(mn == -1) {
                        running = false;
                        dir = 0;
                    } // 当前有比当前更小的楼层  因此继续往下 
                    else if(mn != -1 && mn < now) {
                        running = true;
                        dir = -1;
                    } // 当前没有比当前更小的楼层了   但有比当前楼层高的楼层需要到达  因此往上走 
                    else if(mn != -1 && mn > now) {
                        running = true;
                        dir = 1; 
                    }
                } 
                
                // 电梯正在上升
                if(dir > 0) {
                    up_print(now, now+1);
                    now++;
    
                } //电梯正在下降
                else if(dir < 0) {
                    down_print(now, now-1);
                    now--;
                }
            }
        }
        Cleanup();
        return ;
    }
    电梯 v1.1

    版本V1.2

    1.新增电梯运行 灯光闪烁

    2.新增电梯闲置 灯光闪烁

     #include <stdio.h>
    #include <conio.h>
    #include "ApiExusb.h"
    #pragma comment(lib, "ApiExusb.lib")
    
    #define Max(a,b) ((a>b)?a:b)
    #define Min(a,b) ((a<b)?a:b)
    
    int keyword[10]={126, 134, 138, 140, 190, 198, 202, 204, 222, 230};
    char lcd2[16]={0xb5, 0xb1, 0xc7, 0xb0, 0xc2, 0xa5, 0xb2, 0xe3, 0xa3, 0xba};
    
    char lcdup[10]={0xb5, 0xe7, 0xcc, 0xdd, 0xc9, 0xcf, 0xc9, 0xfd, 0xa1, 0xfc};
    char lcddown[10]={0xb5, 0xe7, 0xcc, 0xdd, 0xcf, 0xc2, 0xbd, 0xb5, 0xa1, 0xfd};
    
    char lcdNum[18]={0xa2, 0xb1, 0xa2, 0xb2, 0xa2, 0xb3, 0xa2, 0xb4, 0xa2, 0xb5,
                        0xa2, 0xb6, 0xa2, 0xb7,0xa2, 0xb8, 0xa2, 0xb9};
    
    int port_8255a, port_8255b, port_8255c, port_8255ctl;
    
    bool vis[10];
    
    // 获取当前数组中的最大值,如若没有就是-1
    int getMax()
    {
        int res = -1;
        for(int i=0; i<10; i++) {
            if(vis[i]) 
                res = Max(i, res);
        }
        return res;
    }
    
    // 获取当前数组中的最大值,如若没有就是-1
    int getMin()
    {
        int res = 10;
        for(int i=0; i<10; i++) {
            if(vis[i])
                res = Min(i, res);
        }
        if(i == res) 
            return -1;
        return res;
    }
    
    // 初始化端口 
    void initPortAndArray()
    {
        port_8255a = 0x288;
        port_8255b = 0x289;
        port_8255c = 0x28a;
        port_8255ctl = 0x28B;
        for(int i=0; i<10; i++) 
            vis[i] = 0;
    }
    
    // 获取按键的键值 
    int getKey(int data)
    {
        for(int i=0; i<10; i++) {
            if(keyword[i] == data) {
                return i;
            }
        }
        return -1;
    }
    
    // 返回按键值  如果为-1 则读取失败 否则成功返回按的键盘
    int pressKey()
    {
        if(!PortWriteByte(port_8255ctl, 0x81)) { //c 0-3 in   4-7 out
            puts("控制字没有写成功");
            return -1;
        }
        byte data;
        if(!PortWriteByte(port_8255c, 0x0F)) {
            printf("写C口数据失败
    ");
            return -1;
        }
        if(!PortReadByte(port_8255c, &data)) {
            printf("读取数据失败
    ");
            return -1;
        }
        //printf("data: %d
    ", data);
        
        if(data == 0x0F) {
               //puts("还没有按键");
               return -1;
        }
        byte col = data;
        if(!PortWriteByte(port_8255ctl, 0x88)) { //c 0-3 out   4-7 in
            puts("控制字没有写成功");
            return -1;
        }
        PortWriteByte(port_8255c, col);
        byte row;
        PortReadByte(port_8255c, &row);
        // printf("row %d  col %d
    ", row, col);
        data = row + col;
        // printf("data : %d 
    ", data);
        int c = getKey(data);
        if(c == -1) {
            return -1; 
        }
        printf("pressKey value:%d
    ", c);
        return c;
    }
    
    // lcd128写命令 
    void cmdsetup()
    {
        PortWriteByte(port_8255b,0x00);
        Sleep(1);
        PortWriteByte(port_8255b,0x04);
        Sleep(1);
        PortWriteByte(port_8255b,0x00);
        Sleep(1);
    }
    
    // lcd128写数据 
    void datasetup()
    {
        PortWriteByte(port_8255b,0x01);
        Sleep(1);
        PortWriteByte(port_8255b,0x05);
        Sleep(1);
        PortWriteByte(port_8255b,0x01);
        Sleep(1);
    }
    
    // lcd清屏 
    void clear()
    {
        PortWriteByte(port_8255a,0x0c);
        cmdsetup();
    }
    
    // 灯泡闪亮
    void shan()
    {
          PortWriteByte(port_8255ctl, 0x80);
        
            PortWriteByte(port_8255c, 0x01);
            Sleep(300);
            PortWriteByte(port_8255c, 0x00);
            PortWriteByte(port_8255c, 0x00);
            PortWriteByte(port_8255c, 0x00);    
    }
    
    //显示器 显示当前楼层 如果为-1则 显示失败 否则 显示成功
    void printFloor(int now)
    {    
        PortWriteByte(port_8255ctl, 0x80);
        clear();
        PortWriteByte(port_8255a,0x90);
        cmdsetup();
        Sleep(10);
        for (int i=0;i<10;i++){
            PortWriteByte(port_8255a,lcd2[i]);
            datasetup();
        }
        byte c1 = lcdNum[2* (now - 1)];
        byte c2 = lcdNum[2* now - 1];
        PortWriteByte(port_8255a,c1);
        datasetup();  
        PortWriteByte(port_8255a,c2);
        datasetup();  
        //PortWriteByte(port_8255a,0x88);
        //cmdsetup();   
        Sleep(10);
        printf("当前楼层 %d
    ",now);      
        shan();    
        return ;
    }
    
    int buf = 0x33;
    // 电机正反转 flag为true时 反转, 否则正转
    void zhuan(bool flag) 
    {
        // PortWriteByte(port_8255ctl, 0x80); //B口输出 10000000 
        int cnt = 70;
        if(!flag) cnt = 50;
        int d = 20;
        while(cnt--) {
            Sleep(d);
            if(flag) 
                buf = ((buf&1)<<7)|(buf>>1);
    
            else  // 正转 
                buf = ((buf&128)>>7)|(buf<<1);
            PortWriteByte(port_8255b, buf);      
        }
    
    }
    
    
    
    
    
    
    // 电机停止转动 
    
    void stop_dianji()
    
    {
        PortWriteByte(port_8255b,0xff);
    }
    
    
    
    // 显示器输出从from到to的上升过程 
    
    void up_print(int from, int to) 
    
    {
        PortWriteByte(port_8255ctl, 0x80);
        int step = to - from;
        for(int i=0; i<step; i++) {
            // 电机正转
            
            clear();
            PortWriteByte(port_8255a, 0x90);
            cmdsetup();
            Sleep(10);
            for (int j=0; j<10; j++){
                PortWriteByte(port_8255a, lcdup[j]);
                datasetup();
            };
            int nxt = from+i+1;
            byte c1 = lcdNum[2* (nxt - 1)];
            byte c2 = lcdNum[2* nxt - 1];
            PortWriteByte(port_8255a,c1);
            datasetup();  
            PortWriteByte(port_8255a,c2);
            datasetup();  
            PortWriteByte(port_8255a,0x88);
            cmdsetup();
            Sleep(10);
            printf("当前楼层 %d
    ", nxt);
            //Sleep(300);
            zhuan(false);
        }
        return ;
    } 
    
    //从from到to的下降过程
    void down_print(int from, int to) 
    {
        PortWriteByte(port_8255ctl, 0x80);
        int step = -(to - from);
        for(int i=0; i<step; i++) {
            // Sleep(1000); 换成步进电机
            clear();
            PortWriteByte(port_8255a, 0x90);
            cmdsetup();
            Sleep(10);
            for (int j=0; j<10; j++){
                PortWriteByte(port_8255a, lcddown[j]);
                datasetup();
            };
            int nxt = from-i-1;
            byte c1 = lcdNum[2* (nxt - 1)];
              byte c2 = lcdNum[2* nxt - 1];rrrrrrrrrrrrrrr
              PortWriteByte(port_8255a,c1);
                datasetup();  
                PortWriteByte(port_8255a,c2);
            datasetup();  
            PortWriteByte(port_8255a,0x88);
            cmdsetup();
            Sleep(10);
            printf("当前楼层 %d
    ", nxt);
            zhuan(true);
        }
        //stop_dianji();
        return ;
    } 
    
    void main()
    {
        if(!Startup()) {
            puts("启动失败,请检查设备情况");
            return ;
        }
        // 初始化端口以及vis数组
        initPortAndArray();
        // 定义当前楼层 并且打印当前楼层
        int now = 1;
        printFloor(now);
        // 判断方向上升还是下降 为0 表示不动 为1表示上升  为-1表示下降
        int dir = 0; 
        // 判断电梯是否在运行,刚开始没运行
        bool running = false;
        while(!kbhit()) {
            // 定义按下的键值
            int nxt = pressKey();
            // 当前电梯没有运行下的情况
            if(running == false) {
                if(nxt == -1 || now == nxt) {
                    continue;
                }
                else {
                    vis[nxt] = 1;
                    dir = ((now > nxt) ? -1 : 1);
                    running = true; 
                    if(dir > 0) {
                        up_print(now, now+1);
                        now++;
                    }
                    else if(dir < 0){
                        down_print(now, now-1);
                        now--;
                    }
                }
            } // 电梯当前正在运行过程中
            else {
                // 当前已经到目标了
                if(vis[now] == 1) {
                    vis[now] = 0;
                    printFloor(now);
                    printf("已经到达楼层%d了
    ", now);
                    Sleep(1500);
                }
                // 当前按键 可达 
                if(nxt != -1 && nxt != now) {
                    vis[nxt] = 1;
                }
                
                // 电梯向上 
                if(dir > 0) {
                    int mx = getMax();
                    // 当前没有需要响应的楼层了,等待键盘监听 
                    if(mx == -1) {
                        running = false;
                        dir = 0;
                    }// 当前有比当前更高的楼层  因此继续往上 
                    else if(mx != -1 && mx > now) {
                        running = true;
                        dir = 1;
                    }// 当前没有比当前更高的楼层了   但有比当前楼层低的楼层需要到达  因此往上走 
                    else if(mx != -1 && mx < now) {
                        running = true;
                        dir = -1;
                    }
                } //电梯向下 
                else if(dir < 0) {
                    int mn = getMin();
                    // 当前没有需要响应的楼层了,等待键盘监听 
                    if(mn == -1) {
                        running = false;
                        dir = 0;
                    } // 当前有比当前更小的楼层  因此继续往下 
                    else if(mn != -1 && mn < now) {
                        running = true;
                        dir = -1;
    
                    } // 当前没有比当前更小的楼层了   但有比当前楼层高的楼层需要到达  因此往上走 
                    else if(mn != -1 && mn > now) {
    
                        running = true;
    
                        dir = 1; 
                    }
                } 
                
                // 电梯正在上升
                if(dir > 0) {
                    up_print(now, now+1);
                    now++;
    
                } //电梯正在下降
                else if(dir < 0) {
                    down_print(now, now-1);
                    now--;
                }
            }
        }
        Cleanup();
        return ;
    }
    电梯 V1.3

    C口插键盘  

    B口第四位 LCD屏控制

    B口高四位 电机控制

    A口LCD数据写入

  • 相关阅读:
    axios、ajax、fetch三者的区别
    React与Vue的相同与不同点
    react-redux
    redux【react】
    react高阶组件
    基于WebGL无插件虚拟场景漫游关键技术(完整版)ThingJS
    基于WebGL的三维交通监控可视化技术应用(实践版) ThingJS
    地下管线监控系统中互联网WebGL三维可视化构建技术 ThingJS
    基于WebGL实现智慧校园的全景漫游技术研究 三维可视化
    基于WebGL的3D可视化告警系统关键技术解析 ThingJS
  • 原文地址:https://www.cnblogs.com/Draymonder/p/10022542.html
Copyright © 2020-2023  润新知