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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機8層電梯程序(傳感器版+定時模擬版)Proteus仿真

[復制鏈接]
跳轉到指定樓層
樓主
第一個版本:8層樓梯傳感器版
第二個版本:8層樓梯定時模擬版

8層樓梯傳感器版仿真




.c程序:


  1. /*******************電梯主程序**********************/

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

  4. /******************移植部分代碼*************************/
  5. sbit DOOR=P3^5;
  6. sbit DlevMotor_P=P3^6; //電梯電機正極
  7. sbit DlevMotor_N=P3^7; //電梯電機負極
  8. #define SEGPort    P0
  9. #define KeyPort_X  P1
  10. #define KeyPort_Y  P2
  11. /******************************************************/


  12. #define u8  unsigned char
  13. #define u16 unsigned int
  14.         
  15. #define MaxFloor   8

  16. #define FloorStayTime 40        //單位:50ms
  17. #define DoorStayTime  2   //單位:S

  18. #define TRUE  1
  19. #define FALSE 0

  20. #define Null  0  
  21. #define STOP  1
  22. #define UP    2
  23. #define DOWN  3
  24. #define Dlev_UP    DlevMotor_P=0;DlevMotor_N=1  //低電平有效
  25. #define Dlev_DOWN  DlevMotor_P=1;DlevMotor_N=0  //低電平有效
  26. #define Dlev_STOP  DlevMotor_P=1;DlevMotor_N=1  //低電平有效

  27. #define OPEN  1  
  28. #define CLOSE 0
  29. #define DOOR_Open  DOOR=OPEN
  30. #define DOOR_Close DOOR=CLOSE


  31. typedef struct
  32. {
  33.         u8 DlevRunning;
  34.   u8 CurrentFloor;
  35.         u8 Direction;
  36.         u8 FloorCallTable[MaxFloor+1];//數組[0]不用,從[1]開始使用
  37.         u8 FloorTimerCount;        
  38.         u8 ArriveFlag;  //到達樓層信號(用于停止或在前一樓層提前加減速)
  39.         u8 FreeFlag;        
  40. }TYPEDEF_DLEVSTATE;
  41. TYPEDEF_DLEVSTATE DlevState;


  42. u8 code SEG_NUM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0x7D,0x07,0x7f,0x6f};   //SEG數碼管段碼  0~9
  43. u8 Timer_Second;
  44. u16 TimerCount;
  45. u8 RICount=0;
  46. u8 RIOver_Flag=0;
  47. u8 ExternKey[2]={0}; //外部按鍵按下信息
  48. u8 FloorCallTableBUFF[MaxFloor+10]={0};
  49. u8 KeyPressFlag=0;

  50. void delay_ms(u16 xms);
  51. void delay_s(u8 xs);
  52. void EXTI0_Init(void);
  53. void Timer0_Init(void);
  54. void USART_Configure(u16 BaudRate);
  55. u8 KeyScan(void);
  56. void KeyDatHandle(u8 key);
  57. void WaitDoorOpen(u8 ts);
  58. void WaitDoorClose(u8 ts);
  59. void SEG_Display(u8 segnum);
  60. void DlevWorkState(u8 state);
  61. void Elevator(void);
  62. u8 FloorCall_UP(u8 floorside);
  63. u8 FloorCall_DOWN(u8 floorside);
  64. void FLOORCALLCHECK(void);
  65. void SYSYEM_INIT(void);


  66. void delay_ms(u16 xms)
  67. {
  68.         u8 i;
  69.         u16 t;
  70.   for(t=xms;t>0;t--)
  71.           for(i=112;i>0;i--);
  72. }

  73. void delay_s(u8 xs)
  74. {
  75.    TimerCount=0;
  76.          Timer_Second=0;
  77.    while(Timer_Second<xs);        
  78. }

  79. void EXTI0_Init(void)
  80. {
  81.   EA = 1;  
  82.         IT0= 1; //下降沿觸發
  83.         EX0= 1;
  84. }

  85. void EXTI1_Init(void)
  86. {
  87.   EA = 1;  
  88.         IT1= 1; //下降沿觸發
  89.         EX1= 1;
  90. }

  91. void Timer0_Init(void)
  92. {
  93.         TMOD |= 0x01;  
  94.   TH0=(65536-50000)/256;
  95.         TL0=(65536-50000)%256;
  96.         EA = 1;
  97.         ET0 = 1;
  98.         TR0 = 1;
  99. }


  100. void USART_Configure(u16 BaudRate)
  101. {
  102.         u8 TH1_Dat;
  103.         
  104.   switch(BaudRate)
  105.         {
  106.           case 1200:  TH1_Dat=0xE8; break;
  107.                 case 2400:  TH1_Dat=0xF4; break;
  108.                 case 4800:  TH1_Dat=0xFA; break;
  109.                 case 9600:  TH1_Dat=0xFD; break;
  110.                 case 14400: TH1_Dat=0xFE; break;
  111.         }
  112.         TMOD |= 0x20;
  113.         SCON |= 0x50;
  114.         TH1 = TH1_Dat;
  115.         TL1 = TH1;
  116.         PCON |= 0x00;
  117.         EA = 1;
  118.         ES = 1;
  119.         TR1 = 1;  
  120. }



  121. u8 KeyScan(void)
  122. {
  123.         u8 keynum;
  124.   
  125.         KeyPort_Y=0x00;
  126.         KeyPort_X=0xFF;
  127.         _nop_(); _nop_(); _nop_(); _nop_();
  128.         if(KeyPort_X!=0xFF)
  129.         {
  130.          delay_ms(10);
  131.          if(KeyPort_X!=0xFF)
  132.          {
  133.                  switch(KeyPort_X)
  134.                  {
  135.                          case 0x7F: keynum=1;   break;
  136.                          case 0xBF: keynum=9;   break;
  137.                          case 0xDF: keynum=17;  break;
  138.                          case 0xEF: keynum=25;  break;
  139.                          case 0xF7: keynum=33;  break;
  140.                          case 0xFB: keynum=41;  break;
  141.                          case 0xFD: keynum=49;  break;
  142.                          case 0xFE: keynum=57;  break;
  143.                  }
  144.                  KeyPort_Y=0xFF;
  145.                  KeyPort_X=0x00;
  146.                  _nop_(); _nop_(); _nop_(); _nop_();
  147.                  if(KeyPort_Y!=0xFF)
  148.                  {
  149.                          switch(KeyPort_Y)
  150.                          {
  151.                                  case 0xFE: keynum=keynum+0;  break;
  152.                                  case 0xFD: keynum=keynum+1;  break;
  153.                                  case 0xFB: keynum=keynum+2;  break;
  154.                                  case 0xF7: keynum=keynum+3;  break;
  155.                                  case 0xEF: keynum=keynum+4;  break;
  156.                                  case 0xDF: keynum=keynum+5;  break;
  157.                                  case 0xBF: keynum=keynum+6;  break;
  158.                                  case 0x7F: keynum=keynum+7;  break;
  159.                          }
  160.                  }
  161.                  KeyPort_Y=0x00;
  162.    }
  163.         }
  164.         else keynum=0;
  165.         return keynum;
  166. }

  167. void KeyDatHandle(u8 key)
  168. {
  169.         if(key==0)
  170.         {
  171.         
  172.         }
  173.         else
  174.         if(key<=MaxFloor) //樓梯內的樓層選擇按鍵
  175.         {
  176.                 if(key>DlevState.CurrentFloor) DlevState.FloorCallTable[key]=UP;
  177.                 else
  178.                 if(key<DlevState.CurrentFloor) DlevState.FloorCallTable[key]=DOWN;
  179.         }
  180.         else
  181.         if((key<=MaxFloor*2)&&(key>MaxFloor+1))  //每個樓層門口外的向下按鍵(底樓按向下無效)
  182.         {
  183.                  DlevState.FloorCallTable[key-MaxFloor]=DOWN;
  184.         }
  185.         else
  186.         if(key<MaxFloor*3) //每個樓層門口外的向上按鍵(頂樓按向上無效)
  187.         {
  188.                  DlevState.FloorCallTable[key-MaxFloor*2]=UP;
  189.         }
  190.         else
  191.         if(key==MaxFloor*3+1)  //開門
  192.         {
  193.                 if(DlevState.DlevRunning==FALSE)
  194.                 {
  195.                   if(DOOR==CLOSE) DOOR_Open;
  196.                 }
  197.         }
  198.         else
  199.         if(key==MaxFloor*3+2) //關門
  200.         {
  201.                 if(DOOR==OPEN)
  202.                 {
  203.                         DOOR_Close;
  204.                         DlevState.FloorTimerCount=0;         //計時器清0
  205.                 }
  206.         }
  207. }

  208. void WaitDoorOpen(u8 ts)
  209. {
  210.         DOOR_Open;
  211.         delay_s(ts);
  212. }

  213. void WaitDoorClose(u8 ts)
  214. {
  215.         DOOR_Close;
  216.         delay_s(ts);
  217. }

  218. void SEG_Display(u8 segnum)
  219. {
  220.   SEGPort=~SEG_NUM[segnum];
  221. }

  222. void DlevWorkState(u8 state)
  223. {
  224.   if(state==UP)
  225.         {
  226.                 Dlev_UP;
  227.                 DlevState.DlevRunning=TRUE;
  228.         }
  229.         else
  230.         if(state==DOWN)
  231.         {
  232.                 Dlev_DOWN;
  233.                 DlevState.DlevRunning=TRUE;
  234.         }
  235.         else
  236.         if(state==STOP)
  237.         {
  238.                 Dlev_STOP;
  239.                 DlevState.DlevRunning=FALSE;
  240.         }
  241.         SEG_Display(DlevState.CurrentFloor);                //數碼管顯示
  242. }
  243.         
  244. void Elevator(void)
  245. {
  246.         if((DOOR==OPEN)||(DlevState.FreeFlag==TRUE)) DlevWorkState(STOP);        
  247.   else
  248.         DlevWorkState(DlevState.Direction);        
  249.         
  250.         if(DlevState.Direction==UP)  //電梯正在向上運行的情況
  251.         {
  252.                 if(DlevState.CurrentFloor<=MaxFloor)  //掃描呼叫列表中的向上方向的呼叫樓層
  253.                 {
  254.                          if(DlevState.FloorCallTable[DlevState.CurrentFloor]==UP) //到達目標樓層,停下開門5秒
  255.                          {
  256.                                  DlevState.FloorCallTable[DlevState.CurrentFloor]=Null; //到達相應的樓層從向上列表中清除                                         
  257.                                  DlevState.FreeFlag=TRUE; //到達樓層,暫停進入空閑狀態                                 
  258.                                  DlevWorkState(STOP);
  259.                            WaitDoorOpen(DoorStayTime);
  260.                                  delay_s(2*DoorStayTime);       //保持門開2秒讓人進出
  261.                                  WaitDoorClose(DoorStayTime);
  262.                                  DlevWorkState(DlevState.Direction);
  263.                                  DlevState.FreeFlag=FALSE; //離開樓層,退出空閑狀態
  264.                                  DlevState.FloorTimerCount=0;         //計時器清0
  265.                          }                 
  266.                 }               
  267.         }
  268.         else
  269.         if(DlevState.Direction==DOWN)  //電梯正在向下運行的情況
  270.         {
  271.                 if(DlevState.CurrentFloor>=1)  //掃描呼叫列表中的向下方向的呼叫樓層
  272.                 {
  273.                          if(DlevState.FloorCallTable[DlevState.CurrentFloor]==DOWN) //到達樓層,停下開門5秒
  274.                          {        
  275.          DlevState.FloorCallTable[DlevState.CurrentFloor]=Null; //到達相應的樓層從向下列表中清除        
  276.                                  DlevState.FreeFlag=TRUE; //到達樓層,暫停進入空閑狀態                 
  277.                                  DlevWorkState(STOP);
  278.                            WaitDoorOpen(DoorStayTime);
  279.                                  delay_s(2*DoorStayTime);       //保持門開2秒讓人進出
  280.                                  WaitDoorClose(DoorStayTime);
  281.                                  DlevWorkState(DlevState.Direction);
  282.                                  DlevState.FreeFlag=FALSE; //離開樓層,退出空閑狀態
  283.                                  DlevState.FloorTimerCount=0;         //計時器清0
  284.                          }                 
  285.                 }               
  286.         }

  287. }  

  288. u8 FloorCall_UP(u8 floorside) // floorside  =  DOWN在樓下  UP在樓上
  289. {
  290.          u8 i;

  291.          if(floorside==UP)
  292.          {
  293.                  for(i=DlevState.CurrentFloor+1;i<=MaxFloor;i++) //掃描呼叫列表樓上是否有要向上的呼叫
  294.                  {
  295.                          if(DlevState.FloorCallTable[i]==UP) //如果掃描到上方樓層有向上的呼叫
  296.                          {
  297.                                  return TRUE;
  298.                          }
  299.                  }
  300.                  return FALSE;
  301.          }
  302.          else
  303.          if(floorside==DOWN)
  304.          {
  305.                  for(i=DlevState.CurrentFloor-1;i>=1;i--) //掃描呼叫列表樓下是否有要向上的呼叫
  306.                  {
  307.                          if(DlevState.FloorCallTable[i]==UP) //如果掃描到上方樓層有向上的呼叫
  308.                          {
  309.                                  return TRUE;
  310.                          }
  311.                  }
  312.                  return FALSE;
  313.          }
  314. }

  315. u8 FloorCall_DOWN(u8 floorside) // floorside  =  DOWN在樓下  UP在樓上
  316. {
  317.          u8 i;

  318.          if(floorside==UP)
  319.          {
  320.                  for(i=DlevState.CurrentFloor+1;i<=MaxFloor;i++) //掃描呼叫列表樓上是否有要向下的呼叫
  321.                  {
  322.                          if(DlevState.FloorCallTable[i]==DOWN) //如果掃描到上方樓層有向下的呼叫
  323.                          {
  324.                                  return TRUE;
  325.                          }
  326.                  }
  327.                  return FALSE;
  328.          }
  329.          else
  330.          if(floorside==DOWN)
  331.          {
  332.                  for(i=DlevState.CurrentFloor-1;i>=1;i--) //掃描呼叫列表樓下是否有要向下的呼叫
  333.                  {
  334.                          if(DlevState.FloorCallTable[i]==DOWN) //如果掃描到上方樓層有向下的呼叫
  335.                          {
  336.                                  return TRUE;
  337.                          }
  338.                  }
  339.                  return FALSE;
  340.          }
  341. }

  342. void FLOORCALLCHECK(void)
  343. {
  344.         u8 i;
  345.                
  346.         for(i=1;i<=MaxFloor;i++) //掃描呼叫列表是否空閑
  347.         {
  348.           if(DlevState.FloorCallTable[i]!=Null) //非空閑
  349.                 {
  350.                          DlevState.FreeFlag=FALSE; //退出空閑狀態
  351.                          DlevState.DlevRunning=TRUE;//正在運行標志打開
  352.        break;
  353.                 }
  354.                 else if(i==MaxFloor) DlevState.FreeFlag=TRUE; //進入空閑狀態
  355.         }
  356.         if(DlevState.CurrentFloor==1)  DlevState.Direction=UP;  //1樓調頭
  357.         else
  358.         if(DlevState.CurrentFloor==MaxFloor)  DlevState.Direction=DOWN; //頂樓調頭
  359.   if((DlevState.FreeFlag==FALSE)&&(DOOR==CLOSE)) //非空閑下
  360.         {                                
  361.      if(DlevState.Direction==UP)//方向向上
  362.                  {
  363.                     if((FloorCall_UP(UP)==TRUE)||(FloorCall_DOWN(UP)==TRUE)) //如果當前樓層上方有呼叫向上的 或 如果當前樓層上方有呼叫向下的
  364.                                 {
  365.                                   if(DlevState.ArriveFlag==TRUE) //檢測是否到達樓層  如果接收到 到達樓層的限位開關信號,則當前樓層值+1
  366.                                   {               
  367.             DlevState.ArriveFlag=FALSE; //清除標志                                                
  368.                                           DlevState.FloorTimerCount=0;         //計時器清0
  369.                                           DlevState.CurrentFloor++;//電梯繼續往上走
  370.                                   }
  371.                                 }
  372.                                 else
  373.         if((FloorCall_UP(DOWN)==TRUE)||(FloorCall_DOWN(DOWN)==TRUE)) //掃描下方是否是有呼叫
  374.                                 {
  375.                                         DlevState.Direction=DOWN; //樓層下方有呼叫則調頭
  376.                                 }
  377.                                 else DlevState.FreeFlag=TRUE; //否則進入空閑狀態
  378.                  }
  379.                  else
  380.                  if(DlevState.Direction==DOWN)//方向向下
  381.                  {
  382.                     if((FloorCall_DOWN(DOWN)==TRUE)||(FloorCall_UP(DOWN)==TRUE)) //如果當前樓層下方有呼叫向下的 或 如果當前樓層下方有呼叫向上的
  383.                                 {
  384.                                   if(DlevState.ArriveFlag==TRUE) //檢測是否到達樓層  如果接收到 到達樓層的限位開關信號,則當前樓層值+1
  385.                                   {        
  386.             DlevState.ArriveFlag=FALSE; //清除標志                                                               
  387.                                           DlevState.FloorTimerCount=0;        
  388.                                           DlevState.CurrentFloor--;//電梯繼續往下走
  389.                                   }
  390.                                 }
  391.                                 else
  392.         if((FloorCall_DOWN(UP)==TRUE)||(FloorCall_UP(UP)==TRUE)) //掃描上方是否是有呼叫
  393.                                 {
  394.                                         DlevState.Direction=UP; //樓層上方有呼叫則調頭
  395.                                 }
  396.                                 else DlevState.FreeFlag=TRUE; //否則進入空閑狀態
  397.                  }
  398.         }
  399.         else
  400.         {               
  401.            DlevWorkState(STOP); //停止運行
  402.                  DlevState.DlevRunning=FALSE;//正在運行標志關閉
  403.         }
  404. }

  405. void SYSYEM_INIT(void)
  406. {
  407.          u8 i;
  408.         
  409.          DlevState.CurrentFloor=1;
  410.          DlevState.Direction=UP;              //初使化方向為向上
  411.          DlevState.FloorTimerCount=0;        
  412.          DlevState.FreeFlag=TRUE;             //初使化為空閑狀態
  413.          DlevState.DlevRunning=FALSE;
  414.          RIOver_Flag=FALSE;
  415.          RICount=0;
  416.          for(i=1;i<=MaxFloor;i++)
  417.          {
  418.                  DlevState.FloorCallTable[i]=Null; //初使化呼叫列表為Null
  419.          }
  420.          DOOR_Close;
  421. }

  422. void main(void)
  423. {
  424.         SYSYEM_INIT();
  425.         EXTI0_Init();
  426.         EXTI1_Init();
  427.         Timer0_Init();
  428.         USART_Configure(9600);
  429.   while(1)
  430.         {
  431.                  KeyPort_Y=0x00;
  432.                  FLOORCALLCHECK();
  433.            Elevator();   
  434.         }
  435. }

  436. void EXTI0_IRQHandler(void) interrupt 0
  437. {         
  438.          DlevState.ArriveFlag=TRUE;
  439. }
  440. void EXTI1_IRQHandler(void) interrupt 2
  441. {
  442.    KeyDatHandle(KeyScan());
  443. }

  444. void TIM0_IRQHandler(void)  interrupt 1
  445. {
  446.    TH0=(65536-50000)/256;
  447.          TL0=(65536-50000)%256;
  448.         
  449.          TimerCount++;
  450.          if(TimerCount==20)  //1秒
  451.          {
  452.                  TimerCount=0;
  453.                  Timer_Second++;
  454.          }         
  455.          DlevState.FloorTimerCount++;
  456. }

  457. void USART_IRQHandler(void) interrupt 4
  458. {                  

  459. }

