声明部分的结构(Structure of the Declaration Section)
块中的声明部分包含以下子域:
常量:在CONST和END_CONST之间。
输入参数:在VAR_INPUT和END_VAR之间。
输出参数:在VAR_OUTPUT和END_VAR之间。
静态变量:在VAR和END_VAR之间。也包括对evalUATE块的本地实例的声明。
CONST
LIMIT := 7;
QUANTITY := LIMIT + 1;
END_CONST
VAR_INPUT 输入变量声明
measval_in :INT ; // 新测量值
newval :BOOL; // 在环形缓冲区"measvals"中的测量值
resort :BOOL; // 对测量值进行排序
funct_sel :BOOL; // Select calculation square root/square
newsel :BOOL; // 取得输出地址
selection :WORD; // 输出地址
END_VAR
VAR_OUTPUT 输出变量声明
result_out :INT; // 计算值
measval_out:INT; // 相应的测量值
END_VAR
VAR 静态变量声明
measvals:ARRAY[0..LIMIT] OF INT := 8(0);
resultbuffer:ARRAY[0..LIMIT] OF
STRUCT
squareroot:INT;
square:INT;
END_STRUCT;
pointer:INT:= 0;
oldval:BOOL:= TRUE;
oldsort:BOOL:= TRUE;
oldsel:BOOL:= TRUE;
address:INT:= 0; // 转换后的输出地址
outvalues_instance: evalUATE;// 定义本地实例
END_VAR
静态变量(Static Variables)
因为某些数据要保留到下一个程序循环,所以选择FB块类型。有些静态变量在声明部分"VAR, END_VAR"中声明。
静态变量是本地变量,其值保留贯穿每个块处理过程。他们用来保留功能块的值,且存贮在实例数据块中。
初始化变量(Initializing Variables)
记住当块被初始化时(下载到CPU之后),在变量中键入初始值。功能块evalUATE的本地实例也在声明子域"VAR, END_VAR"中声明。其名字是以后调用和存取输出参数使用的。共享的实例ACQUIRE_DATA用来存贮数据。
语句部分的结构(Structure of the Statement Section)
ACQUIRE的语句部分分为三个子部分:
获取测量值:
如果输入参数"newval"与"oldval"不同,则读入一个新测量值到环形缓冲区。
启动排序和计算:
比较输入参数"resort"和"oldsort",发生改变时,通过调用evalUATE功能块启动排充和计算。
求取代码并准备输出:
按字读取代码。根据SIMATIC转换规则,意思是上开关组(字节0)包含输入字的高8位,下开关组(字节1)包含低8位。下图显示代码开关的位置。
计算地址(Calculating the Address)
下图显示如何计算地址:检测到取码开关(位15)一个边沿,输入字IW0的12至14位包含了读入的代码。用标准函数SHR右移并用AND屏蔽相应的位得到“地址”。
地址用来将数组元素(计算结果和对应测量值)写入输出参数。是均方根据,还是平方值决定于"funct_sel"。
检测到取码开关的一个边沿,是因为"newsel"和"oldsel"不同。
逻辑块的语句部分如下:
BEGIN
(*****************************************************************
第1部分:获取测量值。
如果"newval"值发生改变,则输入了测量值。MOD运算是用来实现测量值用的环形缓冲区。
******************************************************************)
IF newval <> oldval THEN
pointer := pointer MOD QUANTITY;
measvals[pointer] := measval_in;
pointer := pointer + 1;
END_IF;
oldval := newval;
(*****************************************************************
第2部分:启动排序和计算
如果"resort"发生改变,则启动对环形缓冲区的排序和运行对测量值的计算。
结果存贮在一个新的叫"calcbuffer"的数组里。
******************************************************************)
IF resort <> oldsort THEN
pointer := 0; //复位缓冲区指针
eval_instance(sortbuffer := measvals); //调用evalUATE
END_IF;
oldsort := resort;
resultbuffer := eval_instance.calcbuffer; //平方值和均方根
(*****************************************************************
第3部分:求代码值和准备输出
如果"newsel"发生改变,则计算用来输出的数组元素的寻址代码:屏蔽"selection"
的相应位并转换为整数。依据"funct_sel"开关的设置,选择"squareroot"或
"square"用于输出。
******************************************************************)
IF newsel <> oldsel THEN
address := WORD_TO_INT(SHR(IN := selection, N := 12) AND 16#0007);
END_IF;
oldsel := newsel;
IF funct_sel THEN
result_out := resultbuffer[address].square;
ELSE
result_out := resultbuffer[address].squareroot;
END_IF;
measval_out := measvals[address]; //Measured value display
END_FUNCTION_BLOCK