找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5528|回复: 3
收起左侧

单片机控制4层电梯Proteus仿真电路+代码示例

[复制链接]
ID:420073 发表于 2018-11-3 12:16 | 显示全部楼层 |阅读模式
基于51单片机的4层电梯控制系统仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png

带电梯内部状态显示单元,电梯内部键盘操作单元,电梯外部操作单元,步进电机单元,CPU、日历时钟单元

操作说明:

1.图中绿灯为电梯上行指示灯、黄灯为下行指示灯、红灯为报警指示灯。

2.电梯初始状态位于一楼,在一楼的用户可直接按下电梯内部按钮,按启动电梯开始运行。

3.在任一层楼的用户,可以通过电梯外部的按钮请求电梯,电梯到达后通过内部按钮确定目标层。

注意:启动按钮相当于关门,电梯内部的请求都要按启动后电梯才会运行。

0.png

程序源码详见:
  1. #include <REG52.H>
  2. #include <INTRINS.H>

  3. unsigned char ucMotorDrvPuls; //电机运转时初始值
  4. unsigned char FORREV=1; //1表示上行,0表示下行
  5. unsigned char STOPCUR=0;//1电梯停留在当前层,0不停留
  6. unsigned char CURFLR=1; //当前所在楼层
  7. unsigned char count=0;  //累计到COUNT即表示运行过一层

  8. #define UCTIMES 8 //设置电机转速
  9. #define OUTPUT P2 //电机驱动信号口
  10. #define COUNT 8   //电机每循环8次表示电梯经过一层楼

  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. //报警位
  25. sbit alarmBit=P0^4;
  26. sbit upLight=P0^5;
  27. sbit downLight=P0^6;

  28. void time(unsigned int ucMs);//延时单位:ms
  29. void outPress();//按下电梯外按钮
  30. unsigned char inPress();//按下电梯内楼层按钮
  31. unsigned char elevator();//到达某一层返回1,否则返回0
  32. void storeUP(unsigned char);//存储当前所有上行请求
  33. void storeDOWN(unsigned char);//存储当前所有下行请求

  34. //延时函数
  35. void time(unsigned int ucMs);

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

  38. //设置当前楼层
  39. void setFloor(int floor);

  40. //设置电梯向上运行灯
  41. void setUpLight();

  42. //设置电梯向下运行灯
  43. void setDownLight();

  44. //设置电梯停止运行灯
  45. void setStopLight();

  46. //设置电梯向上运行灯
  47. void setAlarmLight();

  48. //设置电梯报警灯和喇叭
  49. void setAlarmLight();

  50. //关闭电梯报警灯和喇叭
  51. void offAlarmLight();


  52. //报警开关
  53. int alarmSwitch=1;

  54. unsigned char UP_req[5]={0,0,0,0,0}; //上行请求
  55. unsigned char DOWN_req[5]={0,0,0,0,0}; //下行请求

  56. //电机定位
  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. /*                 主函数               */
  69. /****************************************/
  70. void main(void)
  71. {
  72.   time(100);
  73.   initLights();
  74.   position();//电机定位
  75.   ucMotorDrvPuls=0x11;
  76.   OUTPUT=0x00|(P2&0xf0);//电机停止
  77.   setFloor(CURFLR);
  78.   setUpLight();
  79.   time(100);
  80.   
  81.   while(1)//主循环
  82.   {
  83.           outPress();//按下电梯外按钮
  84.           while(STOPCUR==1)//电梯在当前层,电梯不动,可以继续接受请求
  85.           {
  86.             outPress();
  87.             inPress();
  88.           }  

  89.           if(inPress())//按下电梯内楼层按钮
  90.           {
  91.             while(START)//等待启动按键按下,电梯不动,可以继续接受请求
  92.             {
  93.               outPress();
  94.               inPress();
  95.             }
  96.           }

  97.           while(1)//电机运转循环
  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;//没有请求,跳出电机运转循环,电梯不动
  103.                 }
  104.                   
  105.             if(FORREV)//上行
  106.             {
  107.                   setUpLight();//上行灯亮

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

  109.                   if(elevator())//往上到达某一层
  110.               {
  111.                         if(CURFLR==4) {setDownLight();break;}//到达四楼
  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())//往下到达某一层
  122.               {
  123.                         if(CURFLR==1) {setUpLight();break;}//到达一楼
  124.               }
  125.               OUTPUT=(ucMotorDrvPuls&0x0f)|(P2&0xf0);
  126.                   ucMotorDrvPuls=_cror_(ucMotorDrvPuls,1);
  127.             }      
  128.       
  129.             outPress();//按下电梯外按钮
  130.             //if(inPress())//按下电梯内楼层按钮
  131.                 //{
  132.                  // while(START)//等待启动按键按下
  133.                   //{
  134.               //  outPress();
  135.                 inPress();//电梯运行时,内部按钮按下,无需按启动按钮
  136.              // }
  137.                 //}

  138.             time(380-UCTIMES*16);  //////////

  139.           }//end while-电机运转循环
  140.       
  141.         OUTPUT=0x00|(P2&0xf0);//电机停止,有请求时按下启动按钮启动

  142.   }//end while-主循环
  143.    
  144. }

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

  251. //按下电梯内楼层按钮
  252. unsigned char inPress()
  253. {
  254.   
  255.   int i;
  256.   int flag=0;

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

  307.   if(!FLOOR4)
  308.   {
  309.     if(4>CURFLR)
  310.         {
  311.       DOWN_req[4]=1;
  312.           STOPCUR=0;
  313.         }
  314.         if(4==CURFLR)
  315.         {
  316.           STOPCUR=1;
  317.         }
  318.         return 1;
  319.   }
  320.   if(!START)
  321.   {
  322.     STOPCUR=0;
  323.         return 1;
  324.   }
  325.   if(!STOP)//紧急停止
  326.   {
  327.     while(START)//不响应其他按键
  328.         {
  329.           //亮灯
  330.           setStopLight();
  331.         }
  332.         return 1;
  333.   }
  334.   if(!ALARM)
  335.   {
  336.     //while(START)
  337.         //{
  338.           //亮灯
  339.           setAlarmLight();
  340.           //time(800);
  341.           //灭灯
  342.           //offAlarmLight();
  343.         //}
  344.         return 1;
  345.   }

  346.    if(FORREV==1)
  347.    {
  348.       //请求上行而进去电梯内选择的是下层
  349.           for(i=CURFLR+1;i<=4;i++)
  350.           {
  351.             if(UP_req[i]==1||DOWN_req[i]==1){flag=1;}
  352.           }
  353.           if(flag==0)//上层没请求
  354.           {
  355.             FORREV=0;
  356.                
  357.           }
  358.         }
  359.         if(FORREV==0)
  360.         {
  361.            //请求下行而进去电梯内选择的是上层
  362.           for(i=CURFLR-1;i>=1;i--)
  363.           {
  364.             if(UP_req[i]==1||DOWN_req[i]==1){flag=1;}
  365.           }
  366.           if(flag==0)//上层没请求
  367.           {
  368.             FORREV=1;
  369.                
  370.           }
  371.         }
  372.   return 0;
  373. }

  374. /*******************************************************************/
  375. /*                       到达某一层返回1,否则返回0,                           */
  376. /*    亮灯、显示数字、请求清零、电机停止、确定接下去电机方向       */
  377. /*******************************************************************/
  378. unsigned char elevator()
  379. {
  380.   count++;
  381.   if(count==COUNT)
  382.   {
  383.         //正常情况
  384.     if(FORREV==1)//判断上行是否到达请求楼层,上行请求优先处理
  385.         {
  386.           CURFLR++;
  387.           setUpLight();//上行灯亮

  388.          

  389.           if(CURFLR==2)//到达二楼
  390.           {
  391.             count=0;      
  392.             setFloor(2);//显示数字
  393.             if(UP_req[2]==1)//二楼有上行请求,优先处理
  394.             {               
  395.                   setUpLight();
  396.               UP_req[2]=0;
  397.                   OUTPUT=0x00|(P2&0xf0);//电机停止
  398.                   STOPCUR=1;
  399.                   return 1;
  400.             }
  401.                 if(DOWN_req[2]==1&&UP_req[3]==0&&DOWN_req[3]==0
  402.                 &&DOWN_req[4]==0)//二楼有下行请求,上面两层没有请求,不再往上
  403.                 {                  
  404.                    setDownLight();
  405.                    DOWN_req[2]=0;
  406.                    STOPCUR=1;
  407.                    OUTPUT=0x00|(P2&0xf0);//电机停止
  408.                    FORREV=0;
  409.                    return 1;
  410.                 }
  411.           }
  412.           if(CURFLR==3)//到达三楼
  413.           {      
  414.             setFloor(3);//显示数字
  415.                 count=0;
  416.             if(UP_req[3]==1)//三楼有上行请求,优先处理
  417.             {
  418.                   setUpLight();
  419.               UP_req[3]=0;
  420.                   OUTPUT=0x00|(P2&0xf0);//电机停止
  421.                   STOPCUR=1;
  422.                   return 1;
  423.             }
  424.                 if(DOWN_req[3]==1&&DOWN_req[4]==0)//三楼有下行请求,四楼无请求,不再往上
  425.                 {
  426.                   setDownLight();
  427.                   FORREV=0;
  428.                   DOWN_req[3]=0;
  429.                   STOPCUR=1;
  430.                   OUTPUT=0x00|(P2&0xf0);//电机停止
  431.                   return 1;
  432.                 }
  433.           }
  434.           if(CURFLR==4)//到达四楼
  435.           {      
  436.             setFloor(4);//显示数字
  437.                 setDownLight();
  438.                 count=0;
  439.             if(DOWN_req[4]==1)//四楼有请求,四楼的请求只用向下的情况
  440.             {
  441.               DOWN_req[4]=0;
  442.                   FORREV=0;
  443.                   OUTPUT=0x00|(P2&0xf0);//电机停止
  444.                   STOPCUR=1;
  445.             }
  446.           }
  447.         }
  448.         else//判断下行是否到达请求层,下行请求优先处理
  449.         {
  450.           CURFLR--;
  451.           setDownLight();//下行等亮

  452.          

  453.           if(CURFLR==1)//到达一楼
  454.           {      
  455.             setFloor(1);//显示数字
  456.                 count=0;
  457.             if(UP_req[1]==1)//一楼有请求,一楼的请求只有向上的情况
  458.             {
  459.                   setUpLight();
  460.               UP_req[1]=0;
  461.                   FORREV=1;
  462.               OUTPUT=0x00|(P2&0xf0);//电机停止
  463.                   STOPCUR=1;
  464.             }
  465.           }
  466.           if(CURFLR==2)//到达二楼
  467.           {      
  468.             setFloor(2);//显示数字
  469.                 count=0;
  470.             if(DOWN_req[2]==1)//二楼有下行请求,优先处理
  471.             {
  472.                   setDownLight();
  473.               DOWN_req[2]=0;
  474.                   OUTPUT=0x00|(P2&0xf0);//电机停止
  475.                   STOPCUR=1;
  476.                   return 1;
  477.             }
  478.                 if(UP_req[2]==1&&UP_req[1]==0)//一楼无请求,不再往下
  479.                 {
  480.                   setUpLight();
  481.                   FORREV=1;
  482.                   UP_req[2]=0;
  483.                   STOPCUR=1;
  484.                   OUTPUT=0x00|(P2&0xf0);//电机停止
  485.                 }
  486.           }
  487.           if(CURFLR==3)//到达三楼
  488.           {      
  489.             setFloor(3);//显示数字
  490.                 count=0;
  491.             if(DOWN_req[3]==1)//三楼有下行请求,优先处理
  492.             {
  493.                   setDownLight();
  494.               DOWN_req[3]=0;
  495.                   OUTPUT=0x00|(P2&0xf0);//电机停止
  496.                   STOPCUR=1;
  497.                   return 1;
  498.             }
  499.                 if(UP_req[1]==0&&DOWN_req[2]==0&&UP_req[2]==0&&UP_req[3]==1)
  500.                 {
  501.                   setUpLight();
  502.                   FORREV=1;
  503.                   UP_req[3]=0;
  504.                   STOPCUR=1;
  505.                   OUTPUT=0x00|(P2&0xf0);//电机停止
  506.                 }
  507.           }
  508.         }//end if-FORREV

  509.     return 1;
  510.   }
  511.   else
  512.   {
  513.     return 0;
  514.   }//end if-count
  515. }

  516. /****************************************/
  517. /*               保存请求               */
  518. /****************************************/
  519. void storeUP(unsigned char x)
  520. {
  521.   UP_req[x]=1;
  522. }
  523. void storeDOWN(unsigned char x)
  524. {
  525.   DOWN_req[x]=1;
  526. }

  527. /****************************************/
  528. /*               功能函数               */
  529. /****************************************/
  530. //初始化所有灯
  531. void initLights()
  532. {
  533.         P0=0x11;
  534. }

  535. //设置楼层显示
  536. void setFloor(int floor)
  537. {
  538.         switch (floor)
  539.         {
  540.                 case 1:
  541.                 {      
  542.                         P0&=0xf0;//清零
  543.                         P0|=0x01;break;
  544.                 }
  545.                 case 2:
  546.                 {
  547.                         P0&=0xf0;//清零
  548.                         P0|=0x02;break;
  549.                 }
  550.                 case 3:
  551.                 {
  552.                         P0&=0xf0;//清零
  553.                         P0|=0x03;break;
  554.                 }
  555.                 case 4:
  556.                 {
  557.                         P0&=0xf0;//清零
  558.                         P0|=0x04;break;
  559.                 }
  560.                 default:
  561.                 {
  562.                         P0=0x06;break;
  563.                 }
  564.         }
  565. }

  566. //设置电梯向上运行灯
  567. void setUpLight()
  568. {
  569.         upLight=1;
  570.         downLight=0;
  571. }

  572. //设置电梯向下运行灯
  573. void setDownLight()
  574. {
  575.         upLight=0;
  576.         downLight=1;
  577. }

  578. //设置电梯停止运行灯
  579. void setStopLight()
  580. {
  581.         upLight=0;
  582.         downLight=0;
  583. }

  584. //设置电梯报警灯和喇叭
  585. …………
  586. …………
  587. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
全部源码详见:
http://www.51hei.com/bbs/dpj-139823-1.html

0.png

全部资料51hei下载地址:
4层电梯仿真电路示例.zip (54.38 KB, 下载次数: 176)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:420804 发表于 2018-11-5 09:00 | 显示全部楼层
谢谢楼主,很有参考价值
回复

使用道具 举报

ID:155141 发表于 2019-5-11 22:35 | 显示全部楼层
没有仿真图参考意义不大
回复

使用道具 举报

ID:432653 发表于 2020-2-19 17:52 | 显示全部楼层
仿真下行灯全亮的按键没反应
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表