国产免费AV|泡泡玛特欧洲总部将设在伦敦|中文天堂网www新版资源在线|一本久道综合在线中文|国精产品一二三产区的使用方法|香蕉鱼在线观看|www.27eee
ELEOK
標(biāo)題:
51單片機(jī)8層電梯程序(傳感器版+定時模擬版)Proteus仿真
[打印本頁]
作者:
山海致遠(yuǎn)
時間:
2020-1-22 23:38
標(biāo)題:
51單片機(jī)8層電梯程序(傳感器版+定時模擬版)Proteus仿真
第一個版本:8層樓梯傳感器版
第二個版本:8層樓梯定時模擬版
8層樓梯傳感器版.zip
(125.29 KB)
2020-1-22 23:35 上傳
點擊文件名下載附件
8層樓梯定時模擬版.zip
(125.33 KB)
2020-1-22 23:35 上傳
點擊文件名下載附件
8層樓梯傳感器版仿真
1.png
(84.71 KB)
下載附件
2020-1-22 23:31 上傳
/*******************電梯主程序**********************/
#include "reg51.h"
#include "intrins.h"
/******************移植部分代碼*************************/
sbit DOOR=P3^5;
sbit DlevMotor_P=P3^6; //電梯電機(jī)正極
sbit DlevMotor_N=P3^7; //電梯電機(jī)負(fù)極
#define SEGPort P0
#define KeyPort_X P1
#define KeyPort_Y P2
/******************************************************/
#define u8 unsigned char
#define u16 unsigned int
#define MaxFloor 8
#define FloorStayTime 40 //單位:50ms
#define DoorStayTime 2 //單位:S
#define TRUE 1
#define FALSE 0
#define Null 0
#define STOP 1
#define UP 2
#define DOWN 3
#define Dlev_UP DlevMotor_P=0;DlevMotor_N=1 //低電平有效
#define Dlev_DOWN DlevMotor_P=1;DlevMotor_N=0 //低電平有效
#define Dlev_STOP DlevMotor_P=1;DlevMotor_N=1 //低電平有效
#define OPEN 1
#define CLOSE 0
#define DOOR_Open DOOR=OPEN
#define DOOR_Close DOOR=CLOSE
typedef struct
{
u8 DlevRunning;
u8 CurrentFloor;
u8 Direction;
u8 FloorCallTable[MaxFloor+1];//數(shù)組[0]不用,從[1]開始使用
u8 FloorTimerCount;
u8 ArriveFlag; //到達(dá)樓層信號(用于停止或在前一樓層提前加減速)
u8 FreeFlag;
}TYPEDEF_DLEVSTATE;
TYPEDEF_DLEVSTATE DlevState;
u8 code SEG_NUM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0x7D,0x07,0x7f,0x6f}; //SEG數(shù)碼管段碼 0~9
u8 Timer_Second;
u16 TimerCount;
u8 RICount=0;
u8 RIOver_Flag=0;
u8 ExternKey[2]={0}; //外部按鍵按下信息
u8 FloorCallTableBUFF[MaxFloor+10]={0};
u8 KeyPressFlag=0;
void delay_ms(u16 xms);
void delay_s(u8 xs);
void EXTI0_Init(void);
void Timer0_Init(void);
void USART_Configure(u16 BaudRate);
u8 KeyScan(void);
void KeyDatHandle(u8 key);
void WaitDoorOpen(u8 ts);
void WaitDoorClose(u8 ts);
void SEG_Display(u8 segnum);
void DlevWorkState(u8 state);
void Elevator(void);
u8 FloorCall_UP(u8 floorside);
u8 FloorCall_DOWN(u8 floorside);
void FLOORCALLCHECK(void);
void SYSYEM_INIT(void);
void delay_ms(u16 xms)
{
u8 i;
u16 t;
for(t=xms;t>0;t--)
for(i=112;i>0;i--);
}
void delay_s(u8 xs)
{
TimerCount=0;
Timer_Second=0;
while(Timer_Second<xs);
}
void EXTI0_Init(void)
{
EA = 1;
IT0= 1; //下降沿觸發(fā)
EX0= 1;
}
void EXTI1_Init(void)
{
EA = 1;
IT1= 1; //下降沿觸發(fā)
EX1= 1;
}
void Timer0_Init(void)
{
TMOD |= 0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void USART_Configure(u16 BaudRate)
{
u8 TH1_Dat;
switch(BaudRate)
{
case 1200: TH1_Dat=0xE8; break;
case 2400: TH1_Dat=0xF4; break;
case 4800: TH1_Dat=0xFA; break;
case 9600: TH1_Dat=0xFD; break;
case 14400: TH1_Dat=0xFE; break;
}
TMOD |= 0x20;
SCON |= 0x50;
TH1 = TH1_Dat;
TL1 = TH1;
PCON |= 0x00;
EA = 1;
ES = 1;
TR1 = 1;
}
u8 KeyScan(void)
{
u8 keynum;
KeyPort_Y=0x00;
KeyPort_X=0xFF;
_nop_(); _nop_(); _nop_(); _nop_();
if(KeyPort_X!=0xFF)
{
delay_ms(10);
if(KeyPort_X!=0xFF)
{
switch(KeyPort_X)
{
case 0x7F: keynum=1; break;
case 0xBF: keynum=9; break;
case 0xDF: keynum=17; break;
case 0xEF: keynum=25; break;
case 0xF7: keynum=33; break;
case 0xFB: keynum=41; break;
case 0xFD: keynum=49; break;
case 0xFE: keynum=57; break;
}
KeyPort_Y=0xFF;
KeyPort_X=0x00;
_nop_(); _nop_(); _nop_(); _nop_();
if(KeyPort_Y!=0xFF)
{
switch(KeyPort_Y)
{
case 0xFE: keynum=keynum+0; break;
case 0xFD: keynum=keynum+1; break;
case 0xFB: keynum=keynum+2; break;
case 0xF7: keynum=keynum+3; break;
case 0xEF: keynum=keynum+4; break;
case 0xDF: keynum=keynum+5; break;
case 0xBF: keynum=keynum+6; break;
case 0x7F: keynum=keynum+7; break;
}
}
KeyPort_Y=0x00;
}
}
else keynum=0;
return keynum;
}
void KeyDatHandle(u8 key)
{
if(key==0)
{
}
else
if(key<=MaxFloor) //樓梯內(nèi)的樓層選擇按鍵
{
if(key>DlevState.CurrentFloor) DlevState.FloorCallTable[key]=UP;
else
if(key<DlevState.CurrentFloor) DlevState.FloorCallTable[key]=DOWN;
}
else
if((key<=MaxFloor*2)&&(key>MaxFloor+1)) //每個樓層門口外的向下按鍵(底樓按向下無效)
{
DlevState.FloorCallTable[key-MaxFloor]=DOWN;
}
else
if(key<MaxFloor*3) //每個樓層門口外的向上按鍵(頂樓按向上無效)
{
DlevState.FloorCallTable[key-MaxFloor*2]=UP;
}
else
if(key==MaxFloor*3+1) //開門
{
if(DlevState.DlevRunning==FALSE)
{
if(DOOR==CLOSE) DOOR_Open;
}
}
else
if(key==MaxFloor*3+2) //關(guān)門
{
if(DOOR==OPEN)
{
DOOR_Close;
DlevState.FloorTimerCount=0; //計時器清0
}
}
}
void WaitDoorOpen(u8 ts)
{
DOOR_Open;
delay_s(ts);
}
void WaitDoorClose(u8 ts)
{
DOOR_Close;
delay_s(ts);
}
void SEG_Display(u8 segnum)
{
SEGPort=~SEG_NUM[segnum];
}
void DlevWorkState(u8 state)
{
if(state==UP)
{
Dlev_UP;
DlevState.DlevRunning=TRUE;
}
else
if(state==DOWN)
{
Dlev_DOWN;
DlevState.DlevRunning=TRUE;
}
else
if(state==STOP)
{
Dlev_STOP;
DlevState.DlevRunning=FALSE;
}
SEG_Display(DlevState.CurrentFloor); //數(shù)碼管顯示
}
void Elevator(void)
{
if((DOOR==OPEN)||(DlevState.FreeFlag==TRUE)) DlevWorkState(STOP);
else
DlevWorkState(DlevState.Direction);
if(DlevState.Direction==UP) //電梯正在向上運(yùn)行的情況
{
if(DlevState.CurrentFloor<=MaxFloor) //掃描呼叫列表中的向上方向的呼叫樓層
{
if(DlevState.FloorCallTable[DlevState.CurrentFloor]==UP) //到達(dá)目標(biāo)樓層,停下開門5秒
{
DlevState.FloorCallTable[DlevState.CurrentFloor]=Null; //到達(dá)相應(yīng)的樓層從向上列表中清除
DlevState.FreeFlag=TRUE; //到達(dá)樓層,暫停進(jìn)入空閑狀態(tài)
DlevWorkState(STOP);
WaitDoorOpen(DoorStayTime);
delay_s(2*DoorStayTime); //保持門開2秒讓人進(jìn)出
WaitDoorClose(DoorStayTime);
DlevWorkState(DlevState.Direction);
DlevState.FreeFlag=FALSE; //離開樓層,退出空閑狀態(tài)
DlevState.FloorTimerCount=0; //計時器清0
}
}
}
else
if(DlevState.Direction==DOWN) //電梯正在向下運(yùn)行的情況
{
if(DlevState.CurrentFloor>=1) //掃描呼叫列表中的向下方向的呼叫樓層
{
if(DlevState.FloorCallTable[DlevState.CurrentFloor]==DOWN) //到達(dá)樓層,停下開門5秒
{
DlevState.FloorCallTable[DlevState.CurrentFloor]=Null; //到達(dá)相應(yīng)的樓層從向下列表中清除
DlevState.FreeFlag=TRUE; //到達(dá)樓層,暫停進(jìn)入空閑狀態(tài)
DlevWorkState(STOP);
WaitDoorOpen(DoorStayTime);
delay_s(2*DoorStayTime); //保持門開2秒讓人進(jìn)出
WaitDoorClose(DoorStayTime);
DlevWorkState(DlevState.Direction);
DlevState.FreeFlag=FALSE; //離開樓層,退出空閑狀態(tài)
DlevState.FloorTimerCount=0; //計時器清0
}
}
}
}
u8 FloorCall_UP(u8 floorside) // floorside = DOWN在樓下 UP在樓上
{
u8 i;
if(floorside==UP)
{
for(i=DlevState.CurrentFloor+1;i<=MaxFloor;i++) //掃描呼叫列表樓上是否有要向上的呼叫
{
if(DlevState.FloorCallTable[i]==UP) //如果掃描到上方樓層有向上的呼叫
{
return TRUE;
}
}
return FALSE;
}
else
if(floorside==DOWN)
{
for(i=DlevState.CurrentFloor-1;i>=1;i--) //掃描呼叫列表樓下是否有要向上的呼叫
{
if(DlevState.FloorCallTable[i]==UP) //如果掃描到上方樓層有向上的呼叫
{
return TRUE;
}
}
return FALSE;
}
}
u8 FloorCall_DOWN(u8 floorside) // floorside = DOWN在樓下 UP在樓上
{
u8 i;
if(floorside==UP)
{
for(i=DlevState.CurrentFloor+1;i<=MaxFloor;i++) //掃描呼叫列表樓上是否有要向下的呼叫
{
if(DlevState.FloorCallTable[i]==DOWN) //如果掃描到上方樓層有向下的呼叫
{
return TRUE;
}
}
return FALSE;
}
else
if(floorside==DOWN)
{
for(i=DlevState.CurrentFloor-1;i>=1;i--) //掃描呼叫列表樓下是否有要向下的呼叫
{
if(DlevState.FloorCallTable[i]==DOWN) //如果掃描到上方樓層有向下的呼叫
{
return TRUE;
}
}
return FALSE;
}
}
void FLOORCALLCHECK(void)
{
u8 i;
for(i=1;i<=MaxFloor;i++) //掃描呼叫列表是否空閑
{
if(DlevState.FloorCallTable[i]!=Null) //非空閑
{
DlevState.FreeFlag=FALSE; //退出空閑狀態(tài)
DlevState.DlevRunning=TRUE;//正在運(yùn)行標(biāo)志打開
break;
}
else if(i==MaxFloor) DlevState.FreeFlag=TRUE; //進(jìn)入空閑狀態(tài)
}
if(DlevState.CurrentFloor==1) DlevState.Direction=UP; //1樓調(diào)頭
else
if(DlevState.CurrentFloor==MaxFloor) DlevState.Direction=DOWN; //頂樓調(diào)頭
if((DlevState.FreeFlag==FALSE)&&(DOOR==CLOSE)) //非空閑下
{
if(DlevState.Direction==UP)//方向向上
{
if((FloorCall_UP(UP)==TRUE)||(FloorCall_DOWN(UP)==TRUE)) //如果當(dāng)前樓層上方有呼叫向上的 或 如果當(dāng)前樓層上方有呼叫向下的
{
if(DlevState.ArriveFlag==TRUE) //檢測是否到達(dá)樓層 如果接收到 到達(dá)樓層的限位開關(guān)信號,則當(dāng)前樓層值+1
{
DlevState.ArriveFlag=FALSE; //清除標(biāo)志
DlevState.FloorTimerCount=0; //計時器清0
DlevState.CurrentFloor++;//電梯繼續(xù)往上走
}
}
else
if((FloorCall_UP(DOWN)==TRUE)||(FloorCall_DOWN(DOWN)==TRUE)) //掃描下方是否是有呼叫
{
DlevState.Direction=DOWN; //樓層下方有呼叫則調(diào)頭
}
else DlevState.FreeFlag=TRUE; //否則進(jìn)入空閑狀態(tài)
}
else
if(DlevState.Direction==DOWN)//方向向下
{
if((FloorCall_DOWN(DOWN)==TRUE)||(FloorCall_UP(DOWN)==TRUE)) //如果當(dāng)前樓層下方有呼叫向下的 或 如果當(dāng)前樓層下方有呼叫向上的
{
if(DlevState.ArriveFlag==TRUE) //檢測是否到達(dá)樓層 如果接收到 到達(dá)樓層的限位開關(guān)信號,則當(dāng)前樓層值+1
{
DlevState.ArriveFlag=FALSE; //清除標(biāo)志
DlevState.FloorTimerCount=0;
DlevState.CurrentFloor--;//電梯繼續(xù)往下走
}
}
else
if((FloorCall_DOWN(UP)==TRUE)||(FloorCall_UP(UP)==TRUE)) //掃描上方是否是有呼叫
{
DlevState.Direction=UP; //樓層上方有呼叫則調(diào)頭
}
else DlevState.FreeFlag=TRUE; //否則進(jìn)入空閑狀態(tài)
}
}
else
{
DlevWorkState(STOP); //停止運(yùn)行
DlevState.DlevRunning=FALSE;//正在運(yùn)行標(biāo)志關(guān)閉
}
}
void SYSYEM_INIT(void)
{
u8 i;
DlevState.CurrentFloor=1;
DlevState.Direction=UP; //初使化方向為向上
DlevState.FloorTimerCount=0;
DlevState.FreeFlag=TRUE; //初使化為空閑狀態(tài)
DlevState.DlevRunning=FALSE;
RIOver_Flag=FALSE;
RICount=0;
for(i=1;i<=MaxFloor;i++)
{
DlevState.FloorCallTable[i]=Null; //初使化呼叫列表為Null
}
DOOR_Close;
}
void main(void)
{
SYSYEM_INIT();
EXTI0_Init();
EXTI1_Init();
Timer0_Init();
USART_Configure(9600);
while(1)
{
KeyPort_Y=0x00;
FLOORCALLCHECK();
Elevator();
}
}
void EXTI0_IRQHandler(void) interrupt 0
{
DlevState.ArriveFlag=TRUE;
}
void EXTI1_IRQHandler(void) interrupt 2
{
KeyDatHandle(KeyScan());
}
void TIM0_IRQHandler(void) interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TimerCount++;
if(TimerCount==20) //1秒
{
TimerCount=0;
Timer_Second++;
}
DlevState.FloorTimerCount++;
}
void USART_IRQHandler(void) interrupt 4
{
}
復(fù)制代碼
8層樓梯定時模擬版仿真:
2.png
(84.68 KB)
下載附件
2020-1-22 23:36 上傳
/*******************電梯主程序**********************/
#include "reg51.h"
#include "intrins.h"
/******************移植部分代碼*************************/
sbit DOOR=P3^5;
sbit DlevMotor_P=P3^6; //電梯電機(jī)正極
sbit DlevMotor_N=P3^7; //電梯電機(jī)負(fù)極
#define SEGPort P0
#define KeyPort_X P1
#define KeyPort_Y P2
/******************************************************/
#define u8 unsigned char
#define u16 unsigned int
#define MaxFloor 8
#define FloorStayTime 40 //單位:50ms
#define DoorStayTime 2 //單位:S
#define TRUE 1
#define FALSE 0
#define Null 0
#define STOP 1
#define UP 2
#define DOWN 3
#define Dlev_UP DlevMotor_P=0;DlevMotor_N=1 //低電平有效
#define Dlev_DOWN DlevMotor_P=1;DlevMotor_N=0 //低電平有效
#define Dlev_STOP DlevMotor_P=1;DlevMotor_N=1 //低電平有效
#define OPEN 1
#define CLOSE 0
#define DOOR_Open DOOR=OPEN
#define DOOR_Close DOOR=CLOSE
typedef struct
{
u8 DlevRunning;
u8 CurrentFloor;
u8 Direction;
u8 FloorCallTable[MaxFloor+1];//數(shù)組[0]不用,從[1]開始使用
u8 FloorTimerCount;
u8 ArriveFlag; //到達(dá)樓層信號(用于停止或在前一樓層提前加減速)(此版本是定時器模擬,用不到)
u8 FreeFlag;
}TYPEDEF_DLEVSTATE;
TYPEDEF_DLEVSTATE DlevState;
u8 code SEG_NUM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0x7D,0x07,0x7f,0x6f}; //SEG數(shù)碼管段碼 0~9
u8 Timer_Second;
u16 TimerCount;
u8 RICount=0;
u8 RIOver_Flag=0;
u8 ExternKey[2]={0}; //外部按鍵按下信息
u8 FloorCallTableBUFF[MaxFloor+10]={0};
u8 KeyPressFlag=0;
void delay_ms(u16 xms);
void delay_s(u8 xs);
void EXTI0_Init(void);
void Timer0_Init(void);
void USART_Configure(u16 BaudRate);
u8 KeyScan(void);
void KeyDatHandle(u8 key);
void WaitDoorOpen(u8 ts);
void WaitDoorClose(u8 ts);
void SEG_Display(u8 segnum);
void DlevWorkState(u8 state);
void Elevator(void);
u8 FloorCall_UP(u8 floorside);
u8 FloorCall_DOWN(u8 floorside);
void FLOORCALLCHECK(void);
void SYSYEM_INIT(void);
void delay_ms(u16 xms)
{
u8 i;
u16 t;
for(t=xms;t>0;t--)
for(i=112;i>0;i--);
}
void delay_s(u8 xs)
{
TimerCount=0;
Timer_Second=0;
while(Timer_Second<xs);
}
void EXTI0_Init(void)
{
EA = 1;
IT0= 1; //下降沿觸發(fā)
EX0= 1;
}
void EXTI1_Init(void)
{
EA = 1;
IT1= 1; //下降沿觸發(fā)
EX1= 1;
}
void Timer0_Init(void)
{
TMOD |= 0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void USART_Configure(u16 BaudRate)
{
u8 TH1_Dat;
switch(BaudRate)
{
case 1200: TH1_Dat=0xE8; break;
case 2400: TH1_Dat=0xF4; break;
case 4800: TH1_Dat=0xFA; break;
case 9600: TH1_Dat=0xFD; break;
case 14400: TH1_Dat=0xFE; break;
}
TMOD |= 0x20;
SCON |= 0x50;
TH1 = TH1_Dat;
TL1 = TH1;
PCON |= 0x00;
EA = 1;
ES = 1;
TR1 = 1;
}
u8 KeyScan(void)
{
u8 keynum;
KeyPort_Y=0x00;
KeyPort_X=0xFF;
_nop_(); _nop_(); _nop_(); _nop_();
if(KeyPort_X!=0xFF)
{
delay_ms(10);
if(KeyPort_X!=0xFF)
{
switch(KeyPort_X)
{
case 0x7F: keynum=1; break;
case 0xBF: keynum=9; break;
case 0xDF: keynum=17; break;
case 0xEF: keynum=25; break;
case 0xF7: keynum=33; break;
case 0xFB: keynum=41; break;
case 0xFD: keynum=49; break;
case 0xFE: keynum=57; break;
}
KeyPort_Y=0xFF;
KeyPort_X=0x00;
_nop_(); _nop_(); _nop_(); _nop_();
if(KeyPort_Y!=0xFF)
{
switch(KeyPort_Y)
{
case 0xFE: keynum=keynum+0; break;
case 0xFD: keynum=keynum+1; break;
case 0xFB: keynum=keynum+2; break;
case 0xF7: keynum=keynum+3; break;
case 0xEF: keynum=keynum+4; break;
case 0xDF: keynum=keynum+5; break;
case 0xBF: keynum=keynum+6; break;
case 0x7F: keynum=keynum+7; break;
}
}
KeyPort_Y=0x00;
}
}
else keynum=0;
return keynum;
}
void KeyDatHandle(u8 key)
{
if(key==0)
{
}
else
if(key<=MaxFloor) //樓梯內(nèi)的樓層選擇按鍵
{
if(key>DlevState.CurrentFloor) DlevState.FloorCallTable[key]=UP;
else
if(key<DlevState.CurrentFloor) DlevState.FloorCallTable[key]=DOWN;
}
else
if((key<=MaxFloor*2)&&(key>MaxFloor+1)) //每個樓層門口外的向下按鍵(底樓按向下無效)
{
DlevState.FloorCallTable[key-MaxFloor]=DOWN;
}
else
if(key<MaxFloor*3) //每個樓層門口外的向上按鍵(頂樓按向上無效)
{
DlevState.FloorCallTable[key-MaxFloor*2]=UP;
}
else
if(key==MaxFloor*3+1) //開門
{
if(DlevState.DlevRunning==FALSE)
{
if(DOOR==CLOSE) DOOR_Open;
}
}
else
if(key==MaxFloor*3+2) //關(guān)門
{
if(DOOR==OPEN)
{
DOOR_Close;
DlevState.FloorTimerCount=0; //計時器清0
}
}
}
void WaitDoorOpen(u8 ts)
{
DOOR_Open;
delay_s(ts);
}
void WaitDoorClose(u8 ts)
{
DOOR_Close;
delay_s(ts);
}
void SEG_Display(u8 segnum)
{
SEGPort=~SEG_NUM[segnum];
}
void DlevWorkState(u8 state)
{
if(state==UP)
{
Dlev_UP;
DlevState.DlevRunning=TRUE;
}
else
if(state==DOWN)
{
Dlev_DOWN;
DlevState.DlevRunning=TRUE;
}
else
if(state==STOP)
{
Dlev_STOP;
DlevState.DlevRunning=FALSE;
}
SEG_Display(DlevState.CurrentFloor); //數(shù)碼管顯示
}
void Elevator(void)
{
if((DOOR==OPEN)||(DlevState.FreeFlag==TRUE)) DlevWorkState(STOP);
else
DlevWorkState(DlevState.Direction);
if(DlevState.Direction==UP) //電梯正在向上運(yùn)行的情況
{
if(DlevState.CurrentFloor<=MaxFloor) //掃描呼叫列表中的向上方向的呼叫樓層
{
if(DlevState.FloorCallTable[DlevState.CurrentFloor]==UP) //到達(dá)目標(biāo)樓層,停下開門5秒
{
DlevState.FloorCallTable[DlevState.CurrentFloor]=Null; //到達(dá)相應(yīng)的樓層從向上列表中清除
DlevState.FreeFlag=TRUE; //到達(dá)樓層,暫停進(jìn)入空閑狀態(tài)
DlevWorkState(STOP);
WaitDoorOpen(DoorStayTime);
delay_s(2*DoorStayTime); //保持門開2秒讓人進(jìn)出
WaitDoorClose(DoorStayTime);
DlevWorkState(DlevState.Direction);
DlevState.FreeFlag=FALSE; //離開樓層,退出空閑狀態(tài)
DlevState.FloorTimerCount=0; //計時器清0
}
}
}
else
if(DlevState.Direction==DOWN) //電梯正在向下運(yùn)行的情況
{
if(DlevState.CurrentFloor>=1) //掃描呼叫列表中的向下方向的呼叫樓層
{
if(DlevState.FloorCallTable[DlevState.CurrentFloor]==DOWN) //到達(dá)樓層,停下開門5秒
{
DlevState.FloorCallTable[DlevState.CurrentFloor]=Null; //到達(dá)相應(yīng)的樓層從向下列表中清除
DlevState.FreeFlag=TRUE; //到達(dá)樓層,暫停進(jìn)入空閑狀態(tài)
DlevWorkState(STOP);
WaitDoorOpen(DoorStayTime);
delay_s(2*DoorStayTime); //保持門開2秒讓人進(jìn)出
WaitDoorClose(DoorStayTime);
DlevWorkState(DlevState.Direction);
DlevState.FreeFlag=FALSE; //離開樓層,退出空閑狀態(tài)
DlevState.FloorTimerCount=0; //計時器清0
}
}
}
}
u8 FloorCall_UP(u8 floorside) // floorside = DOWN在樓下 UP在樓上
{
u8 i;
if(floorside==UP)
{
for(i=DlevState.CurrentFloor+1;i<=MaxFloor;i++) //掃描呼叫列表樓上是否有要向上的呼叫
{
if(DlevState.FloorCallTable[i]==UP) //如果掃描到上方樓層有向上的呼叫
{
return TRUE;
}
}
return FALSE;
}
else
if(floorside==DOWN)
{
for(i=DlevState.CurrentFloor-1;i>=1;i--) //掃描呼叫列表樓下是否有要向上的呼叫
{
if(DlevState.FloorCallTable[i]==UP) //如果掃描到上方樓層有向上的呼叫
{
return TRUE;
}
}
return FALSE;
}
}
u8 FloorCall_DOWN(u8 floorside) // floorside = DOWN在樓下 UP在樓上
{
u8 i;
if(floorside==UP)
{
for(i=DlevState.CurrentFloor+1;i<=MaxFloor;i++) //掃描呼叫列表樓上是否有要向下的呼叫
{
if(DlevState.FloorCallTable[i]==DOWN) //如果掃描到上方樓層有向下的呼叫
{
return TRUE;
}
}
return FALSE;
}
else
if(floorside==DOWN)
{
for(i=DlevState.CurrentFloor-1;i>=1;i--) //掃描呼叫列表樓下是否有要向下的呼叫
{
if(DlevState.FloorCallTable[i]==DOWN) //如果掃描到上方樓層有向下的呼叫
{
return TRUE;
}
}
return FALSE;
}
}
void FLOORCALLCHECK(void)
{
u8 i;
for(i=1;i<=MaxFloor;i++) //掃描呼叫列表是否空閑
{
if(DlevState.FloorCallTable[i]!=Null) //非空閑
{
DlevState.FreeFlag=FALSE; //退出空閑狀態(tài)
DlevState.DlevRunning=TRUE;//正在運(yùn)行標(biāo)志打開
break;
}
else if(i==MaxFloor) DlevState.FreeFlag=TRUE; //進(jìn)入空閑狀態(tài)
}
if(DlevState.CurrentFloor==1) DlevState.Direction=UP; //1樓調(diào)頭
else
if(DlevState.CurrentFloor==MaxFloor) DlevState.Direction=DOWN; //頂樓調(diào)頭
if((DlevState.FreeFlag==FALSE)&&(DOOR==CLOSE)) //非空閑下
{
if(DlevState.Direction==UP)//方向向上
{
if((FloorCall_UP(UP)==TRUE)||(FloorCall_DOWN(UP)==TRUE)) //如果當(dāng)前樓層上方有呼叫向上的 或 如果當(dāng)前樓層上方有呼叫向下的
{
if(DlevState.FloorTimerCount>FloorStayTime) //檢測是否到達(dá)樓層 如果接收到 到達(dá)樓層的限位開關(guān)信號,則當(dāng)前樓層值+1(這里用定時器來模擬)
{
DlevState.FloorTimerCount=0; //計時器清0
DlevState.CurrentFloor++;//電梯繼續(xù)往上走
}
}
else
if((FloorCall_UP(DOWN)==TRUE)||(FloorCall_DOWN(DOWN)==TRUE)) //掃描下方是否是有呼叫
{
DlevState.Direction=DOWN; //樓層下方有呼叫則調(diào)頭
}
else DlevState.FreeFlag=TRUE; //否則進(jìn)入空閑狀態(tài)
}
else
if(DlevState.Direction==DOWN)//方向向下
{
if((FloorCall_DOWN(DOWN)==TRUE)||(FloorCall_UP(DOWN)==TRUE)) //如果當(dāng)前樓層下方有呼叫向下的 或 如果當(dāng)前樓層下方有呼叫向上的
{
if(DlevState.FloorTimerCount>FloorStayTime) //檢測是否到達(dá)樓層 如果接收到 到達(dá)樓層的限位開關(guān)信號,則當(dāng)前樓層值+1(這里用定時器來模擬)
{
DlevState.FloorTimerCount=0;
DlevState.CurrentFloor--;//電梯繼續(xù)往下走
}
}
else
if((FloorCall_DOWN(UP)==TRUE)||(FloorCall_UP(UP)==TRUE)) //掃描上方是否是有呼叫
{
DlevState.Direction=UP; //樓層上方有呼叫則調(diào)頭
}
else DlevState.FreeFlag=TRUE; //否則進(jìn)入空閑狀態(tài)
}
}
else
{
DlevWorkState(STOP); //停止運(yùn)行
DlevState.DlevRunning=FALSE;//正在運(yùn)行標(biāo)志關(guān)閉
}
}
void SYSYEM_INIT(void)
{
u8 i;
DlevState.CurrentFloor=1;
DlevState.Direction=UP; //初使化方向為向上
DlevState.FloorTimerCount=0;
DlevState.FreeFlag=TRUE; //初使化為空閑狀態(tài)
DlevState.DlevRunning=FALSE;
RIOver_Flag=FALSE;
RICount=0;
for(i=1;i<=MaxFloor;i++)
{
DlevState.FloorCallTable[i]=Null; //初使化呼叫列表為Null
}
DOOR_Close;
}
void main(void)
{
SYSYEM_INIT();
EXTI0_Init();
EXTI1_Init();
Timer0_Init();
USART_Configure(9600);
while(1)
{
KeyPort_Y=0x00;
FLOORCALLCHECK();
Elevator();
}
}
//void EXTI0_IRQHandler(void) interrupt 0 //樓層傳感器中斷(此模擬版本用不到)
//{
// DlevState.ArriveFlag=TRUE;
//}
void EXTI1_IRQHandler(void) interrupt 2 //矩陣按鍵中斷
{
KeyDatHandle(KeyScan());
}
void TIM0_IRQHandler(void) interrupt 1 //定時模擬電梯上升和下降
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TimerCount++;
if(TimerCount==20) //1秒
{
TimerCount=0;
Timer_Second++;
}
DlevState.FloorTimerCount++;
}
void USART_IRQHandler(void) interrupt 4 //用于電梯之間的通信
{
}
復(fù)制代碼
歡迎光臨 ELEOK (http://m.afoofa.cn/)
Powered by Discuz! X5.0