5.1 计时器指令编程
计时器指令是输出指令,根据梯级条件运行,计时基值为1ms,计时范围为1~2147483647ms,计时器计时数值为32位寄存器的正整数。计时器指令使用TIMER结构数据类型的标签,如图5-1所示。
图5-1 TIMER结构数据类型标签
计时器结构数据标签的元素:
●PRE预置值 设置预定的时间值,以毫秒为单位的数值,即计时脉冲个数。
●ACC累加值 计时脉冲个数的积累数值,每当计时器指令被扫描时实施累加。
●EN使能位 梯级条件满足计时器指令时,使能位置位。
●TT计时位 计时器指令被使能,计时位置位,直到累加值大于等于预置值复位。
●DN完成位 计时器指令被使能,完成位复位,当累加值大于等于预置值时置位。
我们先讨论非保持型通延时指令TON。当作为输出指令的TON指令的梯级条件成立时,指令被使能,开始计时工作,直到累加值等于预置值,完成位置位,计时工作停止。梯级条件对于TON指令至关重要,当梯级条件消失,无论是否计时完成,累加值都会复位,同时所有状态位复位。通延时计时器工作状态位波形如图5-2所示。
TON指令梯级条件消失引起的复位是常常被讨论的,这可以用来实现指令的自复位,从而得到定时操作功能,同时预扫描和后扫描对TON的复位影响在编程时也是需要关注的。
图5-2 通延时计时器工作状态位波形图
非保持型的断延时指令TOF,当作为输出指令的TOF指令的梯级条件不成立时,指令被使能,开始计时工作,直到累加值等于预置值,完成位从置位状态变为复位状态,计时工作停止。梯级条件转为成立时,无论是否计时完成,累加值都会复位,同时所有状态位回到初始状态。断延时计时器工作状态位波形如图5-3所示。
TOF指令完全使用负逻辑工作,所以它的梯级条件、指令使能位和完成位与TON的同3个位是相反的,这条指令可以满足负逻辑关系的计时工作,但请留意它的计时位TT跟TON指令的TT位是一样的,或者说仍然是正逻辑关系。此外,它非常特殊的一点是指令初始状态并不是通常指令的复位状态,所以总是被强调,不要对它使用复位指令RES,因为复位指令是将所有的状态位复位来作为初始状态。
保持型计时器指令RTO。当作为输出指令的RTO指令的梯级条件成立时,指令被使能,开始计时工作,直到累加值等于预置值,完成位置位,计时工作停止。从计时对梯级条件的要求来看,RTO指令与TON指令是完全一样的,惟一不同的是,当梯级条件消失,所有状态位复位,但累加值不会复位,累加值的复位与后面我们将要谈到的计数器指令一样,必须使用复位指令RES。保持型计时器RTO工作状态位波形如图5-4所示。
PLC从问世一直到现在都要用来控制时序逻辑、时序时序、时间的顺序,用计时器来担纲,当然是非它莫属了。计时器的工作通常有延时、定时和累计时。下面我们试着用一些常见的例子来编写计时器应用的梯级逻辑。
图5-3 断延时计时器工作状态位波形图
图5-4 保持型计时器RTO工作状态位波形图
5.1.1 计时器的延时编程
延时动作指的是当事件发生后,并不马上执行,而是等到一段延时之后再执行,比如说,现场有一个传感器监视一个故障的发生,当探测故障发生的信号进来,如果马上动作,可能会引起停机,因为有的故障是需要停机的,假定这个故障信号并不是真正的故障,可能只是一个干扰的信号,停机就变成虚惊一场了,还可能带来不必要的停机损失。干扰信号或许是很小的一个窄脉冲,但在快速反应的I/O刷新和快速的例程扫描,已经足以使这个梯级产生控制动作了,我们不妨让这个信号延时一段,确定故障真实的存在,再去故障停机。梯级逻辑编程如图5-5所示。
图5-5 延时梯级逻辑
如果我们将计时器的预定值定义为1000,作为时间基值为1ms的计时器,那么计时器TON的梯级条件Fault能保持1s,这个故障输出动作的产生将延时1s执行。一个故障探测状态输入能够保持1s之久,我们有理由相信,故障真的发生了。如果这仅仅是一个扰动信号,不到1s便已经消失,计时器TON的梯级条件随之消失,计时器复位,完成位不会置位,故障输出动作不会发生。故障动作延时时间可以根据现场实际情况来确定,系统运行一段时间后,挑选一个合适的延时时间便可。
另一个延时监视的例子是对一个旋转机器的监测,以确定旋转的机器没有被机械卡死,一直处在旋转的状态。某个机器有一个机械触发器,如果这个机器一直在旋转,这个触发器会在设定的时间内触动一个感应器,感应器的状态将中断一个计时器的梯级条件,令计时器复位。如果在设定的时间一直没有中断,计时器的完成位便会置位,产生一个状态动作,给出机器不在旋转状态的信息。梯级逻辑编程如图5-6所示。
图5-6 延时梯级逻辑
这个计时器的监视时间是1min,如果1min过去,机械接触器还没有触碰到感应器,计时器的梯级条件在这一段时间都没有消失,计时器计时完成位将锁定机械旋转停止的信息。如果机器旋转正常,则感应器会不时地中断计时器的梯级条件,令计时器复位,完成位的动作就始终不能发出。
我们再看一个双向逻辑控制延时的例子,这是某个输出开关的控制需求,当控制发出打开的命令后,延时2s打开;或者控制发出关闭的命令后,延时2s关闭。如果发出打开的命令后不到2s接受到关闭的命令,则不打开;如果发出关闭的命令后不到2s接受到打开的命令,则不关闭。请看如图5-7所示的梯级逻辑编程。
图5-7 双向延时梯级逻辑
延时控制开关Delay_Control_In同时作为通延时器指令TON和断延时器指令TOF的梯级条件,开或关的任何情况下总能满足其中一个计时器的条件,并令它开始计时,最终产生它的延时动作输出;或者突然中断某个方向的延时而转回原来的方向。
这是一个典型的对称性的编程实例,巧妙地运用了通延时计时器和断延时计时器的逻辑动作,梯级简洁而明了。曾经有学生单用TON指令编出了我要的控制结果,由于没有使用断延时计时器,程序看上去没有对称性,被我无情地否决了。通延时计时和断延时计时的逻辑相反的特点,正是与我们的需求吻合的,为什么不这样直截了当地使用呢,没有对称编写出来的程序,逻辑关系是不够清晰的,解释颇费周折,过不久连自己也读不懂了,尽管可以实现逻辑功能却没有可读性,只要了解TON和TOF执行的不同之处,相信这几个梯级是可以令人一目了然的。
另外,要提醒注意的是,断延时计时器的DN是常开作为动作位(请回顾一下TOF指令的状态位的波形图)。梯级条件编写是当断延时完成动作时,也就是OFF时,去关闭延时控制输出。
5.1.2 计时器的定时编程
定时也是控制现场常见的需求,比如希望能够得到一个定时的动作脉冲去执行一个周期性的动作。
现在,我们来谈谈自复位计时器的定时作用,这是最常使用的方式,如果你看到一个梯级编成这个样子,如图5-8所示,你第一个反映就是,这将产生一个周期性动作,通常这个计时器的DN位在后面的一个梯级中就被当做动作执行的梯级条件了,它所控制的输出指令不失时机地产生了一个执行动作。再强调一下,这个DN位一定要出现在这个计时器后面的梯级,即使你在自己的测试中,DN位在前或在后似乎没有什么不妥,这样的执行顺序是一定不可以忽视的,同时也是一种良好的编程习惯,这可以帮助你避免某些陷阱。
图5-8 自复位计时
为了让大家更清楚定时动作的作用,我们不妨来分析一下这个自复位计时器的工作过程。自复位计时器永远都是用它自己的完成位常开作为它自己的梯级条件。我们知道,还没有开始工作的计时器,DN位现在是为0的,作为常开节点,在梯级第一次被扫描时,梯级条件当然是成立的,此时计时器指令被启动,待这个梯级第二次被扫描时,梯级条件依然成立,计时器依然被使能,计时器指令继续执行,将上次扫描到这次扫描的时间间隔累加到ACC中,然后将ACC与PRE进行比较,如果小于,则离开梯级,这次指令执行完毕。如此循环多次,终于ACC几乎接近PRE了,在最后一次扫描中累加后的判断,ACC大于等于PRE,此时DN位置位为1,指令执行完毕,离开梯级。等到这个梯级再次被扫描时,此时因为DN=1,毫无疑问,梯级条件不成立了,正如我们对TON这条指令执行的了解,当梯级条件不成立时,累加值复位,状态位复位。计时器指令用一个扫描周期的时间为自己复位,这就是自复位计时器。
这样,你当然明白为什么强调动作位一定要编辑在计时器指令的梯级之后了,如果你执意要编在不合适的位置,那你就把这个执行动作置于可能丢失的风险中了。
用两条计时器指令配合,产生两个时段的不同动作,且周而复始地进行,也是满足需求常见的编程方法之一。如图5-9所示的梯级逻辑编程,控制的结果将产生一个正负方向的方波信号,显然分别调节两个计时器的预置值,便可调节方波的频率和正负波占空比。传送指令MOV传送立即数至目标地址,将作为方波的幅值。
这也是自复位的计时方式,不过是两个计时器互为依存的复位,计时器Timer_Reverse的完成位的复位状态首先给Timer_Positive提供了梯级条件,当Timer_Positive计时完成,将为计时器Timer_Reverse提供梯级条件,直至Timer_Reverse计时完成,Timer_Reverse完成位置位复位了计时器Timer_Positive,复位后的Timer_Positive完成位立即复位了计时器Tim-er_Reverse,至此完成一个周期。Timer_Positive的完成位的不同状态则持续了两个时间段,用以完成正幅值和负幅值的传送。
再举一个耳熟能详的例子,交通红绿灯具有定时工作和互锁逻辑关系,比起工控系统中的多逻辑互锁,更为容易理解,我们就拿它来编程模拟工控系统中最常用的互锁逻辑动作。
假设东西方向绿灯和南北方向红灯亮6s;东西方向红灯和南北方向绿灯亮4s(为了观察方便,时间设得短一点),显然可以用两个自复位计时器来控制这两段时间,编辑如图5-10所示的程序。
图5-9 两个计时器互锁复位操作
两个计时器各自复位自己的时间,然后将两个计时器计时动作互锁,每个计时器指令的梯级条件都是对方计时器的使能常开位,这是很常见的指令执行互锁模式(关于多指令执行互锁的编程方法,我们在后面再讨论)。
如何使用计时器的工作位来控制输出,我们可以采用两种不同的编程方式,这是输入梯级条件与输出指令搭配使用的一个典型例子。
如图5-11所示的方式,控制工作位是计时器的计时位TT,即在计时器的整个计时时间段,TT保持在置位状态,提供梯级条件支持非保持型的输出指令OTE,点亮南北方向的绿灯和东西方向的红灯,或点亮东西方向的绿灯和南北方向的红灯,一旦梯级条件复位,相应的灯随之熄灭。
这是用持续的梯级条件来维持非保持性输出指令OTE的输出状态的一种编程实例。使用OTE指令时预扫描和后扫描的作用是要考虑的,显然在交通灯这样的例子中,影响是不太大的。
如图5-12所示的方式,控制工作位是计时器的完成位DN,作为自复位的计时器,一般情况下完成位DN只存在一个扫描周期(互锁的计时器则不同),与之匹配的输出指令应该是锁存输出指令OTL和解锁输出指令OTU,梯级编程为锁存南北方向的绿灯和东西方向的红灯,解锁东西方向的绿灯和南北方向的红灯;或锁存东西方向的绿灯和南北方向的红灯,解锁南北方向的绿灯和东西方向的红灯。
图5-11 交通灯互锁控制
上面的两种编程方式,我个人更倾向于互锁计时器DN位搭配锁存解锁输出指令的方式,这样似乎更为严密而不受干扰。
让我们把这个程序下载到控制器中运行。任何自认为正确严密的程序,都要经过在线运行的测试,这就是现场调试。果然,问题暴露了,这个程序运行之后的前6s内没有任何灯被点亮。你几乎马上就想到了,这段时间没有任何一个计时器DN位置位,这些灯都是靠计时器的完成位DN位来动作的。应该一开始就让灯点亮,我们加上一个初始化的梯级,如图5-13所示。
原来,初始化也不一定是0,只要是初始条件所需要的就可以了,凡是初始化的梯级或例程,它的执行条件一定是只有初次扫描执行惟一的一次。S∶FS被称为首次扫描状态位,是系统中少量的无需建立标签便可直接使用的关键字之一,这是仅仅存在一个扫描周期的为1的状态位,为初始化执行动作提供一个可使用的内部状态位。
图5-13 初始化梯级
有的编程人员会把项目中所有的初始化的操作集中在一个初始化例程里面,初始化例程中有多个如图5-13所示的梯级,然后用S∶FS的梯级条件调用这个子例程。如图5-14所示,初始化例程Initialize只会在控制器运行之初执行一次。这是非常值得推荐的程序规划,尤其是我们谈到的标准化编程,就是希望把同类的处理集中于一处,这样便于查找,当我们猜测某个数据可能有初始化处理时,就会到初始化例程中去查找。
图5-14 调用初始化例程
如果你不愿意将这个初始动作放置在远离梯级控制逻辑的地方,按照如图5-15所示的梯级逻辑编程也是可取的,这样将初始逻辑处理和正常运行的逻辑处理并列一处,让人一目了然,更有利于解读程序,这也是早期有经验的工程师经常采取的方法。从这个实例看来,标准化的编程似乎在挑战这个典型的模式,事情往往这样,标准化的东西总有些繁杂,但有规矩可循,简洁的手段就不愿意墨守成规。如果是一个团队的工作,恐怕还是标准化更有意义,否则沟通所花费的时间将更多。
这个初始处理并列一个初始化条件,输出指令则利用了一个常规的完成操作,似乎比MOV一个值更为简洁,但不适合单独梯级处理。
图5-15 含初始化的梯级逻辑
现在,这个交通灯控制的梯形图的完整梯级逻辑如图5-16所示,请注意梯级安排的顺序。计时器在前面的梯级,它的完成位所执行的动作梯级在后面的梯级。控制南北方向和东西方向的两个互锁的计时器,按照梯级如此的排列,首先计时的是东西方向的计时器Tim-er_TrafficLight_EW,所以S∶FS锁定的是南北计时器的动作,令南北方向率先流通,一旦东西方向计时器完成,便进行交换,之后循环下去。
还有一点需要我们记住的就是,计时器的动作位只有DN位和TT位,这是指令计时开始之后具有的两种状态,只有它们跟计时过程有关。有人居然采用EN作后面梯级逻辑的动作位,那个程序运行起来看上去也还正常,要知道那恰恰是一对互锁的计时器,用于限制两条计时器指令的同时执行,这使他浑然不觉自己的错误。计时器的EN位永远跟梯级条件一致,要知道是梯级条件令计时器使能,如果你使用计时器的EN位,那你还不如直接用计时器的梯级条件,那还要计时器的介入何用呢。
不过,看上去不规范的运用,不是愚昧,就是智慧。我曾读过一段例程,看到EN突兀地出现在一个梯级,吃了一惊,细读之后,不禁哑然失笑。原来这个例程里有一个堪称主心骨的计时器,它的梯级条件十分复杂,并行了好多分支的位状态,一个屏幕都看不完。这个计时器之后一百多条梯级后,居然有个报警动作,也要使用这个跟计时器相同的梯级条件。我刚才还在说,不如直接用这个梯级条件,还真有这种做法,真是开眼界了。
话又说回来,如果出于愚昧,使用了EN位,那就不可原谅了。
有时候程序运行的陷阱是我们自己设置的,因为我们没有正确地使用指令,没有正确地使用指令的参数。
图5-16 交通灯控制的完整梯级逻辑
5.1.3 计时器的累计时编程
计时器还有一个重要的用途,就是用于时间的累计。如果计时器的梯级条件是断断续续的情形,只要梯级条件成立,就开始时间累计;梯级条件不成立,就停止时间累计,最好的选择是采用保持型的计时器指令RTO来完成。如图5-17所示的梯级逻辑编程,就是累计时的一种编写方式。
图5-17 累计时梯级逻辑
保持型计时器累加值使用梯级条件对计时器复位,复位的梯级条件可用ONS指令加以限制,以确保只会执行一次,否则在复位的梯级条件没有取消时,计时器不能开始计时,一般情形,复位指令最好确定只能执行一次。
这里有一个典型的时间累计的例子,要求编程采集一个发动机运行的累计时间为机组保养提供依据,当发动机的转速超过1100转/分钟,算作发动机的正常运行时间,将这个时间进行累计;当发动机转速不到1100转/分钟,发动机不算正常运行时间,不做时间积累,这是一个允许梯级条件断断续续的计时累积,比较指令的判断结果作为梯级条件,决定是否进行计时累积,梯级逻辑编写如图5-18所示。
图5-18 发动机累计时梯级逻辑
当时间累积达到设定的预定值,计时器的完成位Timer-Totalize DN置位,给出机组保养有关的提示。
是否只有断断续续的时间累计才会用到保持型计时器RTO指令呢?也不尽然,出于一些特殊的目的或需求,有时也会用到RTO指令。
在现场运行程序实例中,摘过来两个这样的梯级,如图5-19所示。这是一个电动机连续运行和停止的时间累计,运行或停止的梯级条件满足,连续时间达到1h,计时器的完成位DN将执行相应的动作;不足1h梯级条件消失,指令未使能,计时器常开使能位令计时器复位。
乍看来,这是利用计时器梯级条件不满足,用计时器未使能状态来给计时器复位,为什么编程者不采用TON指令来完成呢?如前面的讨论,我们已经知道,当TON指令的梯级条件消失的时候,计时器的累加值是复位的。在这个实例中,满足的需求显然是:除非梯级逻辑自己判断的不足1h的运行或停止的梯级条件消失可以复位外,其他外在的原因引起的计时器累加值复位都是不允许的。
图5-19 连续累计时梯级逻辑编程
这里重要的差别在于,RTO指令的累加值不受预扫描和后扫描的影响,它的累加值在经历了预扫描和后扫描之后,仍然能够继续积累而不会被清零。你可以试着将控制器从编程状态切换到运行状态,反复进行几次,可以观察到控制器在编程状态时会停止累计时间,在运行状态会继续累计时间,累计值在运行和编程反复切换的过程中不会被清除。如果是TON指令的话,每次从控制器运行切换到编程状态,它的累加值会静止在当前的数值,一旦控制器从编程切换到运行,程序的预扫描作用就会将累加值清除为零,然后重新开始计时。只有在线调试时,才知道自己什么地方考虑不周,如果对指令有足够详尽地理解,就会迅速反应过来,知道自己缺失在何处。
从保持型计时器RTO运行的状态波形图中,我们早已了解它的累加值是不能利用梯级条件的消失来复位的,保持型计时器和保持型指令计数器一样,必须要用专用的复位指令RES来复位。
说到复位指令RES,有一件事不能不再次提及,这就是对断延时指令TOF,千万不可用复位指令。不知是出于习惯还是什么原因,通常我们说的置位,就是把这个位地址设为1;而我们说的复位,就是把这个地址设为0。当使用复位指令RES时,它的复位操作是令所有位为0。但是TOF的初始状态可不是0,大家已经看过它工作的波形图了。可以说除了TOF指令,其余指令的复位状态都是0,只有它是个特例。在编程满足需求时,如果你想给它复位的话,设法消除它的梯级条件就可以了。前面在介绍TOF指令时,已经提到不能使用RES复位,但是想来不会被注意,往往在面对真实的应用时,人们才会恍然大悟。
从以上编程的一些实例来看,大家可以明白,选择什么样的计时器指令来满足你的需求是大有讲究的,计时器指令看起来简单,运用起来却是非常灵活的,许多例程的编写,只有通过现场调试,不断地改进,才能找到最佳的解决方案。
每种控制器产品都有计时器,但是它们的用法未必相同,如果你使用的是Logix控制器,那么享受功能齐全的计时器给你带来编程乐趣吧。