欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 397|回復: 0
收起左側

基于51單片機的八層電梯設計代碼

[復制鏈接]
ID:1137639 發表于 2026-2-11 17: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&UP_IN)==UP_IN)||((ElevState.FloorCallTable&UP_OUT)==UP_OUT)) //如果掃描到上方樓層有向上的呼叫
  •                          {
  •                                  return TRUE;
  •                          }
  •                  }
  •                  return FALSE;
  •          }
  •          else
  •          if(floorside==DOWN)
  •          {
  •                  for(i=ElevState.CurrentFloor-1;i>=1;i--) //掃描呼叫列表樓下是否有要向上的呼叫
  •                  {
  •                          if(((ElevState.FloorCallTable&UP_IN)==UP_IN)||((ElevState.FloorCallTable&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&DOWN_IN)==DOWN_IN)||((ElevState.FloorCallTable&DOWN_OUT)==DOWN_OUT)) //如果掃描到上方樓層有向下的呼叫
  •                          {
  •                                  return TRUE;
  •                          }
  •                  }
  •                  return FALSE;
  •          }
  •          else
  •          if(floorside==DOWN)
  •          {
  •                  for(i=ElevState.CurrentFloor-1;i>=1;i--) //掃描呼叫列表樓下是否有要向下的呼叫
  •                  {
  •                          if(((ElevState.FloorCallTable&DOWN_IN)==DOWN_IN)||((ElevState.FloorCallTable&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!=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=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();
  •         }
  • }


回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表