1. 程式人生 > >硬體課程設計 程式碼備份

硬體課程設計 程式碼備份

版本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 ; }