设为首页
收藏本站
开启辅助访问
登录
注册
只需一步,快速开始
首页
BBS
在线充值
搜索
工控币获得方法
联系方式
搜索
搜索
本版
帖子
用户
工控论坛
»
首页
›
电子技术
›
EDA设计仿真
›
51单片机8层电梯程序(传感器版+定时模拟版)Proteus仿真 ...
返回列表
发新帖
51单片机8层电梯程序(传感器版+定时模拟版)Proteus仿真
[复制链接]
0
|
0
|
2020-1-22 23:38:20
|
显示全部楼层
|
阅读模式
第一个版本:8层楼梯传感器版
第二个版本:8层楼梯定时模拟版
8层楼梯传感器版.zip
(125.29 KB)
2020-1-22 23:35 上传
点击文件名下载附件
8层楼梯定时模拟版.zip
(125.33 KB)
2020-1-22 23:35 上传
点击文件名下载附件
8层楼梯传感器版仿真
/*******************电梯主程序**********************/
#include "reg51.h"
#include "intrins.h"
/******************移植部分代码*************************/
sbit DOOR=P3^5;
sbit DlevMotor_P=P3^6; //电梯电机正极
sbit DlevMotor_N=P3^7; //电梯电机负极
#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];//数组[0]不用,从[1]开始使用
u8 FloorTimerCount;
u8 ArriveFlag; //到达楼层信号(用于停止或在前一楼层提前加减速)
u8 FreeFlag;
}TYPEDEF_DLEVSTATE;
TYPEDEF_DLEVSTATE DlevState;
u8 code SEG_NUM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0x7D,0x07,0x7f,0x6f}; //SEG数码管段码 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; //下降沿触发
EX0= 1;
}
void EXTI1_Init(void)
{
EA = 1;
IT1= 1; //下降沿触发
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) //楼梯内的楼层选择按键
{
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) //关门
{
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); //数码管显示
}
void Elevator(void)
{
if((DOOR==OPEN)||(DlevState.FreeFlag==TRUE)) DlevWorkState(STOP);
else
DlevWorkState(DlevState.Direction);
if(DlevState.Direction==UP) //电梯正在向上运行的情况
{
if(DlevState.CurrentFloor<=MaxFloor) //扫描呼叫列表中的向上方向的呼叫楼层
{
if(DlevState.FloorCallTable[DlevState.CurrentFloor]==UP) //到达目标楼层,停下开门5秒
{
DlevState.FloorCallTable[DlevState.CurrentFloor]=Null; //到达相应的楼层从向上列表中清除
DlevState.FreeFlag=TRUE; //到达楼层,暂停进入空闲状态
DlevWorkState(STOP);
WaitDoorOpen(DoorStayTime);
delay_s(2*DoorStayTime); //保持门开2秒让人进出
WaitDoorClose(DoorStayTime);
DlevWorkState(DlevState.Direction);
DlevState.FreeFlag=FALSE; //离开楼层,退出空闲状态
DlevState.FloorTimerCount=0; //计时器清0
}
}
}
else
if(DlevState.Direction==DOWN) //电梯正在向下运行的情况
{
if(DlevState.CurrentFloor>=1) //扫描呼叫列表中的向下方向的呼叫楼层
{
if(DlevState.FloorCallTable[DlevState.CurrentFloor]==DOWN) //到达楼层,停下开门5秒
{
DlevState.FloorCallTable[DlevState.CurrentFloor]=Null; //到达相应的楼层从向下列表中清除
DlevState.FreeFlag=TRUE; //到达楼层,暂停进入空闲状态
DlevWorkState(STOP);
WaitDoorOpen(DoorStayTime);
delay_s(2*DoorStayTime); //保持门开2秒让人进出
WaitDoorClose(DoorStayTime);
DlevWorkState(DlevState.Direction);
DlevState.FreeFlag=FALSE; //离开楼层,退出空闲状态
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; //退出空闲状态
DlevState.DlevRunning=TRUE;//正在运行标志打开
break;
}
else if(i==MaxFloor) DlevState.FreeFlag=TRUE; //进入空闲状态
}
if(DlevState.CurrentFloor==1) DlevState.Direction=UP; //1楼调头
else
if(DlevState.CurrentFloor==MaxFloor) DlevState.Direction=DOWN; //顶楼调头
if((DlevState.FreeFlag==FALSE)&&(DOOR==CLOSE)) //非空闲下
{
if(DlevState.Direction==UP)//方向向上
{
if((FloorCall_UP(UP)==TRUE)||(FloorCall_DOWN(UP)==TRUE)) //如果当前楼层上方有呼叫向上的 或 如果当前楼层上方有呼叫向下的
{
if(DlevState.ArriveFlag==TRUE) //检测是否到达楼层 如果接收到 到达楼层的限位开关信号,则当前楼层值+1
{
DlevState.ArriveFlag=FALSE; //清除标志
DlevState.FloorTimerCount=0; //计时器清0
DlevState.CurrentFloor++;//电梯继续往上走
}
}
else
if((FloorCall_UP(DOWN)==TRUE)||(FloorCall_DOWN(DOWN)==TRUE)) //扫描下方是否是有呼叫
{
DlevState.Direction=DOWN; //楼层下方有呼叫则调头
}
else DlevState.FreeFlag=TRUE; //否则进入空闲状态
}
else
if(DlevState.Direction==DOWN)//方向向下
{
if((FloorCall_DOWN(DOWN)==TRUE)||(FloorCall_UP(DOWN)==TRUE)) //如果当前楼层下方有呼叫向下的 或 如果当前楼层下方有呼叫向上的
{
if(DlevState.ArriveFlag==TRUE) //检测是否到达楼层 如果接收到 到达楼层的限位开关信号,则当前楼层值+1
{
DlevState.ArriveFlag=FALSE; //清除标志
DlevState.FloorTimerCount=0;
DlevState.CurrentFloor--;//电梯继续往下走
}
}
else
if((FloorCall_DOWN(UP)==TRUE)||(FloorCall_UP(UP)==TRUE)) //扫描上方是否是有呼叫
{
DlevState.Direction=UP; //楼层上方有呼叫则调头
}
else DlevState.FreeFlag=TRUE; //否则进入空闲状态
}
}
else
{
DlevWorkState(STOP); //停止运行
DlevState.DlevRunning=FALSE;//正在运行标志关闭
}
}
void SYSYEM_INIT(void)
{
u8 i;
DlevState.CurrentFloor=1;
DlevState.Direction=UP; //初使化方向为向上
DlevState.FloorTimerCount=0;
DlevState.FreeFlag=TRUE; //初使化为空闲状态
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
{
}
复制代码
8层楼梯定时模拟版仿真:
/*******************电梯主程序**********************/
#include "reg51.h"
#include "intrins.h"
/******************移植部分代码*************************/
sbit DOOR=P3^5;
sbit DlevMotor_P=P3^6; //电梯电机正极
sbit DlevMotor_N=P3^7; //电梯电机负极
#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];//数组[0]不用,从[1]开始使用
u8 FloorTimerCount;
u8 ArriveFlag; //到达楼层信号(用于停止或在前一楼层提前加减速)(此版本是定时器模拟,用不到)
u8 FreeFlag;
}TYPEDEF_DLEVSTATE;
TYPEDEF_DLEVSTATE DlevState;
u8 code SEG_NUM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0x7D,0x07,0x7f,0x6f}; //SEG数码管段码 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; //下降沿触发
EX0= 1;
}
void EXTI1_Init(void)
{
EA = 1;
IT1= 1; //下降沿触发
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) //楼梯内的楼层选择按键
{
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) //关门
{
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); //数码管显示
}
void Elevator(void)
{
if((DOOR==OPEN)||(DlevState.FreeFlag==TRUE)) DlevWorkState(STOP);
else
DlevWorkState(DlevState.Direction);
if(DlevState.Direction==UP) //电梯正在向上运行的情况
{
if(DlevState.CurrentFloor<=MaxFloor) //扫描呼叫列表中的向上方向的呼叫楼层
{
if(DlevState.FloorCallTable[DlevState.CurrentFloor]==UP) //到达目标楼层,停下开门5秒
{
DlevState.FloorCallTable[DlevState.CurrentFloor]=Null; //到达相应的楼层从向上列表中清除
DlevState.FreeFlag=TRUE; //到达楼层,暂停进入空闲状态
DlevWorkState(STOP);
WaitDoorOpen(DoorStayTime);
delay_s(2*DoorStayTime); //保持门开2秒让人进出
WaitDoorClose(DoorStayTime);
DlevWorkState(DlevState.Direction);
DlevState.FreeFlag=FALSE; //离开楼层,退出空闲状态
DlevState.FloorTimerCount=0; //计时器清0
}
}
}
else
if(DlevState.Direction==DOWN) //电梯正在向下运行的情况
{
if(DlevState.CurrentFloor>=1) //扫描呼叫列表中的向下方向的呼叫楼层
{
if(DlevState.FloorCallTable[DlevState.CurrentFloor]==DOWN) //到达楼层,停下开门5秒
{
DlevState.FloorCallTable[DlevState.CurrentFloor]=Null; //到达相应的楼层从向下列表中清除
DlevState.FreeFlag=TRUE; //到达楼层,暂停进入空闲状态
DlevWorkState(STOP);
WaitDoorOpen(DoorStayTime);
delay_s(2*DoorStayTime); //保持门开2秒让人进出
WaitDoorClose(DoorStayTime);
DlevWorkState(DlevState.Direction);
DlevState.FreeFlag=FALSE; //离开楼层,退出空闲状态
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; //退出空闲状态
DlevState.DlevRunning=TRUE;//正在运行标志打开
break;
}
else if(i==MaxFloor) DlevState.FreeFlag=TRUE; //进入空闲状态
}
if(DlevState.CurrentFloor==1) DlevState.Direction=UP; //1楼调头
else
if(DlevState.CurrentFloor==MaxFloor) DlevState.Direction=DOWN; //顶楼调头
if((DlevState.FreeFlag==FALSE)&&(DOOR==CLOSE)) //非空闲下
{
if(DlevState.Direction==UP)//方向向上
{
if((FloorCall_UP(UP)==TRUE)||(FloorCall_DOWN(UP)==TRUE)) //如果当前楼层上方有呼叫向上的 或 如果当前楼层上方有呼叫向下的
{
if(DlevState.FloorTimerCount>FloorStayTime) //检测是否到达楼层 如果接收到 到达楼层的限位开关信号,则当前楼层值+1(这里用定时器来模拟)
{
DlevState.FloorTimerCount=0; //计时器清0
DlevState.CurrentFloor++;//电梯继续往上走
}
}
else
if((FloorCall_UP(DOWN)==TRUE)||(FloorCall_DOWN(DOWN)==TRUE)) //扫描下方是否是有呼叫
{
DlevState.Direction=DOWN; //楼层下方有呼叫则调头
}
else DlevState.FreeFlag=TRUE; //否则进入空闲状态
}
else
if(DlevState.Direction==DOWN)//方向向下
{
if((FloorCall_DOWN(DOWN)==TRUE)||(FloorCall_UP(DOWN)==TRUE)) //如果当前楼层下方有呼叫向下的 或 如果当前楼层下方有呼叫向上的
{
if(DlevState.FloorTimerCount>FloorStayTime) //检测是否到达楼层 如果接收到 到达楼层的限位开关信号,则当前楼层值+1(这里用定时器来模拟)
{
DlevState.FloorTimerCount=0;
DlevState.CurrentFloor--;//电梯继续往下走
}
}
else
if((FloorCall_DOWN(UP)==TRUE)||(FloorCall_UP(UP)==TRUE)) //扫描上方是否是有呼叫
{
DlevState.Direction=UP; //楼层上方有呼叫则调头
}
else DlevState.FreeFlag=TRUE; //否则进入空闲状态
}
}
else
{
DlevWorkState(STOP); //停止运行
DlevState.DlevRunning=FALSE;//正在运行标志关闭
}
}
void SYSYEM_INIT(void)
{
u8 i;
DlevState.CurrentFloor=1;
DlevState.Direction=UP; //初使化方向为向上
DlevState.FloorTimerCount=0;
DlevState.FreeFlag=TRUE; //初使化为空闲状态
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 //用于电梯之间的通信
{
}
复制代码
电梯
,
protues
,
51单片机
相关帖子
•
51单片机采集温度通过串口发送到labview上位机采集曲线显示
•
labview做的五层电梯程序
•
LabVIEW读取和显示温度曲线 51单片机做下位机
•
远程果蔬工厂监控系统设计 LabVIEW+51单片机程序
•
三菱plc+触摸屏实现电梯控制 SFC语言编写
•
VB上位机设置时间 51单片机DS1302时钟的proteus仿真程序
•
C#上位机源程和51单片机实现控制电机加速减速正反转
•
8051单片机彻底研究 全套
•
51单片机原理及应用:基于KeilC与Proteus
•
基于labview的电梯控制的仿真程序
回复
使用道具
举报
返回列表
发新帖
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
注册
本版积分规则
发表回复
回帖后跳转到最后一页
山海致远
5963
主题
6931
帖子
102
积分
初级会员
初级会员, 积分 102, 距离下一级还需 398 积分
初级会员, 积分 102, 距离下一级还需 398 积分
工控币
102
加好友
发消息
回复楼主
返回列表
电子技术综合讨论
单片机嵌入式
EDA设计仿真
STM32/8
51单片机
上位机开发及系统管理
Labview
Multisim仿真
图文推荐
用Fanuc Karel语言实现三点建坐标系
2021-01-04
用CH341A做的USB转SPI_232_485_TTL转换器 PCB+SCH文件 烧写器源
2020-12-14
51单片机采集温度通过串口发送到labview上位机采集曲线显示
2020-12-13
基于组态王的占空比PID算法温度控制系统设计 含源码和文档
2020-12-13
基于LabVIEW的电动车速度监测和控制系统上位机程序设计
2020-12-08
热门排行
1
交通信号灯电子线路实验Multisim仿真电路图
2
Multisim14仿真PIC16f84单片机驱动led
3
基于labview的电子秤
4
哪位大佬能看看logix5571以太网通信故障这
5
WINCC 7.5+SP1+UPD3
6
基于LabVIEW的猜数字游戏
7
安装Com Profibus失败,有没有大神能帮忙看
8
山武温控器SDC35/36使用说明书 中文
9
TIA 博途 V16 专业版+ 模拟器 亲测可用
10
软件安装不成功