復制代碼

8層樓梯定時模擬版仿真:




.c程序:

  1. /*******************電梯主程序**********************/

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

  4. /******************移植部分代碼*************************/
  5. sbit DOOR=P3^5;
  6. sbit DlevMotor_P=P3^6; //電梯電機正極
  7. sbit DlevMotor_N=P3^7; //電梯電機負極
  8. #define SEGPort    P0
  9. #define KeyPort_X  P1
  10. #define KeyPort_Y  P2
  11. /******************************************************/


  12. #define u8  unsigned char
  13. #define u16 unsigned int
  14.         
  15. #define MaxFloor   8

  16. #define FloorStayTime 40        //單位:50ms
  17. #define DoorStayTime  2   //單位:S

  18. #define TRUE  1
  19. #define FALSE 0

  20. #define Null  0  
  21. #define STOP  1
  22. #define UP    2
  23. #define DOWN  3
  24. #define Dlev_UP    DlevMotor_P=0;DlevMotor_N=1  //低電平有效
  25. #define Dlev_DOWN  DlevMotor_P=1;DlevMotor_N=0  //低電平有效
  26. #define Dlev_STOP  DlevMotor_P=1;DlevMotor_N=1  //低電平有效

  27. #define OPEN  1  
  28. #define CLOSE 0
  29. #define DOOR_Open  DOOR=OPEN
  30. #define DOOR_Close DOOR=CLOSE


  31. typedef struct
  32. {
  33.         u8 DlevRunning;
  34.   u8 CurrentFloor;
  35.         u8 Direction;
  36.         u8 FloorCallTable[MaxFloor+1];//數組[0]不用,從[1]開始使用
  37.         u8 FloorTimerCount;        
  38.         u8 ArriveFlag;      //到達樓層信號(用于停止或在前一樓層提前加減速)(此版本是定時器模擬,用不到)
  39.         u8 FreeFlag;        
  40. }TYPEDEF_DLEVSTATE;
  41. TYPEDEF_DLEVSTATE DlevState;


  42. u8 code SEG_NUM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0x7D,0x07,0x7f,0x6f};   //SEG數碼管段碼  0~9
  43. u8 Timer_Second;
  44. u16 TimerCount;
  45. u8 RICount=0;
  46. u8 RIOver_Flag=0;
  47. u8 ExternKey[2]={0}; //外部按鍵按下信息
  48. u8 FloorCallTableBUFF[MaxFloor+10]={0};
  49. u8 KeyPressFlag=0;

  50. void delay_ms(u16 xms);
  51. void delay_s(u8 xs);
  52. void EXTI0_Init(void);
  53. void Timer0_Init(void);
  54. void USART_Configure(u16 BaudRate);
  55. u8 KeyScan(void);
  56. void KeyDatHandle(u8 key);
  57. void WaitDoorOpen(u8 ts);
  58. void WaitDoorClose(u8 ts);
  59. void SEG_Display(u8 segnum);
  60. void DlevWorkState(u8 state);
  61. void Elevator(void);
  62. u8 FloorCall_UP(u8 floorside);
  63. u8 FloorCall_DOWN(u8 floorside);
  64. void FLOORCALLCHECK(void);
  65. void SYSYEM_INIT(void);


  66. void delay_ms(u16 xms)
  67. {
  68.         u8 i;
  69.         u16 t;
  70.   for(t=xms;t>0;t--)
  71.           for(i=112;i>0;i--);
  72. }

  73. void delay_s(u8 xs)
  74. {
  75.    TimerCount=0;
  76.          Timer_Second=0;
  77.    while(Timer_Second<xs);        
  78. }

  79. void EXTI0_Init(void)
  80. {
  81.   EA = 1;  
  82.         IT0= 1; //下降沿觸發
  83.         EX0= 1;
  84. }

  85. void EXTI1_Init(void)
  86. {
  87.   EA = 1;  
  88.         IT1= 1; //下降沿觸發
  89.         EX1= 1;
  90. }

  91. void Timer0_Init(void)
  92. {
  93.         TMOD |= 0x01;  
  94.   TH0=(65536-50000)/256;
  95.         TL0=(65536-50000)%256;
  96.         EA = 1;
  97.         ET0 = 1;
  98.         TR0 = 1;
  99. }


  100. void USART_Configure(u16 BaudRate)
  101. {
  102.         u8 TH1_Dat;
  103.         
  104.   switch(BaudRate)
  105.         {
  106.           case 1200:  TH1_Dat=0xE8; break;
  107.                 case 2400:  TH1_Dat=0xF4; break;
  108.                 case 4800:  TH1_Dat=0xFA; break;
  109.                 case 9600:  TH1_Dat=0xFD; break;
  110.                 case 14400: TH1_Dat=0xFE; break;
  111.         }
  112.         TMOD |= 0x20;
  113.         SCON |= 0x50;
  114.         TH1 = TH1_Dat;
  115.         TL1 = TH1;
  116.         PCON |= 0x00;
  117.         EA = 1;
  118.         ES = 1;
  119.         TR1 = 1;  
  120. }



  121. u8 KeyScan(void)
  122. {
  123.         u8 keynum;
  124.   
  125.         KeyPort_Y=0x00;
  126.         KeyPort_X=0xFF;
  127.         _nop_(); _nop_(); _nop_(); _nop_();
  128.         if(KeyPort_X!=0xFF)
  129.         {
  130.          delay_ms(10);
  131.          if(KeyPort_X!=0xFF)
  132.          {
  133.                  switch(KeyPort_X)
  134.                  {
  135.                          case 0x7F: keynum=1;   break;
  136.                          case 0xBF: keynum=9;   break;
  137.                          case 0xDF: keynum=17;  break;
  138.                          case 0xEF: keynum=25;  break;
  139.                          case 0xF7: keynum=33;  break;
  140.                          case 0xFB: keynum=41;  break;
  141.                          case 0xFD: keynum=49;  break;
  142.                          case 0xFE: keynum=57;  break;
  143.                  }
  144.                  KeyPort_Y=0xFF;
  145.                  KeyPort_X=0x00;
  146.                  _nop_(); _nop_(); _nop_(); _nop_();
  147.                  if(KeyPort_Y!=0xFF)
  148.                  {
  149.                          switch(KeyPort_Y)
  150.                          {
  151.                                  case 0xFE: keynum=keynum+0;  break;
  152.                                  case 0xFD: keynum=keynum+1;  break;
  153.                                  case 0xFB: keynum=keynum+2;  break;
  154.                                  case 0xF7: keynum=keynum+3;  break;
  155.                                  case 0xEF: keynum=keynum+4;  break;
  156.                                  case 0xDF: keynum=keynum+5;  break;
  157.                                  case 0xBF: keynum=keynum+6;  break;
  158.                                  case 0x7F: keynum=keynum+7;  break;
  159.                          }
  160.                  }
  161.                  KeyPort_Y=0x00;
  162.    }
  163.         }
  164.         else keynum=0;
  165.         return keynum;
  166. }

  167. void KeyDatHandle(u8 key)
  168. {
  169.         if(key==0)
  170.         {
  171.         
  172.         }
  173.         else
  174.         if(key<=MaxFloor) //樓梯內的樓層選擇按鍵
  175.         {
  176.                 if(key>DlevState.CurrentFloor) DlevState.FloorCallTable[key]=UP;
  177.                 else
  178.                 if(key<DlevState.CurrentFloor) DlevState.FloorCallTable[key]=DOWN;
  179.         }
  180.         else
  181.         if((key<=MaxFloor*2)&&(key>MaxFloor+1))  //每個樓層門口外的向下按鍵(底樓按向下無效)
  182.         {
  183.                  DlevState.FloorCallTable[key-MaxFloor]=DOWN;
  184.         }
  185.         else
  186.         if(key<MaxFloor*3) //每個樓層門口外的向上按鍵(頂樓按向上無效)
  187.         {
  188.                  DlevState.FloorCallTable[key-MaxFloor*2]=UP;
  189.         }
  190.         else
  191.         if(key==MaxFloor*3+1)  //開門
  192.         {
  193.                 if(DlevState.DlevRunning==FALSE)
  194.                 {
  195.                   if(DOOR==CLOSE) DOOR_Open;
  196.                 }
  197.         }
  198.         else
  199.         if(key==MaxFloor*3+2) //關門
  200.         {
  201.                 if(DOOR==OPEN)
  202.                 {
  203.                         DOOR_Close;
  204.                         DlevState.FloorTimerCount=0;         //計時器清0
  205.                 }
  206.         }
  207. }

  208. void WaitDoorOpen(u8 ts)
  209. {
  210.         DOOR_Open;
  211.         delay_s(ts);
  212. }

  213. void WaitDoorClose(u8 ts)
  214. {
  215.         DOOR_Close;
  216.         delay_s(ts);
  217. }

  218. void SEG_Display(u8 segnum)
  219. {
  220.   SEGPort=~SEG_NUM[segnum];
  221. }

  222. void DlevWorkState(u8 state)
  223. {
  224.   if(state==UP)
  225.         {
  226.                 Dlev_UP;
  227.                 DlevState.DlevRunning=TRUE;
  228.         }
  229.         else
  230.         if(state==DOWN)
  231.         {
  232.                 Dlev_DOWN;
  233.                 DlevState.DlevRunning=TRUE;
  234.         }
  235.         else
  236.         if(state==STOP)
  237.         {
  238.                 Dlev_STOP;
  239.                 DlevState.DlevRunning=FALSE;
  240.         }
  241.         SEG_Display(DlevState.CurrentFloor);                //數碼管顯示
  242. }
  243.         
  244. void Elevator(void)
  245. {
  246.         if((DOOR==OPEN)||(DlevState.FreeFlag==TRUE)) DlevWorkState(STOP);        
  247.   else
  248.         DlevWorkState(DlevState.Direction);        
  249.         
  250.         if(DlevState.Direction==UP)  //電梯正在向上運行的情況
  251.         {
  252.                 if(DlevState.CurrentFloor<=MaxFloor)  //掃描呼叫列表中的向上方向的呼叫樓層
  253.                 {
  254.                          if(DlevState.FloorCallTable[DlevState.CurrentFloor]==UP) //到達目標樓層,停下開門5秒
  255.                          {
  256.                                  DlevState.FloorCallTable[DlevState.CurrentFloor]=Null; //到達相應的樓層從向上列表中清除                                         
  257.                                  DlevState.FreeFlag=TRUE; //到達樓層,暫停進入空閑狀態                                 
  258.                                  DlevWorkState(STOP);
  259.                            WaitDoorOpen(DoorStayTime);
  260.                                  delay_s(2*DoorStayTime);       //保持門開2秒讓人進出
  261.                                  WaitDoorClose(DoorStayTime);
  262.                                  DlevWorkState(DlevState.Direction);
  263.                                  DlevState.FreeFlag=FALSE; //離開樓層,退出空閑狀態
  264.                                  DlevState.FloorTimerCount=0;         //計時器清0
  265.                          }                 
  266.                 }               
  267.         }
  268.         else
  269.         if(DlevState.Direction==DOWN)  //電梯正在向下運行的情況
  270.         {
  271.                 if(DlevState.CurrentFloor>=1)  //掃描呼叫列表中的向下方向的呼叫樓層
  272.                 {
  273.                          if(DlevState.FloorCallTable[DlevState.CurrentFloor]==DOWN) //到達樓層,停下開門5秒
  274.                          {        
  275.          DlevState.FloorCallTable[DlevState.CurrentFloor]=Null; //到達相應的樓層從向下列表中清除        
  276.                                  DlevState.FreeFlag=TRUE; //到達樓層,暫停進入空閑狀態                 
  277.                                  DlevWorkState(STOP);
  278.                            WaitDoorOpen(DoorStayTime);
  279.                                  delay_s(2*DoorStayTime);       //保持門開2秒讓人進出
  280.                                  WaitDoorClose(DoorStayTime);
  281.                                  DlevWorkState(DlevState.Direction);
  282.                                  DlevState.FreeFlag=FALSE; //離開樓層,退出空閑狀態
  283.                                  DlevState.FloorTimerCount=0;         //計時器清0
  284.                          }                 
  285.                 }               
  286.         }

  287. }  

  288. u8 FloorCall_UP(u8 floorside) // floorside  =  DOWN在樓下  UP在樓上
  289. {
  290.          u8 i;

  291.          if(floorside==UP)
  292.          {
  293.                  for(i=DlevState.CurrentFloor+1;i<=MaxFloor;i++) //掃描呼叫列表樓上是否有要向上的呼叫
  294.                  {
  295.                          if(DlevState.FloorCallTable[i]==UP) //如果掃描到上方樓層有向上的呼叫
  296.                          {
  297.                                  return TRUE;
  298.                          }
  299.                  }
  300.                  return FALSE;
  301.          }
  302.          else
  303.          if(floorside==DOWN)
  304.          {
  305.                  for(i=DlevState.CurrentFloor-1;i>=1;i--) //掃描呼叫列表樓下是否有要向上的呼叫
  306.                  {
  307.                          if(DlevState.FloorCallTable[i]==UP) //如果掃描到上方樓層有向上的呼叫
  308.                          {
  309.                                  return TRUE;
  310.                          }
  311.                  }
  312.                  return FALSE;
  313.          }
  314. }

  315. u8 FloorCall_DOWN(u8 floorside) // floorside  =  DOWN在樓下  UP在樓上
  316. {
  317.          u8 i;

  318.          if(floorside==UP)
  319.          {
  320.                  for(i=DlevState.CurrentFloor+1;i<=MaxFloor;i++) //掃描呼叫列表樓上是否有要向下的呼叫
  321.                  {
  322.                          if(DlevState.FloorCallTable[i]==DOWN) //如果掃描到上方樓層有向下的呼叫
  323.                          {
  324.                                  return TRUE;
  325.                          }
  326.                  }
  327.                  return FALSE;
  328.          }
  329.          else
  330.          if(floorside==DOWN)
  331.          {
  332.                  for(i=DlevState.CurrentFloor-1;i>=1;i--) //掃描呼叫列表樓下是否有要向下的呼叫
  333.                  {
  334.                          if(DlevState.FloorCallTable[i]==DOWN) //如果掃描到上方樓層有向下的呼叫
  335.                          {
  336.                                  return TRUE;
  337.                          }
  338.                  }
  339.                  return FALSE;
  340.          }
  341. }

  342. void FLOORCALLCHECK(void)
  343. {
  344.         u8 i;
  345.                
  346.         for(i=1;i<=MaxFloor;i++) //掃描呼叫列表是否空閑
  347.         {
  348.           if(DlevState.FloorCallTable[i]!=Null) //非空閑
  349.                 {
  350.                          DlevState.FreeFlag=FALSE; //退出空閑狀態
  351.                          DlevState.DlevRunning=TRUE;//正在運行標志打開
  352.        break;
  353.                 }
  354.                 else if(i==MaxFloor) DlevState.FreeFlag=TRUE; //進入空閑狀態
  355.         }
  356.         if(DlevState.CurrentFloor==1)  DlevState.Direction=UP;  //1樓調頭
  357.         else
  358.         if(DlevState.CurrentFloor==MaxFloor)  DlevState.Direction=DOWN; //頂樓調頭
  359.   if((DlevState.FreeFlag==FALSE)&&(DOOR==CLOSE)) //非空閑下
  360.         {                                
  361.      if(DlevState.Direction==UP)//方向向上
  362.                  {
  363.                     if((FloorCall_UP(UP)==TRUE)||(FloorCall_DOWN(UP)==TRUE)) //如果當前樓層上方有呼叫向上的 或 如果當前樓層上方有呼叫向下的
  364.                                 {
  365.                                   if(DlevState.FloorTimerCount>FloorStayTime) //檢測是否到達樓層  如果接收到 到達樓層的限位開關信號,則當前樓層值+1(這里用定時器來模擬)
  366.                                   {                                                               
  367.                                           DlevState.FloorTimerCount=0;         //計時器清0
  368.                                           DlevState.CurrentFloor++;//電梯繼續往上走
  369.                                   }
  370.                                 }
  371.                                 else
  372.         if((FloorCall_UP(DOWN)==TRUE)||(FloorCall_DOWN(DOWN)==TRUE)) //掃描下方是否是有呼叫
  373.                                 {
  374.                                         DlevState.Direction=DOWN; //樓層下方有呼叫則調頭
  375.                                 }
  376.                                 else DlevState.FreeFlag=TRUE; //否則進入空閑狀態
  377.                  }
  378.                  else
  379.                  if(DlevState.Direction==DOWN)//方向向下
  380.                  {
  381.                     if((FloorCall_DOWN(DOWN)==TRUE)||(FloorCall_UP(DOWN)==TRUE)) //如果當前樓層下方有呼叫向下的 或 如果當前樓層下方有呼叫向上的
  382.                                 {
  383.                                   if(DlevState.FloorTimerCount>FloorStayTime) //檢測是否到達樓層  如果接收到 到達樓層的限位開關信號,則當前樓層值+1(這里用定時器來模擬)
  384.                                   {                                                               
  385.                                           DlevState.FloorTimerCount=0;        
  386.                                           DlevState.CurrentFloor--;//電梯繼續往下走
  387.                                   }
  388.                                 }
  389.                                 else
  390.         if((FloorCall_DOWN(UP)==TRUE)||(FloorCall_UP(UP)==TRUE)) //掃描上方是否是有呼叫
  391.                                 {
  392.                                         DlevState.Direction=UP; //樓層上方有呼叫則調頭
  393.                                 }
  394.                                 else DlevState.FreeFlag=TRUE; //否則進入空閑狀態
  395.                  }
  396.         }
  397.         else
  398.         {               
  399.            DlevWorkState(STOP); //停止運行
  400.                  DlevState.DlevRunning=FALSE;//正在運行標志關閉
  401.         }
  402. }

  403. void SYSYEM_INIT(void)
  404. {
  405.          u8 i;
  406.         
  407.          DlevState.CurrentFloor=1;
  408.          DlevState.Direction=UP;              //初使化方向為向上
  409.          DlevState.FloorTimerCount=0;        
  410.          DlevState.FreeFlag=TRUE;             //初使化為空閑狀態
  411.          DlevState.DlevRunning=FALSE;
  412.          RIOver_Flag=FALSE;
  413.          RICount=0;
  414.          for(i=1;i<=MaxFloor;i++)
  415.          {
  416.                  DlevState.FloorCallTable[i]=Null; //初使化呼叫列表為Null
  417.          }
  418.          DOOR_Close;
  419. }

  420. void main(void)
  421. {
  422.         SYSYEM_INIT();
  423.         EXTI0_Init();
  424.         EXTI1_Init();
  425.         Timer0_Init();
  426.         USART_Configure(9600);
  427.   while(1)
  428.         {
  429.                  KeyPort_Y=0x00;
  430.                  FLOORCALLCHECK();
  431.            Elevator();   
  432.         }
  433. }

  434. //void EXTI0_IRQHandler(void) interrupt 0     //樓層傳感器中斷(此模擬版本用不到)
  435. //{         
  436. //         DlevState.ArriveFlag=TRUE;
  437. //}
  438. void EXTI1_IRQHandler(void) interrupt 2    //矩陣按鍵中斷
  439. {
  440.    KeyDatHandle(KeyScan());
  441. }

  442. void TIM0_IRQHandler(void)  interrupt 1    //定時模擬電梯上升和下降
  443. {
  444.    TH0=(65536-50000)/256;
  445.          TL0=(65536-50000)%256;
  446.         
  447.          TimerCount++;
  448.          if(TimerCount==20)  //1秒
  449.          {
  450.                  TimerCount=0;
  451.                  Timer_Second++;
  452.          }         
  453.          DlevState.FloorTimerCount++;
  454. }

  455. void USART_IRQHandler(void) interrupt 4  //用于電梯之間的通信
  456. {                  

  457. }

