经常有人问,这个PLC有没有某某指令,或者,有没有指令可以实现这样那样的功能?
产生这样的疑问,部分原因是不熟悉这款PLC的指令。部分原因是为了选型,想找到一种PLC能够内置一些功能,使得自己的编程得到简化。甚至有一些人认为,PLC没有这个指令就是没有这个功能,不能完成某个任务。如果指令能自己做,那就没有这个问题了。那我们就试着自己做自己需要的指令。
本系列文章围绕S7-200 SMART PLC为中心,讲解如何编写自己需要的指令,编程语言主要以梯形图的方式为主。
第一篇 预备知识
一, 扫描
梯形图的所有指令一般遵循扫描原则进行执行。执行一个完整的程序,过程中由于扫描有先后次序,所以必然在一个瞬间只能执行一个指令。那么当扫描到程序中间的时候,程序前部分的程序先获得扫描并执行过,执行的结果将已经产生影响。后面部分的程序未曾执行,将来的执行当中所有条件将以最新的形态执行。
首先来看一个例子。如图1所示。
图1程序
从I0.0 = False(0)之后的某个扫描周期开始看看扫描的过程。此时,所有变量都没有接通。
当有一个扫描周期I0.0 = True(1)的时候,并且方框处的程序刚刚处理完的时刻,第一段的Q0.0显然跟以前的扫描一样,不接通。而此时此刻的M0.0已经接通,它将开始影响以后程序的执行。然后在这个扫描周期结束的时候Q0.1将接通了,但是Q0.0却没有接通。
下一个周期开始,扫描第一个M0.0触点的时候,此时的M0.0才开始影响第一行程序。
所以,扫描到并执行出的结果是影响往后的所有扫描的。并没有扫描周期之分。所有执行都基于扫描。
二, 能流
一行程序最左边粗实线是能流的源,这里永远是True(1)。通过各种触点的True(1)与False(0)组合,能流能到达右侧的线圈指令的话,就可以使线圈置位(1)。能流不能到达右侧线圈的话线圈就复位(0)。能扫描到的指令,基本能按照这种意愿执行。
要正确理解能流True(1)与False(0)两种状态对程序的影响,如图2所示。
图2程序
当I0.0 = True(1)的时候,两个指令都得到了能流。计时器指令按照自己的属性进行计时。传送指令把源地址数据传送到目的地址,无论目的地址原来有什么值都执行传送更新目的地址。
当I0.0 = False(0)的时候,两个指令都没有了能流。计时器在没有能流的时候把当前值写成0,把计时器位写成False(0)。值得注意的是,这个指令在False(0)的时候不是什么都不做的,而是在做False(0)时应该做的事情。有这样特点的指令还有输出线圈指令等。传送指令在没有能流的时候不再传送,不再理会目的地址。大量位于能流最右侧的指令都有这个特点。
三, 双线圈
不追究这个词的历史背景了。反正大家都知道在一个程序里面对同一个线圈出现过两次输出线圈就是双线圈。
双线圈不会当作是一种错误程序。它完全可以按照程序的行为作出解释。也就是说它没有语法错误,但是可能会导致逻辑执行错误。
如图3所示的例子,可能作者希望自动动作时的三个步骤Q0.0得电。而且切换到点动的时候又可以控制Q0.0。结果,由于出现了双线圈,影响了期望的动作。这是双线圈最显著的错误使用。
图3程序
对于输出点Q,总是按照一个周期中最后一个输出指令刷新输出到物理点的。
下面举一个案例,看看怎么处理比较好?
有一个输出点,根据工艺已经做好了程序并且调试成功。程序片段如图4所示。
图4程序
突然甲方来了一个要求,要求Q0.0在原来的基础上并联一个现场按钮,无论Q0.0是否动作,现场按钮按下时,Q0.0都要为True(1)。现场按钮松开时,不影响原来的程序作用。同时要求,Q0.1不受现场按钮影响。于是如图5所示做了如下修改。
图5程序
Ok。程序没有问题。要是改成如图6所示的程序,结果会怎样?同样,这个程序也可以完成上述任务。
图6程序
这是一个双线圈的程序。第二个输出线圈由于带有第一个线圈的执行结果,触点先继承了前面所有的逻辑,在此逻辑下增加了一个现场按钮。解决了Q0.0的需求,但是又没有对Q0.1有任何的影响。程序却非常简单。
再看一个双线圈使用的例子。如图7所示。
图7程序
先看网络1 2 3。“报警”和“运行中”两个信号由于有公共相似的逻辑,所以用一个线圈把公共部分记录下来,再在下面的程序多次使用这样的公共部分。为了使程序简单一点,不用在报警和运行的线圈前都把相同的公共部分重复写一次。然而,网络4才是Q输出点最终要达成的控制逻辑目的。Q只是在前面的工作中临时客串,义务送了一个人情。
临时变量的影子也悄悄地在这个例子中流露出来。
四, 多重赋值
多重赋值是说明一个地址,在程序多个地方都有出现对其写入的操作。双线圈是一种典型的多重赋值。执行写入的主动操作者可以是用户程序,可以是系统行为,可以是来自通讯端口改写。还可以是其他。
在早先一些PLC还不允许出现双线圈的时代,要绕过双线圈的规则,有这样的一种方法。程序开头对线圈复位。后面的自动程序需要什么步骤输出线圈,就用置位指令代替线圈指令。最终扫描结束输出物理信号的时候取决于是否对线圈置位,如图8所示,程序在“步1”、“步2”、“步7”,这三个步骤时输出。
图8程序
如图8这样的程序结构,在多个地方都出现对Q0.0写入值。当然这样各种的值都是不同的,相同的话就不必多重了。我们应该小心处理逻辑关系,避免出现不希望的值。
再看一个例子,如图9所示。
图9程序
程序中把输入量传给输出量。但是当发现输出量是负数的时候,把0传给输出量。也就是说限制输出量最小值是0,不可以再小了。
双线圈和多重赋值都是自定义库程序范围中一个非常重要的思想。不能很好理解这两个概念,将会对制作库程序产生很大的障碍。
五, 间接寻址
在操作数引脚(实参)上直接使用常数、绝对地址、符号这三种方式是编程中使用最多写法。另外,还有符号定义的常量和间接寻址两种方式相对比较少去使用。如图10所示。
图10 程序
间接寻址包括制作指针和使用指针。
指针是指向目的区域目的地址的标记。目前,CPU除了AC、HC、L区不能作为目的区域其他区域都可以间接寻址。
在后面的文章中,都只将V区作为间接寻址的目的地址做说明或者做例子。这并不表示不能寻址到其余区域。
例子中的 ”T40” 的设定值填写的是一个间接寻址。意思就是说这个位置虽然不是一个具体的设定时间,但是,具体的值位于这个指针所指的地方。而这个地方当时是什么值,那么计时器的设定值就是什么值。
简单讲就是“你要的东西用纸(址)包着”和“你要的东西用纸(址)写着”。
现在就围绕这句话,聊一聊间接寻址。
首先说说这张包东西的纸(址),不是什么地方都可以做的。什么材料可以做这张纸?材料可以是全部V区、全部L区、AC区的AC1 AC2 AC3可以装载指针。并且只能用连续的4个字节组成的双字装载指针。起始地址不介意是奇数还是偶数。
要用纸包着东西,必须把东西放进去纸里面。MOVW 100 VW0 这里 ”100” 就是东西, ”VW0” 就是一张纸。小的东西就用一张纸包(一个字节),很大的东西就用四张纸拼成一张大纸包(一个双字)。用这件东西的人只要找到这张纸直接就得到里面的东西。
你要的东西用纸写着,那就是说事前必然有人在纸上已经写了字,后面才能有人看见。MOVD &VB400 VD4 。这里 ”VB400” 就是写在上面的字,”&” 符号是说明写着这几个字是一个地址,不是普普通通的字。”VD4” 就是一张大纸。这就是制作指针。
手里拿着这张纸后,自然要根据这张纸的指引做一些事。如图10程序最后一行指令。执行一个计时器指令时使用了” *VD2” 这张纸 ……,如果只写 ”VD2”,那么就好像是使用 ”VD2” 的值作为计时器设定值,但是事实并非如此。这里 ”VD2” 前面带*号。星号表示 ”VD2” 里面的值是指引真正包含设定值的地址。由于 ”VD2” 里面先前一个指令写入了 ”&VB0” ,所以这张纸其实是指引计时器到 ”VW0” 找寻设定值。这就是使用指针。当然这是因为是在定时器的时间设置用到指针,而这个设置变量的类型是字。而如果在MOVB输入用到相同指针 ”VD2”,那么输入的就是 ”VB0” 而不是 ”VW0” 了,因为MOVB指令需要的输入变量的是字节,也就是指针保存的是起始地址,具体使用的变量取决于指令需要。
使用间接寻址的好处在于通过计算改变指针的值,可以寻址到附近的任何地址。当指针指向VB10的时候,把指针增加10,那么指针就会指向VB20。寻址就改变到VB20。指针再减少3,那么寻址就会找到VB17。对于一片连续的V空间只要知道第一个地址,就可以寻址到连续的第n个地址。
在以后的子程序使用中将会非常多地用到间接寻址的。
后面的内容更精彩——带参数子程序的制作。
编辑:黄飞
评论
查看更多