硬件课程设计 代码备份

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

#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口数据失败\n");
        return -1;
    }
    if(!PortReadByte(port_8255c, &data)) {
        printf("读取数据失败\n");
        return -1;
    }
    //printf("data: %d\n", 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\n", row, col);
    data = row + col;
    // printf("data : %d \n", data);
    int c = getKey(data);
    if(c == -1) {
        return -1; 
    }
    printf("pressKey value:%d\n", 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\n",now);      
    return ;
}

int buf = 0x33;
// 电机正反转 flag为true时 反转, 否则正转
void zhuan(bool flag) 
{
    // PortWriteByte(port_8255ctl, 0x80); //B口输出 10000000 
    int cnt = 15;
    int d = 30;
    while(cnt--) {
        if(d != 0) {
            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++) {
        // 电机正转
        zhuan(false);
        clear();
        PortWriteByte(port_8255a, 0x90);
        cmdsetup();
        Sleep(10);
        for (int j=0; j<10; j++){
            PortWriteByte(port_8255a, lcdup[j]);
            datasetup();
        }
        // Sleep(10);
        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\n", nxt);
        Sleep(50);
        // 换行  
        // PortWriteByte(port_8255a,0x88);
        // cmdsetup();
    }
    // stop_dianji();
    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); 换成步进电机
        int cnt = 20;
        while(cnt--) {
            zhuan(true);
        }
        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\n", nxt);
        Sleep(50);
    }
    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);
                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;
                }
                Sleep(100);
            } 
            // 电梯正在上升
            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 ;
}

猜你喜欢

转载自www.cnblogs.com/Draymonder/p/10022542.html
今日推荐