復制代碼

文件:

8層樓梯傳感器版.zip (125.29 KB, 下載次數: 110)

8層樓梯定時模擬版.zip (125.33 KB, 下載次數: 87)

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

使用道具 舉報

沙發
ID:142059 發表于 2020-2-2 00:44 來自手機 | 只看該作者
光明正大盜????
回復

使用道具 舉報

板凳
ID:734885 發表于 2020-4-22 04:15 | 只看該作者
確實不錯。
回復

使用道具 舉報

地板
ID:734207 發表于 2020-4-22 19:06 來自手機 | 只看該作者
我覺得你這個思路很好
回復

使用道具 舉報

5#
ID:302325 發表于 2020-5-26 14:21 | 只看該作者
感謝分享  很不錯的設計               
回復

使用道具 舉報

6#
ID:902730 發表于 2021-4-21 21:37 來自手機 | 只看該作者
第二個仿真有點問題
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品三级 | 国产情侣一区 | 亚洲精品视频导航 | 欧美一区二区三区免费电影 | 一区二区三区在线免费观看 | 久色网 | 一级黄色裸片 | 日韩一二三区 | 黄色在线免费网站 | 国产精品伦一区二区三级视频 | 欧美日韩国产在线 | 91影院 | 午夜视频免费在线观看 | 国产亚洲一区精品 | 狠狠av| 欧美一区二区免费 | 欧美激情黄色 | 91免费在线看 | 91精品麻豆日日躁夜夜躁 | 国产视频91在线 | 国产福利精品一区 | 亚洲在线免费观看 | 国产在线播 | av毛片 | 国产成人免费视频网站视频社区 | 黄色片免费看视频 | 成人污污视频 | 日本三级黄视频 | 免费一区| 国内精品视频一区二区三区 | 国产精品一区二区在线 | 国产精品久久久久一区二区三区 | 女人毛片a毛片久久人人 | 免费视频久久久久 | 91久久夜色 | av乱码| 日本欧美大片 | 亚av在线| 一级黄色影片在线观看 | 国产91久久久久久 | 精品国产一区二区国模嫣然 |