在PLC编程中,数学运算可能会发生数据溢出。最近一位朋友编写S7-1500 PLC程序,程序中求算术平均数的数据发生了溢出,最终数学计算结果输出错误。于是,朋友想到了调用状态字判断计算程序错误。可是,1500 PLC中却无状态字踪迹。
早期使用S7-300 PLC时,PLC的状态字可轻易地调用。然而S7-1500 PLC没有状态字,程序中已无法使用状态字。那么该怎么处理程序执行错误呢?
加法运算过程中发生溢出可能因为返回错误而导致的错误。但在某些情况下,加法溢出是系统预定义且可以接受,因此PLC系统不再认为加法溢出是一种错误。
通过以下几种方法,可以处理程序执行错误。
一、EN/ENO机制
S7-1500 PLC通过EN/ENO机制,可以检测和处理程序的系统错误。通过使能输入EN指令,将根据具体条件执行。通过使能输出ENO,可查询指令中的运行错误,并进行相应的响应。
新建项目“StatusWord”,并在项目中添加一个1500的PLC。
(1)新建全局数据块“GlobalData”,并添加全局变量:Value1、Value2、Result,ErrorID,Error。
(2)在主程序循环OB块中,添加“数学函数”计算指令。
该函数计算公式为OUT=(IN1+IN2)/IN3。IN3输入为固定值2。
(3)将程序下载到仿真PLC中。
(4)将“GlobalData”.Value1的值修改为16380,“Global”.Value2的值修改为20000,这时“GlobalData”.Result的值为-14578。“GlobalData”.Result正确的值应为18190。Int是16位有符号整数值,可表示的最大值为32767,在加法的过程中,发生了溢出,因此计算结果出现了错误。
(5)将PLC转至离线,单击“CALCULATE”指令块,选择”生成ENO“。并将ENO赋值给“GlobalData”.Error。
“CALCULATE”指令的ENO赋值给“GlobalData”.Error。
(6)修改完成后,将程序下载到仿真PLC中,再次运行PLC。
(7)将“GlobalData”.Value1的值修改为16380,“Global”.Value2的值修改为12000,这时“GlobalData”.Result的值为14190。该结果计算正确,ENO输出为True。“GlobalData”.Error的值为True,表示计算未发生错误。将“GlobalData”.Value1的值修改为16380,“Global”.Value2的值修改为22000,此时,数学运算发生溢出,计算出现错误。但是“GlobalData”.Result的值仍为14190。ENO输出为False,“GlobalData”.Error的值为False,表示计算发生错误。("GlobalData”.Result的值仍为上次计算结果,运算指令未写入值。)
在程序中通过判断“GlobalData”.Error的值,确认计算结果是否溢出或正确。
二、获取本地错误信息
在全局数据块,“GlobalData”中添加整数型(int)数组Value,数据类型为 Array[0..100] of int,添加变量index(int)作为数组索引。
(1)在程序主循环OB块程序段2中,添加加法指令,计算公式为:“GlobalData”.Value[100]:= “GlobalData”.Value[“GlobalData”.index]+100。
(2)将修改后的程序下载到仿真PLC,监视PLC的运行。当“GlobalData”.index的值为0到99时,数组未发生越界,程序运行正确。这时修改“GlobalData”.index的值为101,看看会发生什么。
此时数组寻址发生错误,PLC停止运行。
(3)在程序段3,添加GET_ERR_ID(获取本地错误信息)指令。点击“基础指令”->“程序控制指令”->“程序运行时控制”。
(4)将程序下载到仿真PLC中。再次运行PLC。
此时,PLC继续运行,并没有停机。GET_ERR_ID获取的本地故障码为16#2522,这时候根据故障码判断数组寻址是否越界。
三、SCL控制机制
前面我们提到的都是梯形图,而SCL语言中并没有加法等计算块指令,该怎么判断呢?
(1)新建FC块,命名为“Average”。新建input变量IN1、IN2;新建output变量IN3。变量数据类型均为int。
(2)编写FC块Average程序,#IN3 := (#IN1 + #IN2) / 2;一个简单的求平均数程序已完成。
(3)删除以前的程序块,在程序主循环OB块中调用“Average”,填好输入输出值。
(4)将程序下载到仿真PLC中,运行PLC,观察程序的状态。
这时,无论数学运算是否溢出,FC块都没有提示。
(5)点击“Average”属性,勾选“自动置位ENO”。
(6)将更改后的程序下载到仿真PLC中,改变输入输出值,观察程序状态。
更改属性后,FC块“Average”通过置位ENO,来判断计算是否溢出。
(7)通过调用FC块,可以在主程序OB块中判断数学运算是否溢出。在FC内部该如何编写程序呢。
“Average”属性一定要选择“自动置位ENO”。PLC执行完数学指令后,判断ENO的值,调用错误处理程序。
IF ENO THEN
#Error := 1;
END_IF;
在程序中也可以通过GET_ERR_ID指令控制程序的运行。