久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 58|回復: 0
打印 上一主題 下一主題
收起左側

基于51單片機多層電梯控制程序Proteus仿真設計

[復制鏈接]
跳轉到指定樓層
樓主
keil下的代碼設計proteus仿真圖片如下:

只使用一個數碼管顯示<-8總樓層時,將下面的A芯片刪除,同時將A中的14腳的命名復制到B中的14腳,然后刪除LED中的9-16層(用不到的都可刪除),僅硬件上做這些改動,即可由又數碼管變為單數碼管顯示。

包含基本設計文-仿真-代碼



單片機源程序如下:
  1. /*-----------------------單梯實驗程序----------------------------/
  2. /*************************電梯主程序*****************************/

  3. #include "reg51.h"
  4. #include "intrins.h"

  5. /***********************樓梯參數設置*****************************/
  6. #define MaxFloor      8  //電梯總樓層

  7. #define FloorStayTime 10//40 //單位:50ms, 樓層停留時間:40*50ms=2S
  8. #define DoorStayTime  2  //單位:S   , 電梯門停留時間
  9. #define SEG_Num       2  //數碼管數量(當樓層總數<=8時,樓層顯示可用
  10.                          //1位或2位數碼管顯示,當設為1時請在仿真中
  11.                                                  //刪除第一個595芯片,并把信號線直接接到第二
  12.                                                  //個595即可)
  13. /****************************************************************/


  14. /***********************程序工作模式選擇**************************/
  15. #define USE_MODE 0   //0-定時模擬  
  16. /****************************************************************/


  17. /*********************平臺移植部分代碼****************************/
  18. //定時器模擬版接口:
  19. #if (USE_MODE==0)
  20. sbit DOOR=P3^5;        //電梯門開關控制信號
  21. sbit ElevMotor_P=P3^6; //電梯電機正極控制信號
  22. sbit ElevMotor_N=P3^7; //電梯電機負極控制信號
  23. sbit SHCP=P0^5;        //74HC595  LED、數碼管顯示驅動
  24. sbit DS=P0^6;          //74HC595  LED、數碼管顯示驅動
  25. sbit STCP=P0^7;        //74HC595  LED、數碼管顯示驅動
  26. #define KeyPort_X  P1  //矩陣按鍵接口
  27. #define KeyPort_Y  P2  //矩陣按鍵接口
  28. #endif
  29. //除以上定義的IO外,還需用到P33作為矩陣鍵盤的中斷觸發引腳
  30. //8路與門:用8路與非門CD4068或74LS30+輸出端接一個三極管反向電平。


  31. //傳感器版接口:
  32. #if (USE_MODE==1)
  33. sbit DOOR_CLOSE_SENSOR=P3^4;//電梯門關閉檢測傳感器輸入
  34. sbit DOOR=P3^5;        //電梯門開關控制信號
  35. sbit ElevMotor_P=P3^6; //電梯電機正極控制信號
  36. sbit ElevMotor_N=P3^7; //電梯電機負極控制信號
  37. sbit SHCP=P0^5;        //74HC595  LED、數碼管顯示驅動
  38. sbit DS=P0^6;          //74HC595  LED、數碼管顯示驅動
  39. sbit STCP=P0^7;        //74HC595  LED、數碼管顯示驅動
  40. #define KeyPort_X  P1  //矩陣按鍵接口
  41. #define KeyPort_Y  P2  //矩陣按鍵接口
  42. #endif
  43. //除以上定義的IO外,還需用到P33作為矩陣鍵盤的中斷觸發引腳
  44. //需用到P32作為樓層限位開關觸發中斷引腳
  45. //每個樓層一個限位開關,接在N路輸入的與門芯片上
  46. //如果大于8層,可用兩個8路輸入的與門芯片+一個2路的與門芯片組合
  47. /****************************************************************/


  48. //以下為程序源碼,用戶不可改動
  49. #define u8  unsigned char
  50. #define u16 unsigned int
  51.         
  52. #define TRUE  1    //真
  53. #define FALSE 0    //假

  54. //電梯運行狀態
  55. #define Null  0     //空閑
  56. #define STOP  1     //停止
  57. #define UP    2     //向上
  58. #define DOWN  3     //向下

  59. #define UP_IN     0x01     //內部向上標記(在呼叫列表中的標記  用bit0標記)
  60. #define UP_OUT    0x02     //外部向上標記(在呼叫列表中的標記  用bit1標記)
  61. #define DOWN_IN   0x04     //內部向下標記(在呼叫列表中的標記  用bit2標記)
  62. #define DOWN_OUT  0x08     //外部向下標記(在呼叫列表中的標記  用bit3標記)

  63. #define Elev_UP    ElevMotor_P=0;ElevMotor_N=1  //低電平有效
  64. #define Elev_DOWN  ElevMotor_P=1;ElevMotor_N=0  //低電平有效  電機正轉
  65. #define Elev_STOP  ElevMotor_P=1;ElevMotor_N=1  //低電平有效  電機反轉

  66. #define OPEN  1  
  67. #define CLOSE 0
  68. #define DOOR_Open  DOOR=OPEN     //開門
  69. #define DOOR_Close DOOR=CLOSE    //關門

  70. #define SHCP_H SHCP=1
  71. #define SHCP_L SHCP=0
  72. #define DS_H   DS=1
  73. #define DS_L   DS=0
  74. #define STCP_H STCP=1
  75. #define STCP_L STCP=0

  76. #if MaxFloor>8  
  77. #define MHC595_NUM 8
  78. #else
  79. #define MHC595_NUM 5
  80. #endif

  81. #define SEGPort 0x01
  82. #define LED_IN_Port 0x02
  83. #define LED_OUT_UP_Port 0x03
  84. #define LED_OUT_DOWN_Port 0x04

  85. //FloorCallTable[]呼叫列表說明:該列表由數組構成,下標和每個樓層一一對應,如FloorCallTable[1]表示1樓的呼叫狀態
  86. // bit3-DOWN_OUT  bit2-DOWN_IN  bit1-UP_OUT  bit0-UP_IN   bit=0為沒有呼叫,=1為有呼叫
  87. typedef struct
  88. {
  89.         u8 ElevRunning;      //電梯運行狀態標志
  90.         u8 CurrentFloor;     //當前電梯所處樓層
  91.         u8 Direction;        //電梯運行方向
  92.         u8 FloorCallTable[MaxFloor+1];//數組[0]不用,從[1]開始使用 ,呼叫列表(所有樓層呼叫的信息均保存于此)
  93.         u8 FloorTimerCount;         //計時
  94.         u8 ArriveFlag;       //到達樓層信號(用于停止或在前一樓層提前加減速)(定時器模擬的用不到)
  95.         u8 FreeFlag;             //電梯空閑狀態標志
  96. }TYPEDEF_ELEVSTATE;
  97. TYPEDEF_ELEVSTATE ElevState; //電梯狀態結構體

  98. //u8 code SEG_NUM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0x7D,0x07,0x7f,0x6f};   //共陰SEG數碼管段碼  0~9
  99. u8 code SEG_NUM[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //共陽SEG數碼管段碼  0~F
  100. u16 code LED_NUM[]={0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};   //SEG數碼管段碼  0~9

  101. u8 HC595_BUFF[MHC595_NUM]={0};
  102. u8 Timer_Second;
  103. u16 TimerCount;

  104. u8 ExternKey[2]={0}; //外部按鍵按下信息
  105. u8 FloorCallTableBUFF[MaxFloor+10]={0};
  106. u8 KeyPressFlag=0;

  107. #define Uart_RX_LEN 20  //接收緩存長度(請勿超過芯片rom剩余大小)
  108. typedef struct
  109. {
  110.         u8 RX_BUFF[Uart_RX_LEN]; //接收緩存
  111.         u8 TX_BUFF[Uart_RX_LEN]; //發送緩存
  112.         u16 RX_COUNT;
  113. }UART;
  114. UART Uart;

  115. void delay_ms(u16 xms); //ms延時
  116. void delay_s(u8 xs);    //s延時
  117. void EXTI0_Init(void);
  118. void EXTI1_Init(void);
  119. void TIMER0_Init(void);

  120. void HC595_Send(u8 *p);
  121. u8 KeyScan(void);
  122. void KeyDatHandle(u8 key);
  123. void WaitDoorOpen(u8 ts);
  124. void WaitDoorClose(u8 ts);
  125. void SEG_Display(u8 segnum);
  126. void LED_ON(u8 addr,u8 lednum);
  127. void LED_OFF(u8 addr,u8 lednum);
  128. void ElevWorkState(u8 state);
  129. void Elevator(void);
  130. u8 FloorCall_UP(u8 floorside);
  131. u8 FloorCall_DOWN(u8 floorside);
  132. u8 DelNullCheck(void);
  133. void FloorCallCheck(void);

  134. void SYSYEM_INIT(void);

  135. void delay_ms(u16 xms)
  136. {
  137.         u8 i;
  138.         u16 t;
  139.   for(t=xms;t>0;t--)
  140.           for(i=112;i>0;i--);
  141. }

  142. void delay_s(u8 xs)
  143. {
  144.         TimerCount=0;
  145.         Timer_Second=0;
  146.         while(Timer_Second<xs);        
  147. }

  148. void EXTI0_Init(void)
  149. {
  150.         EA = 1;  
  151.         IT0= 1; //下降沿觸發
  152.         EX0= 1;
  153. }

  154. void EXTI1_Init(void)
  155. {
  156.         EA = 1;  
  157.         IT1= 1; //下降沿觸發
  158.         EX1= 1;
  159. }

  160. void Timer0_Init(void)
  161. {
  162.         TMOD |= 0x01;  
  163.         TH0=(65536-50000)/256;
  164.         TL0=(65536-50000)%256;
  165.         EA = 1;
  166.         ET0 = 1;
  167.         TR0 = 1;
  168. }


  169. void HC595_Send(u8 *p)
  170. {
  171.         u8 i,j;
  172.         u8 temp;
  173.         for(i=MHC595_NUM;i>2-SEG_Num;i--)
  174.         {
  175.                 temp=p[i-1];
  176.                 for(j=0;j<8;j++)
  177.                 {
  178.                   DS=temp&0x80;        
  179.                   temp<<=1;        
  180.                   SHCP_L;
  181.                   SHCP_H;                        
  182.                 }
  183.         }
  184.         STCP_L;
  185.         STCP_H;        
  186. }
  187. /*鍵盤剪裁說明:
  188. 按鍵掃描函數 8*8  如要改為4*4或其他  
  189. 請把KeyPort_Y 和 KeyPort_X 對應的IO口數量減少,如4*4,則用KeyPort_Y低4位和KeyPort_X高4位
  190. 鍵盤分布如下:(序號和IO口高低位對應)

  191.        P20      ->         P27

  192.             Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7
  193. P10         X0 *  *  *  *  *  *  *  *                57 58 59 60 61 62 63 64  
  194.          X1 *  *  *  *  *  *  *  *                49 50 51 52 53 54 55 56
  195.          X2 *  *  *  *  *  *  *  *                41 42 43 44 45 46 47 48
  196. |         X3 *  *  *  *  *  *  *  *  對應按鍵掃描  33 34 35 36 37 38 39 40  仿真文件
  197. |         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
  198.          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
  199.          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
  200. 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

  201. */
  202. //KeyScan()掃描函數兼容8*8以下所有鍵盤,鍵盤改小時無需修改
  203. u8 KeyScan(void)
  204. {
  205.         u8 keynum;
  206.   
  207.         KeyPort_Y=0x00;
  208.         KeyPort_X=0xFF;
  209.         _nop_(); _nop_(); _nop_(); _nop_();
  210.         if(KeyPort_X!=0xFF)
  211.         {
  212.          delay_ms(10);
  213.          if(KeyPort_X!=0xFF)
  214.          {
  215.                  switch(KeyPort_X)
  216.                  {
  217.                          case 0x7F: keynum=1;   break;
  218.                          case 0xBF: keynum=9;   break;
  219.                          case 0xDF: keynum=17;  break;
  220.                          case 0xEF: keynum=25;  break;
  221.                          case 0xF7: keynum=33;  break;
  222.                          case 0xFB: keynum=41;  break;
  223.                          case 0xFD: keynum=49;  break;
  224.                          case 0xFE: keynum=57;  break;
  225.                  }
  226.                  KeyPort_Y=0xFF;
  227.                  KeyPort_X=0x00;
  228.                  _nop_(); _nop_(); _nop_(); _nop_();
  229.                  if(KeyPort_Y!=0xFF)
  230.                  {
  231.                          switch(KeyPort_Y)
  232.                          {
  233.                                  case 0xFE: keynum=keynum+0;  break;
  234.                                  case 0xFD: keynum=keynum+1;  break;
  235.                                  case 0xFB: keynum=keynum+2;  break;
  236.                                  case 0xF7: keynum=keynum+3;  break;
  237.                                  case 0xEF: keynum=keynum+4;  break;
  238.                                  case 0xDF: keynum=keynum+5;  break;
  239.                                  case 0xBF: keynum=keynum+6;  break;
  240.                                  case 0x7F: keynum=keynum+7;  break;
  241.                          }
  242.                  }
  243.                  KeyPort_Y=0x00;
  244.    }
  245.         }
  246.         else keynum=0;
  247.         return keynum;
  248. }
  249. //鍵值處理函數:當鍵盤鍵值需要改動時,請根據上面的鍵值改動
  250. void KeyDatHandle(u8 key)
  251. {
  252.         u8 tempkey;
  253.         if(key==0)
  254.         {
  255.         
  256.         }
  257.         else
  258.         if(((key>0)&&(key<=8))||((key>32)&&(key<=40))) //樓梯內的樓層選擇按鍵(使用1-8 和 33-40作為按鍵)
  259.         {
  260.                 if(key>32) tempkey=key-32+8;
  261.                 else       tempkey=key;
  262.                 if(tempkey<=MaxFloor)
  263.                 {
  264.                         LED_ON(LED_IN_Port,tempkey);
  265.                         if(((tempkey>ElevState.CurrentFloor)&&(tempkey<MaxFloor))||(tempkey==1)) ElevState.FloorCallTable[tempkey]|=UP_IN;//內部按1只能往上
  266.                         else
  267.                         if((tempkey<ElevState.CurrentFloor)||(tempkey==MaxFloor)) ElevState.FloorCallTable[tempkey]|=DOWN_IN;        
  268.                 }
  269.         }
  270.         else
  271.         if(((key>9)&&(key<=16))||((key>40)&&(key<=48)))  //每個樓層門口外的向下按鍵(底樓按向下無效)(使用10-16 和 41-48作為按鍵)
  272.         {
  273.                  if(key>40) tempkey=key-40+8;
  274.                  else       tempkey=key-8;
  275.                  if((tempkey>1)&&(tempkey<=MaxFloor))
  276.                  {
  277.                          LED_ON(LED_OUT_DOWN_Port,tempkey);
  278.                          ElevState.FloorCallTable[tempkey]|=DOWN_OUT;
  279.                  }
  280.         }
  281.         else
  282.         if(((key>16)&&(key<=24))||((key>48)&&(key<56))) //每個樓層門口外的向上按鍵(頂樓按向上無效)(使用17-24 和 49-55作為按鍵)
  283.         {
  284.                  if(key>48) tempkey=key-48+8;
  285.                  else       tempkey=key-16;
  286.                  if(tempkey<MaxFloor)
  287.                  {
  288.                          LED_ON(LED_OUT_UP_Port,tempkey);
  289.                          ElevState.FloorCallTable[tempkey]|=UP_OUT;
  290.                  }
  291.         }
  292.         else
  293.         if(key==25)  //開門   (使用25 作為按鍵)
  294.         {
  295.                 if(ElevState.ElevRunning==FALSE)
  296.                 {
  297.                   if(DOOR==CLOSE) DOOR_Open;
  298.                 }
  299.         }
  300.         else
  301.         if(key==26) //關門    (使用26 作為按鍵)
  302.         {
  303.                 if(DOOR==OPEN)
  304.                 {
  305.                         DOOR_Close;
  306.                         ElevState.FloorTimerCount=0;         //計時器清0
  307.                 }
  308.         }
  309. }
  310. //第待開門
  311. void WaitDoorOpen(u8 ts)
  312. {
  313.         DOOR_Open;
  314.         delay_s(ts);
  315. }
  316. //第待關門
  317. void WaitDoorClose(u8 ts)
  318. {
  319.         DOOR_Close;
  320.         #if (USE_MODE==0)
  321.         delay_s(ts);
  322.         #endif
  323.         #if (USE_MODE==1)
  324.         ts=ts; //防止警告
  325.         while(DOOR_CLOSE_SENSOR==OPEN);
  326.         #endif
  327.         
  328. }
  329. //數碼管顯示驅動
  330. void SEG_Display(u8 segnum)
  331. {
  332.         HC595_BUFF[0]=SEG_NUM[segnum/10];
  333.         HC595_BUFF[1]=SEG_NUM[segnum%10];
  334.         HC595_Send(HC595_BUFF);        
  335. }
  336. //LED顯示驅動
  337. void LED_ON(u8 addr,u8 lednum)
  338. {
  339.         switch(addr)
  340.         {
  341.                 case LED_IN_Port:        if(lednum<9)   HC595_BUFF[2]|=LED_NUM[lednum];
  342.                                                                  else           HC595_BUFF[5]|=LED_NUM[lednum-8]; break;
  343.                 case LED_OUT_DOWN_Port:  if(lednum<9)   HC595_BUFF[3]|=LED_NUM[lednum];
  344.                                                                  else           HC595_BUFF[6]|=LED_NUM[lednum-8]; break;
  345.                 case LED_OUT_UP_Port:    if(lednum<9)   HC595_BUFF[4]|=LED_NUM[lednum];
  346.                                                                  else           HC595_BUFF[7]|=LED_NUM[lednum-8]; break;
  347.         }
  348.         HC595_Send(HC595_BUFF);        
  349. }
  350. //LED顯示驅動
  351. void LED_OFF(u8 addr,u8 lednum)
  352. {
  353.         switch(addr)
  354.         {
  355.                 case LED_IN_Port:        if(lednum<9)  HC595_BUFF[2]&=~LED_NUM[lednum];
  356.                                      else          HC595_BUFF[5]&=~LED_NUM[lednum-8]; break;
  357.                 case LED_OUT_DOWN_Port:  if(lednum<9)  HC595_BUFF[3]&=~LED_NUM[lednum];
  358.                                                                  else          HC595_BUFF[6]&=~LED_NUM[lednum-8]; break;
  359.                 case LED_OUT_UP_Port:    if(lednum<9)  HC595_BUFF[4]&=~LED_NUM[lednum];
  360.                                                                  else          HC595_BUFF[7]&=~LED_NUM[lednum-8]; break;
  361.         }
  362.         HC595_Send(HC595_BUFF);        
  363. }
  364. //電梯運行狀態設置
  365. void ElevWorkState(u8 state)
  366. {
  367.   if(state==UP)
  368.         {
  369.                 Elev_UP;
  370.                 ElevState.ElevRunning=TRUE;
  371.         }
  372.         else
  373.         if(state==DOWN)
  374.         {
  375.                 Elev_DOWN;
  376.                 ElevState.ElevRunning=TRUE;
  377.         }
  378.         else
  379.         if(state==STOP)
  380.         {
  381.                 Elev_STOP;
  382.                 ElevState.ElevRunning=FALSE;
  383.         }
  384.         SEG_Display(ElevState.CurrentFloor);                //數碼管顯示
  385. }
  386. //調頭檢測函數
  387. void TurnHead_Check(void)
  388. {
  389.         if(ElevState.CurrentFloor==1)  
  390.         {
  391.                 ElevState.Direction=UP;  //1樓調頭
  392.         }
  393.         else if(ElevState.CurrentFloor==MaxFloor)
  394.         {
  395.                 ElevState.Direction=DOWN; //頂樓調頭
  396.         }
  397. }
  398. //電梯運行函數
  399. void Elevator(void)
  400. {
  401.         if((DOOR==OPEN)||(ElevState.FreeFlag==TRUE)) ElevWorkState(STOP);        
  402.         else   ElevWorkState(ElevState.Direction);        
  403.         TurnHead_Check();  //調頭檢測
  404.         if(ElevState.Direction==UP)  //電梯正在向上運行的情況
  405.         {
  406.                 if(ElevState.CurrentFloor<=MaxFloor)  //掃描呼叫列表中的向上方向的呼叫樓層
  407.                 {
  408.                          if(((ElevState.FloorCallTable[ElevState.CurrentFloor]&UP_IN)==UP_IN)||((ElevState.FloorCallTable[ElevState.CurrentFloor]&UP_OUT)==UP_OUT)) //到達目標樓層,停下開門5秒
  409.                          {
  410.                                  LED_OFF(LED_IN_Port,ElevState.CurrentFloor);
  411.                                  LED_OFF(LED_OUT_UP_Port,ElevState.CurrentFloor);
  412.                                  ElevState.FloorCallTable[ElevState.CurrentFloor]&=~UP_IN; //到達相應的樓層從向上列表中清除        
  413.                                  ElevState.FloorCallTable[ElevState.CurrentFloor]&=~UP_OUT; //到達相應的樓層從向上列表中清除                                         
  414.                                  ElevState.FreeFlag=TRUE; //到達樓層,暫時進入空閑狀態                                 
  415.                                  ElevWorkState(STOP);     //修改電梯狀態為停止態
  416.                              WaitDoorOpen(DoorStayTime);    //延時等待電梯門打開
  417.                                  delay_s(2*DoorStayTime);       //適當延時
  418.                                  WaitDoorClose(DoorStayTime);   //等待門關好
  419.                                  ElevWorkState(ElevState.Direction);
  420.                                  ElevState.FreeFlag=FALSE; //離開樓層,退出空閑狀態
  421.                                  ElevState.FloorTimerCount=0;         //計時器清0
  422.                          }                 
  423.                 }               
  424.         }
  425.         else
  426.         if(ElevState.Direction==DOWN)  //電梯正在向下運行的情況
  427.         {
  428.                 if(ElevState.CurrentFloor>=1)  //掃描呼叫列表中的向下方向的呼叫樓層
  429.                 {
  430.                          if(((ElevState.FloorCallTable[ElevState.CurrentFloor]&DOWN_IN)==DOWN_IN)||((ElevState.FloorCallTable[ElevState.CurrentFloor]&DOWN_OUT)==DOWN_OUT)) //到達樓層,停下開門5秒
  431.                          {        
  432.                                  LED_OFF(LED_IN_Port,ElevState.CurrentFloor);
  433.                                  LED_OFF(LED_OUT_DOWN_Port,ElevState.CurrentFloor);
  434.                                  ElevState.FloorCallTable[ElevState.CurrentFloor]&=~DOWN_IN; //到達相應的樓層從向下列表中清除        
  435.                                  ElevState.FloorCallTable[ElevState.CurrentFloor]&=~DOWN_OUT; //到達相應的樓層從向下列表中清除        
  436.                                  ElevState.FreeFlag=TRUE; //到達樓層,暫時進入空閑狀態                 
  437.                                  ElevWorkState(STOP);     //修改電梯狀態為停止態
  438.                                  WaitDoorOpen(DoorStayTime);    //延時等待電梯門打開
  439.                                  delay_s(2*DoorStayTime);       //保持門開2秒讓人進出
  440.                                  WaitDoorClose(DoorStayTime);   //適當延時
  441.                                  ElevWorkState(ElevState.Direction);   //等待門關好
  442.                                  ElevState.FreeFlag=FALSE; //離開樓層,退出空閑狀態
  443.                                  ElevState.FloorTimerCount=0;         //計時器清0
  444.                          }                        
  445.                 }               
  446.         }

  447. }  

  448. //掃描呼叫列表查看樓上或樓下是否有要向上的呼叫,有則返回TRUE,沒有返回FALSE
  449. u8 FloorCall_UP(u8 floorside) // floorside  =  DOWN樓下  UP樓上
  450. {
  451.          u8 i;

  452.          if(floorside==UP)
  453.          {
  454.                  for(i=ElevState.CurrentFloor+1;i<=MaxFloor;i++) //掃描呼叫列表樓上是否有要向上的呼叫
  455.                  {
  456.                          if(((ElevState.FloorCallTable[i]&UP_IN)==UP_IN)||((ElevState.FloorCallTable[i]&UP_OUT)==UP_OUT)) //如果掃描到上方樓層有向上的呼叫
  457.                          {
  458.                                  return TRUE;
  459.                          }
  460.                  }
  461.                  return FALSE;
  462.          }
  463.          else
  464.          if(floorside==DOWN)
  465.          {
  466.                  for(i=ElevState.CurrentFloor-1;i>=1;i--) //掃描呼叫列表樓下是否有要向上的呼叫
  467.                  {
  468.                          if(((ElevState.FloorCallTable[i]&UP_IN)==UP_IN)||((ElevState.FloorCallTable[i]&UP_OUT)==UP_OUT)) //如果掃描到上方樓層有向上的呼叫
  469.                          {
  470.                                  return TRUE;
  471.                          }
  472.                  }
  473.                  return FALSE;
  474.          }
  475.          else return FALSE;
  476. }
  477. //掃描呼叫列表查看樓上或樓下是否有要向下的呼叫,有則返回TRUE,沒有返回FALSE
  478. u8 FloorCall_DOWN(u8 floorside) // floorside  =  DOWN樓下  UP樓上
  479. {
  480.          u8 i;

  481.          if(floorside==UP)
  482.          {
  483.                  for(i=ElevState.CurrentFloor+1;i<=MaxFloor;i++) //掃描呼叫列表樓上是否有要向下的呼叫
  484.                  {
  485.                          if(((ElevState.FloorCallTable[i]&DOWN_IN)==DOWN_IN)||((ElevState.FloorCallTable[i]&DOWN_OUT)==DOWN_OUT)) //如果掃描到上方樓層有向下的呼叫
  486.                          {
  487.                                  return TRUE;
  488.                          }
  489.                  }
  490.                  return FALSE;
  491.          }
  492.          else
  493.          if(floorside==DOWN)
  494.          {
  495.                  for(i=ElevState.CurrentFloor-1;i>=1;i--) //掃描呼叫列表樓下是否有要向下的呼叫
  496.                  {
  497.                          if(((ElevState.FloorCallTable[i]&DOWN_IN)==DOWN_IN)||((ElevState.FloorCallTable[i]&DOWN_OUT)==DOWN_OUT)) //如果掃描到上方樓層有向下的呼叫
  498.                          {
  499.                                  return TRUE;
  500.                          }
  501.                  }
  502.                  return FALSE;
  503.          }
  504.          else return FALSE;
  505. }

  506. ////掃描呼叫列表是否為空(沒有呼叫),空-返回TRUE  有呼叫-返回FALSE
  507. u8 DelNullCheck(void) //掃描呼叫列表是否空閑
  508. {
  509.         u8 i;
  510.         u8 result;
  511.                
  512.         for(i=1;i<=MaxFloor;i++)
  513.         {
  514.           if(ElevState.FloorCallTable[i]!=Null)
  515.                 {
  516.                          result=FALSE; //非空閑
  517.        break;
  518.                 }
  519.                 else if(i==MaxFloor) result=TRUE;  //空閑
  520.         }
  521.         return result;
  522. }
  523. //樓層呼叫處理函數(無需修改)
  524. void FloorCallCheck(void)
  525. {
  526.         if(DelNullCheck()==FALSE) //非空閑
  527.         {
  528.                  ElevState.FreeFlag=FALSE; //退出空閑狀態
  529.                  ElevState.ElevRunning=TRUE;//正在運行標志打開
  530.         }
  531.         else  ElevState.FreeFlag=TRUE; //進入空閑狀態
  532.         TurnHead_Check();
  533.         if((ElevState.FreeFlag==FALSE)&&(DOOR==CLOSE)) //非空閑下
  534.         {                                
  535.      if(ElevState.Direction==UP)//方向向上
  536.                  {
  537.                     if((FloorCall_UP(UP)==TRUE)||(FloorCall_DOWN(UP)==TRUE)) //如果當前樓層上方有呼叫向上的 或 如果當前樓層上方有呼叫向下的
  538.                                 {
  539.                                        
  540.                                   if(ElevState.FloorTimerCount>FloorStayTime) //檢測是否到達樓層  如果接收到 到達樓層的限位開關信號,則當前樓層值+1(這里用定時器來模擬)
  541.                                   {                                                               
  542.                                           ElevState.FloorTimerCount=0;         //計時器清0
  543.                                           ElevState.CurrentFloor++;//電梯繼續往上走
  544.                                   }
  545.                                        
  546.                                                                           
  547.                                 }
  548.                                 else ElevState.Direction=DOWN; //調頭                                
  549.                  }
  550.                  else
  551.                  if(ElevState.Direction==DOWN)//方向向下
  552.                  {
  553.                     if((FloorCall_DOWN(DOWN)==TRUE)||(FloorCall_UP(DOWN)==TRUE)) //如果當前樓層下方有呼叫向下的 或 如果當前樓層下方有呼叫向上的
  554.                                 {

  555.                                   if(ElevState.FloorTimerCount>FloorStayTime) //檢測是否到達樓層 (這里用定時器來模擬)
  556.                                   {                                                               
  557.                                           ElevState.FloorTimerCount=0;        
  558.                                           ElevState.CurrentFloor--;//電梯繼續往下走
  559.                                   }
  560.                                 
  561.                                 }
  562.                                 else ElevState.Direction=UP; //調頭                        
  563.                  }
  564.         }
  565.         else
  566.         {               
  567.                 ElevWorkState(STOP); //停止運行
  568.                 ElevState.ElevRunning=FALSE;//正在運行標志關閉
  569.         }
  570. }

  571. //系統初使化
  572. void SYSYEM_INIT(void)
  573. {
  574.          u8 i;
  575.          ElevState.CurrentFloor=1;
  576.          ElevState.Direction=UP;              //初使化方向為向上
  577.          ElevState.FloorTimerCount=0;                //定時器版計時清0
  578.          ElevState.FreeFlag=TRUE;             //初使化為空閑狀態
  579.          ElevState.ElevRunning=FALSE;         //運行標志置FALSE  表示暫停運行
  580.          Uart.RX_COUNT=0;                    //串口接收計數清0
  581.          for(i=0;i<=MaxFloor;i++)
  582.          {
  583.                  ElevState.FloorCallTable[i]=Null;  //初使化呼叫列表為Null
  584.          }
  585.          DOOR_Close;                          //關門
  586. }

  587. void EXTI0_IRQHandler(void) interrupt 0   //樓層傳感器中斷
  588. {         
  589.         #if (USE_MODE==1)
  590.         ElevState.ArriveFlag=TRUE;//觸發中斷后表示到達樓層,讓到達樓層標志置TRUE
  591.         #endif
  592. }
  593. void EXTI1_IRQHandler(void) interrupt 2    //矩陣按鍵中斷
  594. {
  595.    KeyDatHandle(KeyScan()); //把KeyScan()按鍵掃描函數返回的按鍵值帶入到KeyDatHandle()處理按鍵
  596. }
  597. void TIM0_IRQHandler(void)  interrupt 1    //定時模擬電梯上升和下降
  598. {
  599.          TH0=(65536-50000)/256;//定時50ms
  600.          TL0=(65536-50000)%256;//定時50ms
  601.         
  602.          TimerCount++;
  603.          if(TimerCount==20)  //1秒
  604.          {
  605.                  TimerCount=0;
  606.                  Timer_Second++;
  607.          }        
  608.          if(DelNullCheck()==FALSE) ElevState.FloorTimerCount++; //非空閑狀態計時累加
  609.          else ElevState.FloorTimerCount=0;  //空閑狀態計時清0
  610. }

  611. void Uart_IRQHandler(void) interrupt 4  //用于電梯之間的通信
  612. {                  
  613.   if(RI==1)        //判斷是否為接收中斷(串口中斷分為發送中斷和接收中斷,均用同一個中斷服務函數入口)
  614.         {
  615.                 RI = 0;        //清除RI接收中斷標志
  616.                 Uart.RX_BUFF[Uart.RX_COUNT++]=SBUF;
  617.                 if(Uart.RX_COUNT==Uart_RX_LEN) Uart.RX_COUNT=0;
  618.         }        
  619. }

  620. void main(void)  //主函數
  621. {
  622.         SYSYEM_INIT();
  623.         EXTI0_Init();
  624.         EXTI1_Init();
  625.         TIMER0_Init();
  626.         while(1)
  627.         {         
  628.                  KeyPort_Y=0x00;   //不可刪除
  629.                  FloorCallCheck();
  630.                  Elevator();   
  631.         }
  632. }
復制代碼

仿真-代碼-設計文檔下載: 八層電梯模擬控制.7z (1010.81 KB, 下載次數: 0)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

無效樓層,該帖已經被刪除
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲欧洲一区二区 | 国产亚洲精品成人av久久ww | 中文字幕一区二区三区精彩视频 | 亚洲一区 中文字幕 | 国产精品美女在线观看 | 网站国产 | 久久久久国产 | 国产xxxx在线 | 成人免费观看男女羞羞视频 | 亚洲国产福利视频 | 日本久久精品视频 | 欧美日韩综合一区 | 国产亚洲精品久久久优势 | 91精品国产一区二区三区 | 成人在线免费观看 | 91麻豆精品国产91久久久资源速度 | 9久久精品 | 夜夜爽99久久国产综合精品女不卡 | 成人18亚洲xxoo| 欧美激情亚洲激情 | 久久国产精品首页 | 国产精品免费看 | 天天综合网天天综合色 | 日韩中文字幕在线视频观看 | 羞羞在线视频 | 欧美电影免费观看 | 精品在线一区 | 国产a级黄色录像 | 久久影院一区 | 国产视频线观看永久免费 | 国产一区999| 91大片| 日韩电影在线一区 | 欧美一级免费 | av官网在线| 东方伊人免费在线观看 | 久久精品—区二区三区 | 日韩中文字幕在线观看 | 欧美日韩淫片 | 亚洲精品综合一区二区 | 日日日日日日bbbbb视频 |