1.如下的程序实现了SFC20的部分功能,可以作为Any使用的参考。
FUNCTION FC 1 : VOID
TITLE =
VERSION : 0.1
VAR_INPUT
SRCBLK : ANY ;
END_VAR
VAR_OUTPUT
RETVAL : INT ;
DSTBLK : ANY ;
END_VAR
VAR_TEMP
LOOP : INT ;
BLOCK_NO_DB : WORD ;
BLOCK_NO_DI : WORD ;
SRC_ADD : DWORD ;
DST_ADD : DWORD ;
END_VAR
BEGIN
NETWORK
TITLE =
L P##SRCBLK; //读取输入any的首地址
LAR1 ; //装载到ar1
L P##DSTBLK; //读取输出any的首地址
LAR2 ; //装载到ar2
L W [AR1,P#4.0]; //打开DB块
T #BLOCK_NO_DB;
L W [AR2,P#4.0]; //打开DI块
T #BLOCK_NO_DI;
OPN DB [#BLOCK_NO_DB]; //打开DB块
OPN DI [#BLOCK_NO_DI]; //打开DI块
L D [AR1,P#6.0];
T #SRC_ADD; //读取地址
L D [AR2,P#6.0];
T #DST_ADD; //读取地址
L W [AR1,P#2.0]; //读取循环次数
_001: T #LOOP;
L DBB [#SRC_ADD];
T DIB [#DST_ADD]; //赋值
//地址偏移1个字节
L P#1.0;
L #SRC_ADD;
+D ;
T #SRC_ADD;
L P#1.0;
L #DST_ADD;
+D ;
T #DST_ADD;
L #LOOP; //循环
LOOP _001;
END_FUNCTION
2.当FC 或FB的输入参数类型为:BLOCK_DB, TIMER或者 COUNTER,如何确定其编号?
例1 :FB 块
FB1 变量声明中定义了“ Timer” 类型的变量“ Time_1” ,在 FB2 中调用 FB1,将定时器“T5”传递给变量“ Time_1”。如图 01 所示程序代码中数值 5 表示“T5”。
图 01 FB中确定定时器编号
在使用多重实例时,需要在图 01 所示程序中增加以下代码:
TAR2 //多重实例偏移地址
LAR1 P##Time_1
+AR1 //多重实例偏移地址与当前地址相加
L W[AR1,P#0.0]
T MW0
例 2 FC
FC1 变量声明中定义了“ Timer” 类型的变量“ Time_1” ,在 FC2 中调用 FC1,将定时器“T8”传递给变量“ Time_1”。如图 02 所示程序代码中数值 8 表示“T8”。
图 02 FC中确定定时器编号
“BLOCK_DB”类型参数在调用 FC 时不可以直接传送给 FC 。如果在调用功能时试图使用此参数类型,将产生如下的错误消息: “非法的参数传输<参数名>” 。“BLOCK_DB”类型参数仅在 FB 被调用(从一个 FB 或 FC 中)时可被传送。 “BLOCK_DB”类型参数不可以在 FC 被调用(从一个 FB 或 FC 中)时可被传送。
相关详细信息可参考 STEP7 在线帮助中“合法的传输参数类型”。
然而,如果希望将 BLOCK_DB 参数类型传送给 FC, DB 块的编号可以通过基本数据类型(例如 WORD)传送。在下面的例子中,FB100 拥有一个“BLOCK_DB” 的输入参数类型。为了在调用 FC101 时将参数传送给它,“BLOCK_DB”中的 DB 块编号被传送给 WORD 临时变量(DB_No)。当 FC 被调用,数据块序号以一个 WORD 参数类型替代 BLOCK_DB 参数类型。
图 03 FB中确定Block_DB编号
如果 FB 的接口参数能被定义成 WORD 参数类型来传送 DB 块编号,当 FC 被调用时,此参数可以被直接传送给 FC。
图 04 FC中确定DB编号