脉冲指令用于将输入脉冲化,在某种情况下,如果未能将输入脉冲化,则每个扫描周期都将执行指令(如自加/自减指令等),会得到错误结果。
其它品牌PLC脉冲指令无前周期状态位,虽则简化了编程,但是在某些特殊情况下会导致错误运算结果,以下为实际编程中出现的情况。
之前刚做了一个项目,用的是日系某品牌,该项目在主程序中3次调用某子程序,子程序中有下降沿脉冲指令用于计数,在调试时发现计数不是按预计出现下降沿脉冲时计数一次,而是不停计数。
反复检查子程序逻辑,未发现问题。最后将子程序只调用一次则计数正常。
经再三思考,发现问题出在子程序中调用了脉冲指令,解释如下:
假设:子程序中使用了形参M0的下降沿脉冲指令,此指令对寄存器D0加计数。第一次调用实参为X0,第二次调用时实参为X1。
程序运行后X0接通,X1断开。程序执行如下:
步1:X0接通;
步2:第一次调用,进入子程序,M0接通;
步3:第一次调用结束,M0保持ON;
步4:第二次调用,此时因X1未接通,进入子程序时M0为OFF;
步5:M0状态由ON变为OFF,出现下降沿脉冲,D20加1计数;
步6:程序重复执行,则重复以上1~5步。
发生以上情况的原因是当退出子程序时,系统只能保持一次位变量前一周期扫描状态,当第二次调用子程序 时,此状态会被错误引用(只调用一次则没问题), 后来将子程序中脉冲指令移到子程序外,测试未发现问题。
查阅了其它PLC资料,发现另一日系品牌及S7-200存在相同问题。但S7-300/400/1200中则可设置可分别设置前一扫描周期状态保持位,不会发生以上问题,以下使用S7-1200及Step7 V11编程时为例。
1) 单次调用脉冲化指令
单次调用脉冲化指令时,只需给其指定一个前周期状态保持位即可,在OB或FC中单次调用脉冲化指令情况较多,分别以LAD及SCL编程时说明:

说明:1.1 在LAD编程中,上一扫描周期状态保持位为M1.0,它保留上一扫描周期的I0.0状态,并与此扫描周期I0.0状态对比,若有上升沿则输出;
1.2 在SCL编程中,利用可保持的位来实现上升沿检测,其中boolTag1为FC或OB输入参数,Tag_39为M1.0的变量名,利用以上语句可实现boolTag1上升沿检测。注意前一扫描周期状态保持位不能为FC的临时参数,因为临时参数在执行扫描时会设置为0,从而导致程序执行达不到要求。
2)多次调用脉冲指令
如果某一FB或FC被多次调用,使用以上方法编程则会出现程序执行达不到要求,分析如上所示,此时可采用方法让每次调用都使用不同的保持位,则可解决以上问题。
如果是在FB中调用脉冲化指令,则比较简单。可利用FB被其它程序块调用的“多重背景”功能,将脉冲化指令的上一扫描周期保持位设置为FB的静态变量则可解决。

程序中boolTag1为FB输入参数,BitMem1为FB静态变量,其在FB多次调用时,会将当前值保存在不同的背景数据块中,从而实现多次调用不互相干扰。
如果是在FC中调用,因为FC并无静态变量,所以可选择用一个输入输出参数来作为前一扫描周期状态保持位,每次调用时先读取状态位,然后保存在输入输出参数中,即可实现多次调用互不干扰。

程序中boolTag1为FC输入参数,boolMem1为FC输入输出参数,因为需先读后写,所以需使用输入输出类型参数。