人人都在用沿触发。但是我觉得沿触发是刚开始接触PLC的伙计们遇到的第一个需要认真思考的问题,因为这牵涉到PLC中一个重要的知识点:程序扫描。今天借着与同事的对话就说说沿触发的一些事儿。
今天和一个同事在探讨编程问题的时候,他说其他品牌的PLC还有西门子200系列的PLC在做沿触发时都无需占用一个bool的空间。只有300/400/1200/1500才需要占用一个位,这样觉得很奇怪,下图是这些型号PLC的沿触发程序。其中变量“tag_2”似乎完全无用。我们只需要结果“Tag_3”就可以了。

图1
我说,其他类型的PLC在做沿触发时如果没有类似Tag_2这样的变量,那么这个型号的CPU的沿触发数量一定是有限制的。他说,是的,有数量限制。我接着说,因为这类型的CPU在做沿触发时在CPU内部资源中有一个专门给沿触发预留的存储空间,用于沿触发的中间bool变量。虽然在程序中我们没有看到这个中间变量,但是在编译时系统会自动为每一个沿触发指令分配一个中间变量,并加入到程序中。如果沿触发过多,系统预留的中间变量用完了,那么就无法再增加沿触发的程序了。这就是这类型CPU沿触发数量限制的原因。
虽然300/400/1200/1500在做沿触发时需要这个中间变量,但是有一个好处是:沿触发的数量非常大,可以讲是没有限制的。
第二个问题
前面说明了沿触发肯定有一个中间变量。只不过这个bool类型的中间变量要么是显式的(如300/400/1X00),要么是隐式的(如200系列)。这是第一个问题。现在有了第二个问题。为什么沿触发需要这个中间变量呢?这是因为这个中间变量要记住上一个扫描周期tag_1的状态是0还是1。
世界上无论哪个CPU芯片都没有沿触发这条汇编语句。那么PLC的CPU是如何实现沿触发的呢?答案是:把沿触发转换为普通的CPU芯片可以执行的语句。
我们不妨把图1的内容翻译为文本语言,看看沿触发的工作原理。

图2
图2就是把梯形图翻译为SCL语言,network 2可以实现上升沿触发,功能完全等价于network1。只是把Tag_2的名字更改为了Pre。Pre的含义就是记住Tag_1在上一个扫描周期的状态。所以在第7行就是实现这个意思用的。通过这个讨论,我们建立起了一个概念:程序是在不断的、持续不停的滚动执行。每次从头到尾的执行就是一个扫描周期。下一个扫描周期IO状态与这个扫描周期的IO状态不同,我们的PLC程序就是在应对这些状态的变化,因此演绎出千变万化的应用程序。
用扫描周期的思想审视一下图1中"P_TRIG"指令。实际上是将这个指令转换为了图2那样的简单语句在CPU中执行的。
我们现在知道这个中间变量就是为了记住上一个扫描周期Tag_1的状态用了。只有记住了上一个扫描周期的状态,在这个扫描周期状态与上一个扫描周期状态比较后就知道这个扫描周期是上升沿还是下降沿或者没有沿。
200系列PLC只有1024个沿触发。如果超过这个数量,我们可以按照上述的原理自己编写延触发程序。
第三个问题
我们再把这个沿触发的问题延申一下。
如果network1或者network2在一个FC中,比如FC1。而这个FC1在上一个扫描周期没有被调用。那么情况就有意思了。如果没有被调用,那么M0.1自然就没有记住上一个周期Tag_1的状态。M0.1仅仅记住了上一次调用FC1时Tag_1的状态。那么这个沿触发就失败了。所以这个问题要引起重视。有时候我们的程序和预想的不一致,原因都隐藏在这些小小的细节中。
通常讲,如果有沿触发,那么一定要让这个沿触发的程序在每个扫描周期都执行。
第四个问题
上面讨论到通常的情况。这就留了个口子。自然还有不通常的情况。第4个延申问题就说说不通常的情况。
当前PLC运行速度非常快。可以处理一些轻型的IT任务。IT任务的一个特点是事件触发。没有事件时无需触发。假设一个事件触发了一个IT任务,这个IT任务的代码在一个FB中。这个FB不是每个扫描周期都执行的。一旦触发了这个IT任务,这个FB大约要执行若干的扫描周期。在这个FB中需要一个沿触发。这个沿触发的代码怎么写呢?这个就有点意思了。
把上一段抽象的说具体点,这样有利于思考。比如本PLC收到上位MES发的指令。指令要求本PLC执行Job003任务。当本PLC从以太网收到这条指令后,本PLC要触发一个相应的FB执行,比如是fb_Job003。在这个FB中要做如下内容:1,马上回复MES,告知MES我现在是否可以执行这个JOB003任务。2,当执行完JOB003之后,还要向MES汇报执行的结果如何。当这2件事情做完后,这个FB就不需要执行了。在FB的业务代码中需要沿触发的功能,比如第1项工作(立即回复MES的工作)只需要做1次,不需要做第二次。这就需要一个沿触发。用PLC自带的沿触发肯定是满足不了要求的。因为上面我们探讨过,PLC自带的沿触发必须每个扫描周期都执行,但是本FB不能每个扫描周期都执行。所以只能自己写沿触发功能。那么在这个不是每个扫描周期都执行的FB中如何写沿触发的代码呢?
有人问,为什么这个FB不能每个扫描周期都执行呢?因为在这个PLC中这样的FB有很多,比如job001-job50。而其中每个FB的程序量又很大。如果每个扫描周期都调用所有类似的FB,那么PLC的扫描周期会很长。
总结第4个问题,要求如下:
1,有个FB不能每个扫描周期都运行
2,这个FB一旦执行,那么需要执行若干扫描周期
3,在这若干扫描周期中,需要沿触发的功能
4,如何触发这个FB不是本题目,题目是:如何在这个不能每个扫描周期都执行的FB中实现沿触发的功能。
这种场景我有自己的解决方法。不过也想让大家在过节期间稍微锻炼一下脑子,否则脑子容易硬化,不够灵活。
可以回帖说说你的解决方案或者想法或者不解。
本贴总结:本帖针对沿触发的功能引申探讨了4个问题。
1,沿触发需要一个中间变量
2,沿触发为什么需要这个中间变量
3,通常讲沿触发的代码需要每个扫描周期都执行。这里补充一点:不同OB的沿触发不能混用。
4,在不是每个扫描周期都执行的程序块中,需要自己开发沿触发功能代码。
本篇就到此吧。另外,有点小感触:一个平时不被注意的沿触发,延申出了4个问题。每一个问题都建立在上一个问题之上,思虑层层递进。这让我联想起一句话,业精于勤而荒于嬉。
如何提高自己的竞争力呢?2个方面。提高人格。这方面仁者见仁智者见智。另一方面提高自己的业务水平,要精、专、细。