用點陣做的電梯 ,附帶程序和仿真
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
- #include <regx52.h>
- #define uchar unsigned char
- #define uint unsigned int
- extern void disp3216();
- extern uchar key_get();
- /* 電梯控制與傳感器信號I/O */
- sbit s1=P1^6;sbit s2=P1^7;sbit s3=P3^7;
- sbit mk1=P3^4;sbit mk2=P3^5;
- #define dtSTOP {s1=1;s2=1;}
- #define dtUP {s1=0;s2=1;}
- #define dtDOWN {s1=1;s2=0;}
- sbit dF1=P2^0;sbit dF2=P2^1;sbit dF3=P2^2;sbit dF4=P2^3;
- sbit dF5=P2^4;sbit dF6=P2^5;sbit dF7=P2^6;sbit dF8=P2^7;
- #define fSTOP 0
- #define fUP 1
- #define fDOWN 2
- uchar dir; //電梯方向,0=停,1=上行,2=下行
- uchar LCount; //樓層計數
- #define kOUT 0x01 /*請求出門*/
- #define kUP 0x08 /*請求上行*/
- #define kDOWN 0x40 /*請求下行*/
- extern uchar dispBuf[3]; //顯存
- uchar dat[8]={0,0,0,0,0,0,0,0}; //對應8~1樓,標志數據
- uchar c,t10,s,min,hor; //時鐘與定時
- //判斷是否上行
- bit UpOk(){
- switch(LCount){
- case 1:if(dat[6]&(kOUT|kUP|kDOWN))return 1;
- case 2:if(dat[5]&(kOUT|kUP|kDOWN))return 1;
- case 3:if(dat[4]&(kOUT|kUP|kDOWN))return 1;
- case 4:if(dat[3]&(kOUT|kUP|kDOWN))return 1;
- case 5:if(dat[2]&(kOUT|kUP|kDOWN))return 1;
- case 6:if(dat[1]&(kOUT|kUP|kDOWN))return 1;
- case 7:if(dat[0]&(kOUT|kDOWN))return 1;
- case 8:return 0;
- }
- return 0;
- }
- //判斷是否下行
- bit DownOk(){
- switch(LCount){
- case 8:if(dat[1]&(kOUT|kUP|kDOWN))return 1;
- case 7:if(dat[2]&(kOUT|kUP|kDOWN))return 1;
- case 6:if(dat[3]&(kOUT|kUP|kDOWN))return 1;
- case 5:if(dat[4]&(kOUT|kUP|kDOWN))return 1;
- case 4:if(dat[5]&(kOUT|kUP|kDOWN))return 1;
- case 3:if(dat[6]&(kOUT|kUP|kDOWN))return 1;
- case 2:if(dat[7]&(kOUT|kUP))return 1;
- case 1:return 0;
- }
- return 0;
- }
- //電梯到達某層時,判斷是否停下開門
- //入口:LCount當前到達層號
- //條件:梯內有出或梯外有“順向”進,則開門。
- km(){
- bit b=0; uchar i;
- if(LCount==1)dir=fUP; //最下層,方向改向上
- else if(LCount==8)dir=fDOWN; //最上層,方向改向下
- //梯內有人出
- if(kOUT==(dat[8-LCount]&kOUT)){
- dat[8-LCount]&=(~kOUT);b=1;
- if(dir==fUP&&!UpOk())dat[8-LCount]&=(~kDOWN);
- if(dir==fDOWN&&!DownOk())dat[8-LCount]&=(~kUP);
- }
- //上行時,看梯外有無人上行
- if(dir==fUP&&kUP==(dat[8-LCount]&kUP)&&LCount!=8){
- dat[8-LCount]&=(~kUP);
- if(!UpOk())dat[8-LCount]&=(~kDOWN);
- b=1;
- }
- //下行時,看梯外有無人下行
- if(dir==fDOWN&&kDOWN==(dat[8-LCount]&kDOWN)&&LCount!=1){
- dat[8-LCount]&=(~kDOWN);
- if(!DownOk())dat[8-LCount]&=(~kUP);
- b=1;
- }
- //到達底層或頂層,清空梯內按鍵信息
- if(LCount==1||LCount==8){
- for(i=1;i<7;i++)dat[i]&=(~kOUT);
- }
- if(b){dtSTOP;s3=0;t10=100;}
- }
- void main(){
- uchar k;
- bit bkey;
- dir=fUP;
- c=t10=s=0;
- min=0;hor=12;
- TMOD=0x01;
- EA=ET0=TR0=1;
- //檢測電梯所在樓層
- sta:
- if (dF1==0)LCount=dispBuf[1]=1;
- else if (dF2==0)LCount=dispBuf[1]=2;
- else if (dF3==0)LCount=dispBuf[1]=3;
- else if (dF4==0)LCount=dispBuf[1]=4;
- else if (dF5==0)LCount=dispBuf[1]=5;
- else if (dF6==0)LCount=dispBuf[1]=6;
- else if (dF7==0)LCount=dispBuf[1]=7;
- else if (dF8==0)LCount=dispBuf[1]=8;
- else {dir=fDOWN;s2=0;goto sta;} //若電梯位于兩樓之間,令其下行
- s1=s2=1; //電梯停止
- while(1){
- if(!bkey)k=key_get(),bkey=1;
- if((LCount!=(k&0x0F))||s3){
- if(k>0&&k<9)dat[8-k]^=kOUT; //出電梯鍵
- else if(k>10&&k<18)dat[18-k]|=kUP; //上行鍵
- else if(k>21&&k<29)dat[28-k]|=kDOWN; //下行鍵
- k=0;
- }
- if(!key_get())bkey=0;
- //樓層到達信號,diapBuf[1]為樓號顯示緩存
- if(dF1==0)dispBuf[1]=1;
- else if(dF2==0)dispBuf[1]=2;
- else if(dF3==0)dispBuf[1]=3;
- else if(dF4==0)dispBuf[1]=4;
- else if(dF5==0)dispBuf[1]=5;
- else if(dF6==0)dispBuf[1]=6;
- else if(dF7==0)dispBuf[1]=7;
- else if(dF8==0)dispBuf[1]=8;
- //到達某層,判斷是否需要開門,開門后定時自動關門。
- if(LCount!=dispBuf[1]){ //如果是新樓層
- LCount=dispBuf[1]; //更新樓號
- km(); //開門?
- }
- if(dir==fUP&&mk1==0&&s3==1){//是否繼續上行?
- if(UpOk()){dtUP;} //上行
- else {dir=fDOWN;if(P2!=0xff)dtSTOP;km();}//不上,反轉
- }else if(dir==fDOWN&&mk1==0&&s3==1){//是否繼續下行?
- if(DownOk()){dtDOWN;}
- else {dir=fUP;if(P2!=0xff)dtSTOP;km();}
- }
- //靜止狀態下,本層是否有請求?
- if(mk1==0&&s3==1&&s1==1&&s2==1){
- if (0!=(dat[8-LCount]&kOUT)){
- s3=0;t10=100;
- dat[8-LCount]&=(~kOUT);
- }
- if(0!=(dat[8-LCount]&kUP)&&dir==fUP){
- dat[8-LCount]&=(~kUP);
- s3=0;t10=100;
- }
- if(0!=(dat[8-LCount]&kDOWN)&&dir==fDOWN){
- dat[8-LCount]&=(~kDOWN);
- s3=0;t10=100;
- }
- }
- //定時到,關門
- if(t10==0)s3=1;
- //電梯門“開/關”好顯示
- if(mk1==0&&mk2==1)dispBuf[2]=14;
- else if(mk1==1&&mk2==0)dispBuf[2]=13;
- else dispBuf[2]=15;
- //電梯“上行/下行”符號
- if(s1==0&&s2==1)dispBuf[0]=10;
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
(電梯仿真及程序).rar
(58.09 KB, 下載次數: 146)
2019-6-5 16:00 上傳
點擊文件名下載附件
|