【SCL】算法——简单优先级

使用SCL实现一个算法来实现简单优先级


前言

大家好啊!今天我们一起用SCL语言来实现一个算法——简单优先级;使用场景是在<三层电梯>试验中;这里会结合着西门子的触摸屏来实现,可以看的更加直观一些!



一、场景需求

在我们实现三层电梯的运动控制时,主要有两个问题 :一是怎么才能记录所按下的按钮,然后根据所按下的按钮依次执行上升或下降;二是在上升或下降时怎么实现先执行距离当前位置最近的楼层,例:电梯在一层时,4层先被按下然后3层2层被按下,在进行上升的过程中,我们希望电梯先到达2层再到达3层最后再去4层,从高层下降到低层时也是一样。

 这里按钮的优先级是先考虑的电梯内部按钮(主要实现也是内部,外部因为有上和下,先暂时不考虑) ,下面我们来实现一下这两个主要需求。

 


1.记录所有按下的按钮,然后执行 

这里我们可以代入平时坐电梯时的基本运行:在电梯内有很多个按钮被按下,然后电梯按照一定规律进行上升下降,直到走完所有被按下的楼层(或没有按钮被按下了)。

那么问题来了,如何记录被按下的按钮,这里我的方法是:每个按钮被按下都让它有一个数值(代表被按下),再把数值存放起来,然后让电梯一个一个的执行;

具体实现就是:按钮按下给数组传一个值,在使用时我们遍历这个数组,然后再执行;

 SCL代码段:

按下按钮传入不同的值到数组中; 



//获取按钮上升沿
#PR[0](CLK := #S1);
#PR[1](CLK := #S2);
#PR[2](CLK := #S3);
#PR[3](CLK := #SU1);
#PR[4](CLK := #SU2);
#PR[5](CLK := #SD2);
#PR[6](CLK := #SD3);
    

//传入数值到数组
IF #PR[0].Q THEN
        "数据块_1".#SZ[1] := 1;
    ELSIF #PR[1].Q THEN
        "数据块_1".#SZ[2] := 1;
    ELSIF #PR[2].Q THEN
        "数据块_1".#SZ[3] := 1;
    ELSIF #PR[3].Q THEN
        "数据块_1".#SZ[4] := 1;
    ELSIF #PR[4].Q THEN
        "数据块_1".#SZ[5] := 1;
    ELSIF #PR[5].Q THEN
        "数据块_1".#SZ[6] := 1;
    ELSIF #PR[6].Q THEN
        "数据块_1".#SZ[7] := 1;
    END_IF;

在这里进行判断,找到一个不等于0的,然后执行;

 //判断条件
IF #I = 0 THEN
        FOR "数据块_1".W := 1 TO 7 DO   //执行循环
            
            IF "数据块_1".SZ["数据块_1".W] <> 0 THEN   //判断哪一个<>0,将当前第几个传给变量,下 
                                                      // 面变量再执行
                "数据块_1".T := "数据块_1".W;
                #I := 1;                              //找到后退出
                EXIT;
            END_IF;
            
        END_FOR;
 
    END_IF;

 

 触摸屏效果:这样就实现了记录的功能。





二、简单优先级

 可以进行按钮记录后,我们要来完成简单优先级设置,上升时要优先去最近的楼层,下降是优先先下降到最近的楼层

1.下降优先

 按钮传值和上面相同,这里我们着重看for循环;这里把数组的类型改成了bool型,不是0就是1;


    FOR "数据块_1".W := 1 TO 8 DO   //执行循环
   
        IF "数据块_1".SZ["数据块_1".W] = TRUE THEN  
            "数据块_1".T := "数据块_1".W;
        END_IF;
    END_FOR;

 效果:

 这里会优先找到最大的楼层,如果按钮1,2,3,4,5被短时按下,将会执行最高的楼层5,到达楼层后再执行楼层4,然后3,2,1;符合我们的下降优先要求! 


 

 执行流程:  

  FOR "数据块_1".W := 1 TO 8 DO   //执行循环  
        IF "数据块_1".SZ["数据块_1".W] = TRUE THEN   
            "数据块_1".T := "数据块_1".W;
        END_IF; 

END_FOR;

 上电后,for循环开始运行,变量W从1到8来遍历整个数组,如果其中一个按钮被按下,就将数组下标(第几个)传给一个变量,然后再执行程序;如果1,2,3被按下,那么2会覆盖掉1,3会覆盖掉2,最后输出结果就是3;如果有比3大的被按下,3就被覆盖掉了,然后执行最大的;最大的执行完成后,就会找到另一个数组里面最大的,再执行;

 


 程序运行原理:

工作流程知道后,下面就是它为什么一直这样执行?大的为什么能够覆盖掉小的?小的为真时为什么无法覆盖掉大的呢?

第一:它为什么能一直这样执行?

这样执行是和PLC的工作过程有关 ,PLC的工作过程是一个不断循环扫描的过程,cpu从第1条指令开始,按顺序逐条的执行用户程序直到程序结束,然后返回第一条指令,开始新的一轮扫描;每次扫描的过程有:输入采样、程序执行、输出刷新。所以,for循环从1到8循环1次后,会再次的进行循环。

第二:大的为什么能覆盖小的?

 for 循环从1到8开始遍历数组,我们假设5楼按钮按下,SZ【5】为TRUE,在循环到5的时候,条件成立;在这时按下4,输出结果仍为5,而不是4;因为4的后面还有5,5是最后一个,也就是最后输出的结果,运行后输出的始终是最后一个,因为它是1,2,3,4,5,6,7顺序来循环的。

第三:小的为什么不能覆盖大的?

 理解上面的运行原理后,就知道了;因为它最后的输出结果是最后一个,小的在前面不在后面,所以无法覆盖。


 

2.上升优先

上升优先要实现只需要和下降优先相反就可以啦!

 这里让for循环从8开始然后循环到1,就好了。


    FOR "数据块_1".W := 8 TO 1 BY -1 DO   //执行循环
        
        IF "数据块_1".SZ["数据块_1".W] = TRUE THEN 
            "数据块_1".T := "数据块_1".W; 
        END_IF;
    END_FOR;

 效果:

 

 






总结

以上就是今天的所有内容啦!再见!

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵小李

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值