,出水阀门使用6秒的输出脉冲打开。这样每个水泵的控制,需要3个
计时器。
为节省篇幅,这里省略了水泵停止部分的子程序,有兴趣的读者不妨自己实现。需要注意的是,水泵停止子程序要复位启动子程序中使用的计时器以及启动完成标志,启动子程序要复位停止子程序使用的计时器以及停止完成标志。梯形图主程序如图所示。
其中,TONR_TIMER为含有7个FBD_TIMER类型的计时器数组。计时器TONR_TIMER[0]没有使用。TONR_TIMER[1],TONR_TIMER[2],TONR_TIMER[3]用于水泵A的启动。计时器TONR_TIMER[4],TONR_TIMER[5],TONR_TIMER[6]用于水泵B的启动。JSR为子程序的调用指令。对于水泵A子程序,最后的Input Par为1,表示使用计时器数组中的前3个;水泵B子程序,最后的Input Par为4,是输入“实参”,表示使用计时器数组中的后3个。Return Par是输出的返回“实参”。MOV是赋值指令,Source为数据源。TONR_TIMER[].PRE是相应计时器的时间设定值。上面梯形图中的MOV指令实现的是对这6个计
时器的计时时间的赋值。
启动子程序使用ST结构化文本,其程序如下:
SBR(SBR_STARTED, SBR_OPENED, SBR_NUM);
TONR(TONR_TIMER[SBR_NUM]); //声明3个TONR型的延时开计时器
TONR(TONR_TIMER[SBR_NUM + 1]);
TONR(TONR_TIMER[SBR_NUM + 2]);
TONR_TIMER[SBR_NUM].TimerEnable := 1;//计时器1启动
SBR_START := NOT TONR_TIMER[SBR_NUM].DN;//水泵启动输出信号
TONR_TIMER[SBR_NUM + 1].TimerEnable := SBR_STARTED;//计时器2启动
TONR_TIMER[SBR_NUM + 2].TimerEnable := TONR_TIMER[SBR_NUM + 1].DN;//计时器3启动
SBR_OPEN := NOT TONR_TIMER[SBR_NUM + 2].DN AND TONR_TIMER[SBR_NUM + 1].DN;//出水阀门打开输出信号
SBR_STARTED := SBR_OPENED; //启动完成信号
RET(SBR_STARTED);
其中,SBR为子程序,括号内为输入“形参”,RET为子程序返回指令,返回输出“形参”。DN是计时器计时时间到;TimerEnable是计时器的允许启动。水泵的启动采用了3秒的脉冲信号,出水阀门打开使用了6秒脉冲信号。
当水泵A调用启动子程序时,使用的计时器从计时器数组TONR_TIMER[1]开始;水泵B调用子程序时,则是从TONR_TIMER[4]开始使用。虽然启动子程序是同一个,但使用的计时器是不一样的,这样就完成了在子程序中使用计时器。
结束语
由于在西门子Step 7子程序中已经内置了实现计时器的功能,所以我们也有必要在AB的RSLgix5000子程序中实现计时器功能,更何况需要有计时控制功能的子程序是大量存在的,不实现这一功能,意味着子程序几乎没有什么用处。
虽然本文中的具体实现方法与Step 7肯定是不一样的,但本质是一样的,都是利用了子程序外部的真实的计时器,通过真实的计时器实现计时功能。本文中,由于RSLgix5000无法使用“形参”,所以直接使用了外部真实计时器,而Step 7则是通过“形参”间接地使用了外部真实计时器。
从理论上来说,西门子的Step 7中的子程序,更好地体现了子程序的优势,通过特殊设计的“伪计时器”读取真实计时器的参数值,成功地把根本就不能将计时器作为子程序“形参”这一情况,在直观上得到彻底改变,方便了人们的使用。
而在RSLgix5000子程序中,只能直接使用外部真实的计时器。由于没有计时器作为“实参”和“形参”,所以无法全面体现出子程序的优势(在计算机高级语言的程序设计中,例如“C语言”,在子程序中使用全局变量,被公认为是不好的。但plc程序有自己不同于计算机程序的特点,不必拘泥于此)。但这也未必就是个问题,毕竟没有“伪计时器”功能,也就节省了其可能有的内存及执行时间的开销。如果说有不足的话,那就是使用了ST结构化文本,在只能使用梯形图进行编程的情况下就不适合了。