欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
基于51單片機多層電梯控制程序Proteus仿真設計
[打印本頁]
作者:
judetang
時間:
2025-4-16 13:01
標題:
基于51單片機多層電梯控制程序Proteus仿真設計
keil下的代碼設計proteus仿真圖片如下:
3.png
(189.58 KB, 下載次數: 0)
下載附件
2025-4-16 13:01 上傳
只使用一個數碼管顯示<-8總樓層時,將下面的A芯片刪除,同時將A中的14腳的命名復制到B中的14腳,然后刪除LED中的9-16層(用不到的都可刪除),僅硬件上做這些改動,即可由又數碼管變為單數碼管顯示。
包含基本設計文-仿真-代碼
51hei.gif
(121.23 KB, 下載次數: 0)
下載附件
2025-4-17 16:03 上傳
單片機源程序如下:
/*-----------------------單梯實驗程序----------------------------/
/*************************電梯主程序*****************************/
#include "reg51.h"
#include "intrins.h"
/***********************樓梯參數設置*****************************/
#define MaxFloor 8 //電梯總樓層
#define FloorStayTime 10//40 //單位:50ms, 樓層停留時間:40*50ms=2S
#define DoorStayTime 2 //單位:S , 電梯門停留時間
#define SEG_Num 2 //數碼管數量(當樓層總數<=8時,樓層顯示可用
//1位或2位數碼管顯示,當設為1時請在仿真中
//刪除第一個595芯片,并把信號線直接接到第二
//個595即可)
/****************************************************************/
/***********************程序工作模式選擇**************************/
#define USE_MODE 0 //0-定時模擬
/****************************************************************/
/*********************平臺移植部分代碼****************************/
//定時器模擬版接口:
#if (USE_MODE==0)
sbit DOOR=P3^5; //電梯門開關控制信號
sbit ElevMotor_P=P3^6; //電梯電機正極控制信號
sbit ElevMotor_N=P3^7; //電梯電機負極控制信號
sbit SHCP=P0^5; //74HC595 LED、數碼管顯示驅動
sbit DS=P0^6; //74HC595 LED、數碼管顯示驅動
sbit STCP=P0^7; //74HC595 LED、數碼管顯示驅動
#define KeyPort_X P1 //矩陣按鍵接口
#define KeyPort_Y P2 //矩陣按鍵接口
#endif
//除以上定義的IO外,還需用到P33作為矩陣鍵盤的中斷觸發引腳
//8路與門:用8路與非門CD4068或74LS30+輸出端接一個三極管反向電平。
//傳感器版接口:
#if (USE_MODE==1)
sbit DOOR_CLOSE_SENSOR=P3^4;//電梯門關閉檢測傳感器輸入
sbit DOOR=P3^5; //電梯門開關控制信號
sbit ElevMotor_P=P3^6; //電梯電機正極控制信號
sbit ElevMotor_N=P3^7; //電梯電機負極控制信號
sbit SHCP=P0^5; //74HC595 LED、數碼管顯示驅動
sbit DS=P0^6; //74HC595 LED、數碼管顯示驅動
sbit STCP=P0^7; //74HC595 LED、數碼管顯示驅動
#define KeyPort_X P1 //矩陣按鍵接口
#define KeyPort_Y P2 //矩陣按鍵接口
#endif
//除以上定義的IO外,還需用到P33作為矩陣鍵盤的中斷觸發引腳
//需用到P32作為樓層限位開關觸發中斷引腳
//每個樓層一個限位開關,接在N路輸入的與門芯片上
//如果大于8層,可用兩個8路輸入的與門芯片+一個2路的與門芯片組合
/****************************************************************/
//以下為程序源碼,用戶不可改動
#define u8 unsigned char
#define u16 unsigned int
#define TRUE 1 //真
#define FALSE 0 //假
//電梯運行狀態
#define Null 0 //空閑
#define STOP 1 //停止
#define UP 2 //向上
#define DOWN 3 //向下
#define UP_IN 0x01 //內部向上標記(在呼叫列表中的標記 用bit0標記)
#define UP_OUT 0x02 //外部向上標記(在呼叫列表中的標記 用bit1標記)
#define DOWN_IN 0x04 //內部向下標記(在呼叫列表中的標記 用bit2標記)
#define DOWN_OUT 0x08 //外部向下標記(在呼叫列表中的標記 用bit3標記)
#define Elev_UP ElevMotor_P=0;ElevMotor_N=1 //低電平有效
#define Elev_DOWN ElevMotor_P=1;ElevMotor_N=0 //低電平有效 電機正轉
#define Elev_STOP ElevMotor_P=1;ElevMotor_N=1 //低電平有效 電機反轉
#define OPEN 1
#define CLOSE 0
#define DOOR_Open DOOR=OPEN //開門
#define DOOR_Close DOOR=CLOSE //關門
#define SHCP_H SHCP=1
#define SHCP_L SHCP=0
#define DS_H DS=1
#define DS_L DS=0
#define STCP_H STCP=1
#define STCP_L STCP=0
#if MaxFloor>8
#define MHC595_NUM 8
#else
#define MHC595_NUM 5
#endif
#define SEGPort 0x01
#define LED_IN_Port 0x02
#define LED_OUT_UP_Port 0x03
#define LED_OUT_DOWN_Port 0x04
//FloorCallTable[]呼叫列表說明:該列表由數組構成,下標和每個樓層一一對應,如FloorCallTable[1]表示1樓的呼叫狀態
// bit3-DOWN_OUT bit2-DOWN_IN bit1-UP_OUT bit0-UP_IN bit=0為沒有呼叫,=1為有呼叫
typedef struct
{
u8 ElevRunning; //電梯運行狀態標志
u8 CurrentFloor; //當前電梯所處樓層
u8 Direction; //電梯運行方向
u8 FloorCallTable[MaxFloor+1];//數組[0]不用,從[1]開始使用 ,呼叫列表(所有樓層呼叫的信息均保存于此)
u8 FloorTimerCount; //計時
u8 ArriveFlag; //到達樓層信號(用于停止或在前一樓層提前加減速)(定時器模擬的用不到)
u8 FreeFlag; //電梯空閑狀態標志
}TYPEDEF_ELEVSTATE;
TYPEDEF_ELEVSTATE ElevState; //電梯狀態結構體
//u8 code SEG_NUM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0x7D,0x07,0x7f,0x6f}; //共陰SEG數碼管段碼 0~9
u8 code SEG_NUM[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //共陽SEG數碼管段碼 0~F
u16 code LED_NUM[]={0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //SEG數碼管段碼 0~9
u8 HC595_BUFF[MHC595_NUM]={0};
u8 Timer_Second;
u16 TimerCount;
u8 ExternKey[2]={0}; //外部按鍵按下信息
u8 FloorCallTableBUFF[MaxFloor+10]={0};
u8 KeyPressFlag=0;
#define Uart_RX_LEN 20 //接收緩存長度(請勿超過芯片rom剩余大小)
typedef struct
{
u8 RX_BUFF[Uart_RX_LEN]; //接收緩存
u8 TX_BUFF[Uart_RX_LEN]; //發送緩存
u16 RX_COUNT;
}UART;
UART Uart;
void delay_ms(u16 xms); //ms延時
void delay_s(u8 xs); //s延時
void EXTI0_Init(void);
void EXTI1_Init(void);
void TIMER0_Init(void);
void HC595_Send(u8 *p);
u8 KeyScan(void);
void KeyDatHandle(u8 key);
void WaitDoorOpen(u8 ts);
void WaitDoorClose(u8 ts);
void SEG_Display(u8 segnum);
void LED_ON(u8 addr,u8 lednum);
void LED_OFF(u8 addr,u8 lednum);
void ElevWorkState(u8 state);
void Elevator(void);
u8 FloorCall_UP(u8 floorside);
u8 FloorCall_DOWN(u8 floorside);
u8 DelNullCheck(void);
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 HC595_Send(u8 *p)
{
u8 i,j;
u8 temp;
for(i=MHC595_NUM;i>2-SEG_Num;i--)
{
temp=p[i-1];
for(j=0;j<8;j++)
{
DS=temp&0x80;
temp<<=1;
SHCP_L;
SHCP_H;
}
}
STCP_L;
STCP_H;
}
/*鍵盤剪裁說明:
按鍵掃描函數 8*8 如要改為4*4或其他
請把KeyPort_Y 和 KeyPort_X 對應的IO口數量減少,如4*4,則用KeyPort_Y低4位和KeyPort_X高4位
鍵盤分布如下:(序號和IO口高低位對應)
P20 -> P27
Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7
P10 X0 * * * * * * * * 57 58 59 60 61 62 63 64
X1 * * * * * * * * 49 50 51 52 53 54 55 56
X2 * * * * * * * * 41 42 43 44 45 46 47 48
| X3 * * * * * * * * 對應按鍵掃描 33 34 35 36 37 38 39 40 仿真文件
| X4 * * * * * * * * 函數返回值-> 25 26 27 28 29 30 31 32 布局-> 25 26 27 28 29 30 31 32 57 58 59 60 61 62 63 64
X5 * * * * * * * * 17 18 19 20 21 22 23 24 17 18 19 20 21 22 23 24 49 50 51 52 53 54 55 56
X6 * * * * * * * * 9 10 11 12 13 14 15 16 9 10 11 12 13 14 15 16 41 42 43 44 45 46 47 48
P17 X7 * * * * * * * * 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 33 34 35 36 37 38 39 40
*/
//KeyScan()掃描函數兼容8*8以下所有鍵盤,鍵盤改小時無需修改
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)
{
u8 tempkey;
if(key==0)
{
}
else
if(((key>0)&&(key<=8))||((key>32)&&(key<=40))) //樓梯內的樓層選擇按鍵(使用1-8 和 33-40作為按鍵)
{
if(key>32) tempkey=key-32+8;
else tempkey=key;
if(tempkey<=MaxFloor)
{
LED_ON(LED_IN_Port,tempkey);
if(((tempkey>ElevState.CurrentFloor)&&(tempkey<MaxFloor))||(tempkey==1)) ElevState.FloorCallTable[tempkey]|=UP_IN;//內部按1只能往上
else
if((tempkey<ElevState.CurrentFloor)||(tempkey==MaxFloor)) ElevState.FloorCallTable[tempkey]|=DOWN_IN;
}
}
else
if(((key>9)&&(key<=16))||((key>40)&&(key<=48))) //每個樓層門口外的向下按鍵(底樓按向下無效)(使用10-16 和 41-48作為按鍵)
{
if(key>40) tempkey=key-40+8;
else tempkey=key-8;
if((tempkey>1)&&(tempkey<=MaxFloor))
{
LED_ON(LED_OUT_DOWN_Port,tempkey);
ElevState.FloorCallTable[tempkey]|=DOWN_OUT;
}
}
else
if(((key>16)&&(key<=24))||((key>48)&&(key<56))) //每個樓層門口外的向上按鍵(頂樓按向上無效)(使用17-24 和 49-55作為按鍵)
{
if(key>48) tempkey=key-48+8;
else tempkey=key-16;
if(tempkey<MaxFloor)
{
LED_ON(LED_OUT_UP_Port,tempkey);
ElevState.FloorCallTable[tempkey]|=UP_OUT;
}
}
else
if(key==25) //開門 (使用25 作為按鍵)
{
if(ElevState.ElevRunning==FALSE)
{
if(DOOR==CLOSE) DOOR_Open;
}
}
else
if(key==26) //關門 (使用26 作為按鍵)
{
if(DOOR==OPEN)
{
DOOR_Close;
ElevState.FloorTimerCount=0; //計時器清0
}
}
}
//第待開門
void WaitDoorOpen(u8 ts)
{
DOOR_Open;
delay_s(ts);
}
//第待關門
void WaitDoorClose(u8 ts)
{
DOOR_Close;
#if (USE_MODE==0)
delay_s(ts);
#endif
#if (USE_MODE==1)
ts=ts; //防止警告
while(DOOR_CLOSE_SENSOR==OPEN);
#endif
}
//數碼管顯示驅動
void SEG_Display(u8 segnum)
{
HC595_BUFF[0]=SEG_NUM[segnum/10];
HC595_BUFF[1]=SEG_NUM[segnum%10];
HC595_Send(HC595_BUFF);
}
//LED顯示驅動
void LED_ON(u8 addr,u8 lednum)
{
switch(addr)
{
case LED_IN_Port: if(lednum<9) HC595_BUFF[2]|=LED_NUM[lednum];
else HC595_BUFF[5]|=LED_NUM[lednum-8]; break;
case LED_OUT_DOWN_Port: if(lednum<9) HC595_BUFF[3]|=LED_NUM[lednum];
else HC595_BUFF[6]|=LED_NUM[lednum-8]; break;
case LED_OUT_UP_Port: if(lednum<9) HC595_BUFF[4]|=LED_NUM[lednum];
else HC595_BUFF[7]|=LED_NUM[lednum-8]; break;
}
HC595_Send(HC595_BUFF);
}
//LED顯示驅動
void LED_OFF(u8 addr,u8 lednum)
{
switch(addr)
{
case LED_IN_Port: if(lednum<9) HC595_BUFF[2]&=~LED_NUM[lednum];
else HC595_BUFF[5]&=~LED_NUM[lednum-8]; break;
case LED_OUT_DOWN_Port: if(lednum<9) HC595_BUFF[3]&=~LED_NUM[lednum];
else HC595_BUFF[6]&=~LED_NUM[lednum-8]; break;
case LED_OUT_UP_Port: if(lednum<9) HC595_BUFF[4]&=~LED_NUM[lednum];
else HC595_BUFF[7]&=~LED_NUM[lednum-8]; break;
}
HC595_Send(HC595_BUFF);
}
//電梯運行狀態設置
void ElevWorkState(u8 state)
{
if(state==UP)
{
Elev_UP;
ElevState.ElevRunning=TRUE;
}
else
if(state==DOWN)
{
Elev_DOWN;
ElevState.ElevRunning=TRUE;
}
else
if(state==STOP)
{
Elev_STOP;
ElevState.ElevRunning=FALSE;
}
SEG_Display(ElevState.CurrentFloor); //數碼管顯示
}
//調頭檢測函數
void TurnHead_Check(void)
{
if(ElevState.CurrentFloor==1)
{
ElevState.Direction=UP; //1樓調頭
}
else if(ElevState.CurrentFloor==MaxFloor)
{
ElevState.Direction=DOWN; //頂樓調頭
}
}
//電梯運行函數
void Elevator(void)
{
if((DOOR==OPEN)||(ElevState.FreeFlag==TRUE)) ElevWorkState(STOP);
else ElevWorkState(ElevState.Direction);
TurnHead_Check(); //調頭檢測
if(ElevState.Direction==UP) //電梯正在向上運行的情況
{
if(ElevState.CurrentFloor<=MaxFloor) //掃描呼叫列表中的向上方向的呼叫樓層
{
if(((ElevState.FloorCallTable[ElevState.CurrentFloor]&UP_IN)==UP_IN)||((ElevState.FloorCallTable[ElevState.CurrentFloor]&UP_OUT)==UP_OUT)) //到達目標樓層,停下開門5秒
{
LED_OFF(LED_IN_Port,ElevState.CurrentFloor);
LED_OFF(LED_OUT_UP_Port,ElevState.CurrentFloor);
ElevState.FloorCallTable[ElevState.CurrentFloor]&=~UP_IN; //到達相應的樓層從向上列表中清除
ElevState.FloorCallTable[ElevState.CurrentFloor]&=~UP_OUT; //到達相應的樓層從向上列表中清除
ElevState.FreeFlag=TRUE; //到達樓層,暫時進入空閑狀態
ElevWorkState(STOP); //修改電梯狀態為停止態
WaitDoorOpen(DoorStayTime); //延時等待電梯門打開
delay_s(2*DoorStayTime); //適當延時
WaitDoorClose(DoorStayTime); //等待門關好
ElevWorkState(ElevState.Direction);
ElevState.FreeFlag=FALSE; //離開樓層,退出空閑狀態
ElevState.FloorTimerCount=0; //計時器清0
}
}
}
else
if(ElevState.Direction==DOWN) //電梯正在向下運行的情況
{
if(ElevState.CurrentFloor>=1) //掃描呼叫列表中的向下方向的呼叫樓層
{
if(((ElevState.FloorCallTable[ElevState.CurrentFloor]&DOWN_IN)==DOWN_IN)||((ElevState.FloorCallTable[ElevState.CurrentFloor]&DOWN_OUT)==DOWN_OUT)) //到達樓層,停下開門5秒
{
LED_OFF(LED_IN_Port,ElevState.CurrentFloor);
LED_OFF(LED_OUT_DOWN_Port,ElevState.CurrentFloor);
ElevState.FloorCallTable[ElevState.CurrentFloor]&=~DOWN_IN; //到達相應的樓層從向下列表中清除
ElevState.FloorCallTable[ElevState.CurrentFloor]&=~DOWN_OUT; //到達相應的樓層從向下列表中清除
ElevState.FreeFlag=TRUE; //到達樓層,暫時進入空閑狀態
ElevWorkState(STOP); //修改電梯狀態為停止態
WaitDoorOpen(DoorStayTime); //延時等待電梯門打開
delay_s(2*DoorStayTime); //保持門開2秒讓人進出
WaitDoorClose(DoorStayTime); //適當延時
ElevWorkState(ElevState.Direction); //等待門關好
ElevState.FreeFlag=FALSE; //離開樓層,退出空閑狀態
ElevState.FloorTimerCount=0; //計時器清0
}
}
}
}
//掃描呼叫列表查看樓上或樓下是否有要向上的呼叫,有則返回TRUE,沒有返回FALSE
u8 FloorCall_UP(u8 floorside) // floorside = DOWN樓下 UP樓上
{
u8 i;
if(floorside==UP)
{
for(i=ElevState.CurrentFloor+1;i<=MaxFloor;i++) //掃描呼叫列表樓上是否有要向上的呼叫
{
if(((ElevState.FloorCallTable[i]&UP_IN)==UP_IN)||((ElevState.FloorCallTable[i]&UP_OUT)==UP_OUT)) //如果掃描到上方樓層有向上的呼叫
{
return TRUE;
}
}
return FALSE;
}
else
if(floorside==DOWN)
{
for(i=ElevState.CurrentFloor-1;i>=1;i--) //掃描呼叫列表樓下是否有要向上的呼叫
{
if(((ElevState.FloorCallTable[i]&UP_IN)==UP_IN)||((ElevState.FloorCallTable[i]&UP_OUT)==UP_OUT)) //如果掃描到上方樓層有向上的呼叫
{
return TRUE;
}
}
return FALSE;
}
else return FALSE;
}
//掃描呼叫列表查看樓上或樓下是否有要向下的呼叫,有則返回TRUE,沒有返回FALSE
u8 FloorCall_DOWN(u8 floorside) // floorside = DOWN樓下 UP樓上
{
u8 i;
if(floorside==UP)
{
for(i=ElevState.CurrentFloor+1;i<=MaxFloor;i++) //掃描呼叫列表樓上是否有要向下的呼叫
{
if(((ElevState.FloorCallTable[i]&DOWN_IN)==DOWN_IN)||((ElevState.FloorCallTable[i]&DOWN_OUT)==DOWN_OUT)) //如果掃描到上方樓層有向下的呼叫
{
return TRUE;
}
}
return FALSE;
}
else
if(floorside==DOWN)
{
for(i=ElevState.CurrentFloor-1;i>=1;i--) //掃描呼叫列表樓下是否有要向下的呼叫
{
if(((ElevState.FloorCallTable[i]&DOWN_IN)==DOWN_IN)||((ElevState.FloorCallTable[i]&DOWN_OUT)==DOWN_OUT)) //如果掃描到上方樓層有向下的呼叫
{
return TRUE;
}
}
return FALSE;
}
else return FALSE;
}
////掃描呼叫列表是否為空(沒有呼叫),空-返回TRUE 有呼叫-返回FALSE
u8 DelNullCheck(void) //掃描呼叫列表是否空閑
{
u8 i;
u8 result;
for(i=1;i<=MaxFloor;i++)
{
if(ElevState.FloorCallTable[i]!=Null)
{
result=FALSE; //非空閑
break;
}
else if(i==MaxFloor) result=TRUE; //空閑
}
return result;
}
//樓層呼叫處理函數(無需修改)
void FloorCallCheck(void)
{
if(DelNullCheck()==FALSE) //非空閑
{
ElevState.FreeFlag=FALSE; //退出空閑狀態
ElevState.ElevRunning=TRUE;//正在運行標志打開
}
else ElevState.FreeFlag=TRUE; //進入空閑狀態
TurnHead_Check();
if((ElevState.FreeFlag==FALSE)&&(DOOR==CLOSE)) //非空閑下
{
if(ElevState.Direction==UP)//方向向上
{
if((FloorCall_UP(UP)==TRUE)||(FloorCall_DOWN(UP)==TRUE)) //如果當前樓層上方有呼叫向上的 或 如果當前樓層上方有呼叫向下的
{
if(ElevState.FloorTimerCount>FloorStayTime) //檢測是否到達樓層 如果接收到 到達樓層的限位開關信號,則當前樓層值+1(這里用定時器來模擬)
{
ElevState.FloorTimerCount=0; //計時器清0
ElevState.CurrentFloor++;//電梯繼續往上走
}
}
else ElevState.Direction=DOWN; //調頭
}
else
if(ElevState.Direction==DOWN)//方向向下
{
if((FloorCall_DOWN(DOWN)==TRUE)||(FloorCall_UP(DOWN)==TRUE)) //如果當前樓層下方有呼叫向下的 或 如果當前樓層下方有呼叫向上的
{
if(ElevState.FloorTimerCount>FloorStayTime) //檢測是否到達樓層 (這里用定時器來模擬)
{
ElevState.FloorTimerCount=0;
ElevState.CurrentFloor--;//電梯繼續往下走
}
}
else ElevState.Direction=UP; //調頭
}
}
else
{
ElevWorkState(STOP); //停止運行
ElevState.ElevRunning=FALSE;//正在運行標志關閉
}
}
//系統初使化
void SYSYEM_INIT(void)
{
u8 i;
ElevState.CurrentFloor=1;
ElevState.Direction=UP; //初使化方向為向上
ElevState.FloorTimerCount=0; //定時器版計時清0
ElevState.FreeFlag=TRUE; //初使化為空閑狀態
ElevState.ElevRunning=FALSE; //運行標志置FALSE 表示暫停運行
Uart.RX_COUNT=0; //串口接收計數清0
for(i=0;i<=MaxFloor;i++)
{
ElevState.FloorCallTable[i]=Null; //初使化呼叫列表為Null
}
DOOR_Close; //關門
}
void EXTI0_IRQHandler(void) interrupt 0 //樓層傳感器中斷
{
#if (USE_MODE==1)
ElevState.ArriveFlag=TRUE;//觸發中斷后表示到達樓層,讓到達樓層標志置TRUE
#endif
}
void EXTI1_IRQHandler(void) interrupt 2 //矩陣按鍵中斷
{
KeyDatHandle(KeyScan()); //把KeyScan()按鍵掃描函數返回的按鍵值帶入到KeyDatHandle()處理按鍵
}
void TIM0_IRQHandler(void) interrupt 1 //定時模擬電梯上升和下降
{
TH0=(65536-50000)/256;//定時50ms
TL0=(65536-50000)%256;//定時50ms
TimerCount++;
if(TimerCount==20) //1秒
{
TimerCount=0;
Timer_Second++;
}
if(DelNullCheck()==FALSE) ElevState.FloorTimerCount++; //非空閑狀態計時累加
else ElevState.FloorTimerCount=0; //空閑狀態計時清0
}
void Uart_IRQHandler(void) interrupt 4 //用于電梯之間的通信
{
if(RI==1) //判斷是否為接收中斷(串口中斷分為發送中斷和接收中斷,均用同一個中斷服務函數入口)
{
RI = 0; //清除RI接收中斷標志
Uart.RX_BUFF[Uart.RX_COUNT++]=SBUF;
if(Uart.RX_COUNT==Uart_RX_LEN) Uart.RX_COUNT=0;
}
}
void main(void) //主函數
{
SYSYEM_INIT();
EXTI0_Init();
EXTI1_Init();
TIMER0_Init();
while(1)
{
KeyPort_Y=0x00; //不可刪除
FloorCallCheck();
Elevator();
}
}
復制代碼
仿真-代碼-設計文檔下載:
八層電梯模擬控制.7z
(1010.81 KB, 下載次數: 0)
2025-4-17 16:06 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
denminshen
時間:
2025-4-18 16:06
謝謝分享,收藏了!
作者:
淡抹
時間:
2025-6-30 18:39
怎么改成30層的啊
作者:
WFX777888
時間:
2025-10-23 07:34
謝謝分享,收藏了!
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1