找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 4911|回復(fù): 8
收起左側(cè)

單片機(jī)電梯仿真控制源程序與Proteus仿真

  [復(fù)制鏈接]
ID:813428 發(fā)表于 2020-9-23 13:18 | 顯示全部樓層 |閱讀模式
1.圖中綠燈為電梯上行指示燈、黃燈為下行指示燈、紅燈為報(bào)警指示燈。2.電梯初始狀態(tài)位于一樓,在一樓的用戶可直接按下電梯內(nèi)部按鈕,按啟動(dòng)電梯開始運(yùn)行。3.在任一層樓的用戶,可以通過(guò)電梯外部的按鈕請(qǐng)求電梯,電梯到達(dá)后通過(guò)內(nèi)部按鈕確定目標(biāo)層。注意:?jiǎn)?dòng)按鈕相當(dāng)于關(guān)門,電梯內(nèi)部的請(qǐng)求都要按啟動(dòng)后電梯才會(huì)運(yùn)行。

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png 51hei.png

單片機(jī)源程序如下:
  1. #include <REG52.H>
  2. #include <INTRINS.H>

  3. unsigned char ucMotorDrvPuls; //電機(jī)運(yùn)轉(zhuǎn)時(shí)初始值
  4. unsigned char FORREV=1; //1表示上行,0表示下行
  5. unsigned char STOPCUR=0;//1電梯停留在當(dāng)前層,0不停留
  6. unsigned char CURFLR=1; //當(dāng)前所在樓層
  7. unsigned char count=0;  //累計(jì)到COUNT即表示運(yùn)行過(guò)一層

  8. #define UCTIMES 8 //設(shè)置電機(jī)轉(zhuǎn)速
  9. #define OUTPUT P2 //電機(jī)驅(qū)動(dòng)信號(hào)口
  10. #define COUNT 8   //電機(jī)每循環(huán)8次表示電梯經(jīng)過(guò)一層樓

  11. sbit UP1=P3^4;
  12. sbit DOWN2=P3^3;
  13. sbit UP2=P3^2;
  14. sbit DOWN3=P3^1;
  15. sbit UP3=P3^0;
  16. sbit DOWN4=P1^7;
  17. sbit FLOOR1=P1^0;
  18. sbit FLOOR2=P1^1;
  19. sbit FLOOR3=P1^2;
  20. sbit FLOOR4=P1^3;
  21. sbit START=P1^4;
  22. sbit STOP=P1^5;
  23. sbit ALARM=P1^6;

  24. //報(bào)警位
  25. sbit alarmBit=P0^4;
  26. sbit upLight=P0^5;
  27. sbit downLight=P0^6;

  28. void time(unsigned int ucMs);//延時(shí)單位:ms
  29. void outPress();//按下電梯外按鈕
  30. unsigned char inPress();//按下電梯內(nèi)樓層按鈕
  31. unsigned char elevator();//到達(dá)某一層返回1,否則返回0
  32. void storeUP(unsigned char);//存儲(chǔ)當(dāng)前所有上行請(qǐng)求
  33. void storeDOWN(unsigned char);//存儲(chǔ)當(dāng)前所有下行請(qǐng)求

  34. //延時(shí)函數(shù)
  35. void time(unsigned int ucMs);

  36. //初始化所有燈
  37. void initLights(void);

  38. //設(shè)置當(dāng)前樓層
  39. void setFloor(int floor);

  40. //設(shè)置電梯向上運(yùn)行燈
  41. void setUpLight();

  42. //設(shè)置電梯向下運(yùn)行燈
  43. void setDownLight();

  44. //設(shè)置電梯停止運(yùn)行燈
  45. void setStopLight();

  46. //設(shè)置電梯向上運(yùn)行燈
  47. void setAlarmLight();

  48. //設(shè)置電梯報(bào)警燈和喇叭
  49. void setAlarmLight();

  50. //關(guān)閉電梯報(bào)警燈和喇叭
  51. void offAlarmLight();


  52. //報(bào)警開關(guān)
  53. int alarmSwitch=1;

  54. unsigned char UP_req[5]={0,0,0,0,0}; //上行請(qǐng)求
  55. unsigned char DOWN_req[5]={0,0,0,0,0}; //下行請(qǐng)求

  56. //電機(jī)定位
  57. void position(void)
  58. {
  59.   OUTPUT=0x01|(P2&0xf0);time(200);
  60.   OUTPUT=0x02|(P2&0xf0);time(200);
  61.   OUTPUT=0x04|(P2&0xf0);time(200);
  62.   OUTPUT=0x08|(P2&0xf0);time(200);
  63.   ucMotorDrvPuls=0x11;
  64.   OUTPUT=0x01|(P2&0xf0);       
  65.   
  66. }

  67. /****************************************/
  68. /*                 主函數(shù)               */
  69. /****************************************/
  70. void main(void)
  71. {
  72.   time(100);
  73.   initLights();
  74.   position();//電機(jī)定位
  75.   ucMotorDrvPuls=0x11;
  76.   OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
  77.   setFloor(CURFLR);
  78.   setUpLight();
  79.   time(100);
  80.   
  81.   while(1)//主循環(huán)
  82.   {
  83.           outPress();//按下電梯外按鈕
  84.           while(STOPCUR==1)//電梯在當(dāng)前層,電梯不動(dòng),可以繼續(xù)接受請(qǐng)求
  85.           {
  86.             outPress();
  87.             inPress();
  88.           }  

  89.           if(inPress())//按下電梯內(nèi)樓層按鈕
  90.           {
  91.             while(START)//等待啟動(dòng)按鍵按下,電梯不動(dòng),可以繼續(xù)接受請(qǐng)求
  92.             {
  93.               outPress();
  94.               inPress();
  95.             }
  96.           }

  97.           while(1)//電機(jī)運(yùn)轉(zhuǎn)循環(huán)
  98.           {
  99.             if(UP_req[1]==0&&UP_req[2]==0&&UP_req[3]==0&&
  100.                 DOWN_req[2]==0&&DOWN_req[3]==0&&DOWN_req[4]==0)
  101.                 {
  102.                   break;//沒(méi)有請(qǐng)求,跳出電機(jī)運(yùn)轉(zhuǎn)循環(huán),電梯不動(dòng)
  103.                 }
  104.                   
  105.             if(FORREV)//上行
  106.             {
  107.                   setUpLight();//上行燈亮

  108.                   if(STOPCUR==1){break;}//

  109.                   if(elevator())//往上到達(dá)某一層
  110.               {
  111.                         if(CURFLR==4) {setDownLight();break;}//到達(dá)四樓
  112.               }
  113.               OUTPUT=(ucMotorDrvPuls&0x0f)|(P2&0xf0);
  114.                   ucMotorDrvPuls=_crol_(ucMotorDrvPuls,1);
  115.             }
  116.             if(!FORREV)//下行
  117.             {
  118.                   setDownLight();//下行燈亮
  119. ;
  120.                   if(STOPCUR==1){break;}

  121.                   if(elevator())//往下到達(dá)某一層
  122.               {
  123.                         if(CURFLR==1) {setUpLight();break;}//到達(dá)一樓
  124.               }
  125.               OUTPUT=(ucMotorDrvPuls&0x0f)|(P2&0xf0);
  126.                   ucMotorDrvPuls=_cror_(ucMotorDrvPuls,1);
  127.             }       
  128.        
  129.             outPress();//按下電梯外按鈕
  130.             //if(inPress())//按下電梯內(nèi)樓層按鈕
  131.                 //{
  132.                  // while(START)//等待啟動(dòng)按鍵按下
  133.                   //{
  134.               //  outPress();
  135.                 inPress();//電梯運(yùn)行時(shí),內(nèi)部按鈕按下,無(wú)需按啟動(dòng)按鈕
  136.              // }
  137.                 //}

  138.             time(380-UCTIMES*16);

  139.           }//end while-電機(jī)運(yùn)轉(zhuǎn)循環(huán)
  140.        
  141.         OUTPUT=0x00|(P2&0xf0);//電機(jī)停止,有請(qǐng)求時(shí)按下啟動(dòng)按鈕啟動(dòng)

  142.   }//end while-主循環(huán)   
  143. }

  144. /****************************************/
  145. /*               按鈕事件               */
  146. /****************************************/
  147. //按下電梯外按鈕
  148. void outPress()
  149. {
  150.    //FORREV=1;
  151.    if(!UP1)//1樓上
  152.    {
  153.      storeUP(1);
  154.          if(CURFLR>1&&STOPCUR==1)//電梯不在一樓,且當(dāng)前沒(méi)其他請(qǐng)求,電梯馬上自動(dòng)啟動(dòng)
  155.          {
  156.            FORREV=0;//向下運(yùn)行
  157.            STOPCUR=0;
  158.          }
  159.          if(CURFLR==1)
  160.          {
  161.            STOPCUR=1;//電梯停留在當(dāng)前層
  162.          }
  163.    }
  164.    if(!UP2)//2樓上
  165.    {
  166.      storeUP(2);
  167.          if(CURFLR>2&&STOPCUR==1)//電梯在二樓以上
  168.          {
  169.            FORREV=0;
  170.            STOPCUR=0;
  171.          }
  172.          if(CURFLR<2&&STOPCUR==1)
  173.          {
  174.            FORREV=1;
  175.            STOPCUR=0;
  176.          }
  177.          if(CURFLR==2)
  178.          {
  179.            STOPCUR=1;
  180.          }
  181.    }
  182.    if(!UP3)//3樓上
  183.    {
  184.      storeUP(3);
  185.          if(CURFLR>3&&STOPCUR==1)//電梯在三樓以上
  186.          {
  187.            FORREV=0;
  188.            STOPCUR=0;
  189.          }
  190.          if(CURFLR<3&&STOPCUR==1)
  191.          {
  192.            FORREV=1;
  193.            STOPCUR=0;
  194.          }
  195.          if(CURFLR==3)
  196.          {
  197.            STOPCUR=1;
  198.          }
  199.    }
  200.    if(!DOWN2)//2樓下
  201.    {
  202.      storeDOWN(2);
  203.          if(CURFLR>2&&STOPCUR==1)//電梯在二樓以上
  204.          {
  205.            FORREV=0;
  206.            STOPCUR=0;
  207.          }
  208.          if(CURFLR<2&&STOPCUR==1)
  209.          {
  210.            FORREV=1;
  211.            STOPCUR=0;
  212.          }
  213.          if(CURFLR==2)
  214.          {
  215.            STOPCUR=1;
  216.          }
  217.    }
  218.    if(!DOWN3)//3樓下
  219.    {
  220.      storeDOWN(3);
  221.          if(CURFLR>3&&STOPCUR==1)//電梯在三樓以上
  222.          {
  223.            FORREV=0;
  224.            STOPCUR=0;
  225.          }
  226.          if(CURFLR<3&&STOPCUR==1)
  227.          {
  228.            FORREV=1;
  229.            STOPCUR=0;
  230.          }
  231.          if(CURFLR==3)
  232.          {
  233.            STOPCUR=1;
  234.          }
  235.    }
  236.    if(!DOWN4)//4樓下
  237.    {
  238.      storeDOWN(4);
  239.          if(CURFLR<4&&STOPCUR==1)
  240.          {
  241.            FORREV=1;
  242.            STOPCUR=0;
  243.          }
  244.          if(CURFLR==4)
  245.          {
  246.            STOPCUR=1;
  247.          }
  248.    }
  249. }

  250. //按下電梯內(nèi)樓層按鈕
  251. unsigned char inPress()
  252. {
  253.   
  254.   int i;
  255.   int flag=0;

  256.   if(!FLOOR1)
  257.   {       
  258.     if(1<CURFLR)
  259.         {
  260.           STOPCUR=0;
  261.           UP_req[1]=1;
  262.         }
  263.         if(1==CURFLR)
  264.         {
  265.           STOPCUR=1;
  266.         }
  267.         return 1;
  268.   }
  269.   if(!FLOOR2)
  270.   {
  271.     if(2>CURFLR)//請(qǐng)求層大于當(dāng)前層
  272.         {
  273.           UP_req[2]=1;
  274.           STOPCUR=0;
  275.         }
  276.         if(2<CURFLR)
  277.         {
  278.           DOWN_req[2]=1;
  279.           STOPCUR=0;
  280.         }
  281.         if(2==CURFLR)
  282.         {
  283.           STOPCUR=1;
  284.         }
  285.         return 1;
  286.        
  287.   }
  288.   if(!FLOOR3)
  289.   {
  290.     if(3>CURFLR)//請(qǐng)求層大于當(dāng)前層
  291.         {
  292.           UP_req[3]=1;
  293.           STOPCUR=0;
  294.         }
  295.         if(3<CURFLR)
  296.         {
  297.           DOWN_req[3]=1;
  298.           STOPCUR=0;
  299.         }
  300.         if(3==CURFLR)
  301.         {
  302.           STOPCUR=1;
  303.         }
  304.         return 1;
  305.   }

  306.   if(!FLOOR4)
  307.   {
  308.     if(4>CURFLR)
  309.         {
  310.       DOWN_req[4]=1;
  311.           STOPCUR=0;
  312.         }
  313.         if(4==CURFLR)
  314.         {
  315.           STOPCUR=1;
  316.         }
  317.         return 1;
  318.   }
  319.   if(!START)
  320.   {
  321.     STOPCUR=0;
  322.         return 1;
  323.   }
  324.   if(!STOP)//緊急停止
  325.   {
  326.     while(START)//不響應(yīng)其他按鍵
  327.         {
  328.           //亮燈
  329.           setStopLight();
  330.         }
  331.         return 1;
  332.   }
  333.   if(!ALARM)
  334.   {
  335.           setAlarmLight();
  336.         return 1;
  337.   }

  338.    if(FORREV==1)
  339.    {
  340.       //請(qǐng)求上行而進(jìn)去電梯內(nèi)選擇的是下層
  341.           for(i=CURFLR+1;i<=4;i++)
  342.           {
  343.             if(UP_req[i]==1||DOWN_req[i]==1){flag=1;}
  344.           }
  345.           if(flag==0)//上層沒(méi)請(qǐng)求
  346.           {
  347.             FORREV=0;
  348.                
  349.           }
  350.         }
  351.         if(FORREV==0)
  352.         {
  353.            //請(qǐng)求下行而進(jìn)去電梯內(nèi)選擇的是上層
  354.           for(i=CURFLR-1;i>=1;i--)
  355.           {
  356.             if(UP_req[i]==1||DOWN_req[i]==1){flag=1;}
  357.           }
  358.           if(flag==0)//上層沒(méi)請(qǐng)求
  359.           {
  360.             FORREV=1;
  361.                
  362.           }
  363.         }
  364.   return 0;
  365. }

  366. /*******************************************************************/
  367. /*                       到達(dá)某一層返回1,否則返回0,                           */
  368. /*    亮燈、顯示數(shù)字、請(qǐng)求清零、電機(jī)停止、確定接下去電機(jī)方向       */
  369. /*******************************************************************/
  370. unsigned char elevator()
  371. {
  372.   count++;
  373.   if(count==COUNT)
  374.   {
  375.         //正常情況
  376.     if(FORREV==1)//判斷上行是否到達(dá)請(qǐng)求樓層,上行請(qǐng)求優(yōu)先處理
  377.         {
  378.           CURFLR++;
  379.           setUpLight();//上行燈亮

  380.           

  381.           if(CURFLR==2)//到達(dá)二樓
  382.           {
  383.             count=0;       
  384.             setFloor(2);//顯示數(shù)字
  385.             if(UP_req[2]==1)//二樓有上行請(qǐng)求,優(yōu)先處理
  386.             {               
  387.                   setUpLight();
  388.               UP_req[2]=0;
  389.                   OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
  390.                   STOPCUR=1;
  391.                   return 1;
  392.             }
  393.                 if(DOWN_req[2]==1&&UP_req[3]==0&&DOWN_req[3]==0
  394.                 &&DOWN_req[4]==0)//二樓有下行請(qǐng)求,上面兩層沒(méi)有請(qǐng)求,不再往上
  395.                 {                  
  396.                    setDownLight();
  397.                    DOWN_req[2]=0;
  398.                    STOPCUR=1;
  399.                    OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
  400.                    FORREV=0;
  401.                    return 1;
  402.                 }
  403.           }
  404.           if(CURFLR==3)//到達(dá)三樓
  405.           {       
  406.             setFloor(3);//顯示數(shù)字
  407.                 count=0;
  408.             if(UP_req[3]==1)//三樓有上行請(qǐng)求,優(yōu)先處理
  409.             {
  410.                   setUpLight();
  411.               UP_req[3]=0;
  412.                   OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
  413.                   STOPCUR=1;
  414.                   return 1;
  415.             }
  416.                 if(DOWN_req[3]==1&&DOWN_req[4]==0)//三樓有下行請(qǐng)求,四樓無(wú)請(qǐng)求,不再往上
  417.                 {
  418.                   setDownLight();
  419.                   FORREV=0;
  420.                   DOWN_req[3]=0;
  421.                   STOPCUR=1;
  422.                   OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
  423.                   return 1;
  424.                 }
  425.           }
  426.           if(CURFLR==4)//到達(dá)四樓
  427.           {       
  428.             setFloor(4);//顯示數(shù)字
  429.                 setDownLight();
  430.                 count=0;
  431.             if(DOWN_req[4]==1)//四樓有請(qǐng)求,四樓的請(qǐng)求只用向下的情況
  432.             {
  433.               DOWN_req[4]=0;
  434.                   FORREV=0;
  435.                   OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
  436.                   STOPCUR=1;
  437.             }
  438.           }
  439.         }
  440.         else//判斷下行是否到達(dá)請(qǐng)求層,下行請(qǐng)求優(yōu)先處理
  441.         {
  442.           CURFLR--;
  443.           setDownLight();//下行等亮

  444.          

  445.           if(CURFLR==1)//到達(dá)一樓
  446.           {       
  447.             setFloor(1);//顯示數(shù)字
  448.                 count=0;
  449.             if(UP_req[1]==1)//一樓有請(qǐng)求,一樓的請(qǐng)求只有向上的情況
  450.             {
  451.                   setUpLight();
  452.               UP_req[1]=0;
  453.                   FORREV=1;
  454.               OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
  455.                   STOPCUR=1;
  456.             }
  457.           }
  458.           if(CURFLR==2)//到達(dá)二樓
  459.           {       
  460.             setFloor(2);//顯示數(shù)字
  461.                 count=0;
  462.             if(DOWN_req[2]==1)//二樓有下行請(qǐng)求,優(yōu)先處理
  463.             {
  464.                   setDownLight();
  465.               DOWN_req[2]=0;
  466.                   OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
  467.                   STOPCUR=1;
  468.                   return 1;
  469.             }
  470.                 if(UP_req[2]==1&&UP_req[1]==0)//一樓無(wú)請(qǐng)求,不再往下
  471.                 {
  472.                   setUpLight();
  473.                   FORREV=1;
  474.                   UP_req[2]=0;
  475.                   STOPCUR=1;
  476.                   OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
  477.                 }
  478.           }
  479.           if(CURFLR==3)//到達(dá)三樓
  480.           {       
  481.             setFloor(3);//顯示數(shù)字
  482.                 count=0;
  483.             if(DOWN_req[3]==1)//三樓有下行請(qǐng)求,優(yōu)先處理
  484.             {
  485.                   setDownLight();
  486.               DOWN_req[3]=0;
  487.                   OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
  488.                   STOPCUR=1;
  489.                   return 1;
  490.             }
  491.                 if(UP_req[1]==0&&DOWN_req[2]==0&&UP_req[2]==0&&UP_req[3]==1)
  492.                 {
  493.                   setUpLight();
  494.                   FORREV=1;
  495.                   UP_req[3]=0;
  496.                   STOPCUR=1;
  497.                   OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
  498.                 }
  499.           }
  500.         }//end if-FORREV

  501.     return 1;
  502.   }
  503.   else
  504.   {
  505.     return 0;
  506.   }//end if-count
  507. }

  508. /****************************************/
  509. /*               保存請(qǐng)求               */
  510. /****************************************/
  511. void storeUP(unsigned char x)
  512. {
  513.   UP_req[x]=1;
  514. }
  515. void storeDOWN(unsigned char x)
  516. {
  517.   DOWN_req[x]=1;
  518. }

  519. /****************************************/
  520. /*               功能函數(shù)               */
  521. /****************************************/
  522. //初始化所有燈
  523. void initLights()
  524. {
  525.         P0=0x11;
  526. }

  527. //設(shè)置樓層顯示
  528. void setFloor(int floor)
  529. {
  530.         switch (floor)
  531.         {
  532.                 case 1:
  533.                 {       
  534.                         P0&=0xf0;//清零
  535.                         P0|=0x01;break;
  536.                 }
  537.                 case 2:
  538.                 {
  539.                         P0&=0xf0;//清零
  540.                         P0|=0x02;break;
  541.                 }
  542.                 case 3:
  543.                 {
  544.                         P0&=0xf0;//清零
  545.                         P0|=0x03;break;
  546.                 }
  547.                 case 4:
  548.                 {
  549.                         P0&=0xf0;//清零
  550.                         P0|=0x04;break;
  551.                 }
  552.                 default:
  553.                 {
  554.                         P0=0x06;break;
  555.                 }
  556.         }
  557. }

  558. //設(shè)置電梯向上運(yùn)行燈
  559. void setUpLight()
  560. {
  561.         upLight=1;
  562.         downLight=0;
  563. }

  564. //設(shè)置電梯向下運(yùn)行燈
  565. ……………………

  566. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
51hei.png
所有資料51hei提供下載:
SJ 001 電梯控制系統(tǒng).rar (537.43 KB, 下載次數(shù): 219)


評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:337139 發(fā)表于 2020-9-23 19:47 | 顯示全部樓層
很棒的,在上下樓的選擇上還可以優(yōu)化。
回復(fù)

使用道具 舉報(bào)

ID:337139 發(fā)表于 2020-9-23 19:56 | 顯示全部樓層

RE: 單片機(jī)電梯仿真控制源程序與Proteus仿真

各樓層模擬圖

各樓層模擬圖

回復(fù)

使用道具 舉報(bào)

ID:301242 發(fā)表于 2021-5-21 11:31 | 顯示全部樓層
請(qǐng)問(wèn)大神再加兩層應(yīng)該注意什么
回復(fù)

使用道具 舉報(bào)

ID:999778 發(fā)表于 2022-1-6 17:17 | 顯示全部樓層
5層的時(shí)候只有一個(gè)下降鍵,那你在4層時(shí)如何上去?
回復(fù)

使用道具 舉報(bào)

ID:709612 發(fā)表于 2022-2-18 17:17 | 顯示全部樓層
強(qiáng),代碼可讀性也很高,protues版圖也很漂亮整潔
回復(fù)

使用道具 舉報(bào)

ID:278457 發(fā)表于 2022-5-4 03:51 | 顯示全部樓層
代碼可以用模塊化,這樣程序會(huì)易懂,思路會(huì)更清晰.
回復(fù)

使用道具 舉報(bào)

ID:6540 發(fā)表于 2024-10-15 10:48 | 顯示全部樓層
強(qiáng),代碼可讀性也很高,protues版圖也很漂亮整潔
回復(fù)

使用道具 舉報(bào)

ID:1130471 發(fā)表于 2024-10-21 11:58 | 顯示全部樓層
強(qiáng),代碼可讀性也很高,protues版圖也很漂亮整潔
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表