step7 V5.x上的SCL

xiacuncun / 2025-02-21 / 原文

新建SCL块

  • 新建项目,选择SCL source:
  • 选择模板,FB/FC都行,这里选择FB模板:

把对应的FBxxx改成实际的FB编号
VAR TEMP是FB的临时变量;
VAR是FB的静态Static变量

  • 模板选择完成,可以选择参数模板(定义变量的IN/OUT/INOUT接口模板):

选择参数模板之后,可以看到多了VAR INPUT,VAR IN_OUT,VAR OUTPUT一类的宏,这明显对应了FB块的三类接口。

  • 实际项目中,还需要其他模板,也可以在Insert中择需选择。
  • 更改为实际的FB编号之后(如此处是FB1),点击编译,会发现生成了新的FB1。
  • 实际效果:

导入外部源文件

  • 导入源文件(如博图SCL源文件):
  • 导入之后的一些兼容性问题:

红色标记处都是有一些兼容性问题的,因为博图是用的符号访问,返回到Step7时,格式反而不对了,要改回fb编号才行。
ton_time,S7_Optimized_Access那些都是后期才支持的东西,放在老版本上明显不兼容。
step7 的 SCL 没有 #来表示局部变量,局部直接写符号名就行。
step7 的 指令系统不如博图的SCL丰富,比如TON其实是SFB4,使用的时候需要定义SFB4的背景DB或者使用多重背景DB的方法。
step7 的 SCL 调用FC或者FB的时候,IN管脚和IN_OUT管脚和书写习惯未变。但输出管脚有特殊的写法,需要注意。

导出成外部源文件

  • step7的SCL和STL以及LAD都可以被导出成外部源文件:
    • 先打开程序编辑器,选择生成源
    • 选择存放源的文件夹,给源文件取名字,然后点击OK
    • 选择需要生成源的块
    • 最后,进Sources文件夹中找到刚生成源的文件,右键导出即可

寻址方式

  • Step7 V5.x上的SCL可以混用绝对寻址符号寻址
//下面所有写法在编译的时候都可以通过
  DB1.D0.0 := TRUE; 
  DB1.DBX0.0 := TRUE; 
  DB1.DB2 := 16#ff; 
  DB1.DBB2 :=  16#ff; 
  QX0.0:=TRUE; 
  Q0.0:=TRUE; 
  QX0.1:=IX0.1;
  Q0.1:=I0.1;
  "TestDB".DB_VAR:=10;
  M0.0:="AlwaysTrue";   //M10.1 means "AlwaysTrue"
  PQB0:=16#FF; //访问物理I/O,不需要写成:P  
  • 绝对寻址格式说明:

  • 间接寻址格式说明:

批量寻址直接用QW[index_num]:= 16#FFFF,中括号中放的是绝对寻址数(不用像STL一样转成地址指针P#)。

建立UDT

  • 建立UDT需要在FUNCTION..END_FUNCTION或者FUNCTION_BLOCK..END_FUNCTION_BLOCK之外,demo如下:
  • 建立好如下格式并成功编译,系统会自动生成UDT100

AT的使用:

  • AT映射UDT实例,完成反序列化:

  • 用AT将数据序列化
  • 手搓ANY类型的结构,用AT映射:

此处的TEST1/TEST2有10个BYTE的长度,正是ANY数据类型的基本结构。
从数据结构也侧面说明了,ANY类型和IN_OUT类型不通用,不能把IN_OUT类型的变量放到ANY类型的管脚上去,博图能放是因为博图一般是用的VARIANT而不是ANY。

多重背景调用

  • 多重调用SFB4,注意输出管脚SFB_4_TON.QSFB4_TON.ET的写法。

管脚SFB_4_TON.QSFB4_TON.ET在括号外面,括号用隔开。输出变量M0.0Zeit写在程序的左边。
因为它不像博图有=>表示输出,所以产生了这种特殊的表示方法。
IN_OUT类型写在括号里面,和IN类型的表示一致。

  • 以下多重背景的定义声明方法都是合理且允许的:
VAR
    // Static Variables
    My_Ton_Timer_1:SFB4;
    My_Ton_Timer_2:TON;
    My_Ton_Timer_3,My_Ton_Timer_4,My_Ton_Timer_5:SFB4;

END_VAR
  • 区别于博图,数组不支持以下定义方法:
VAR
//不支持的定义
    My_Ton_Timer_Arr:ARRAY[0..31] OF SFB4;

END_VAR

报错内容

  • 数组里面使用不了TON的退而求其次的方法
    • 数组支持STRUCT结构,可以用STRUCT把指令的接口定义出来
    • 数组不支持fb 多重背景类型,这是Step7 V5.x避免不了的问题,退而求其次:尽量选择不生成背景DB的指令,比如S_ODT这类指令或者使用SFC这类系统库。
//Code来自于Step7 V5.x 帮助文档
//Example of an absolute call:
CurrTime:=S_ODT (T_NO:=T10,
                 S:=TRUE,
                 TV:=T#1s,
                 R:=FALSE,
                 BI:=biVal,
                 Q:=actFlag);

//Example of a dynamic call: In each iteration of a 
//FOR loop, a different timer function is called:
FUNCTION_BLOCK TIME
VAR_INPUT
 MY_TIMER: ARRAY [1..4] of STRUCT
              T_NO: INT;
              TV : WORD;
             END_STRUCT;
.
.
END_VAR
.
.
FOR I:= 1 TO 4 DO
CurrTime:= S_ODT(T_NO:=MY_TIMER[I].T_NO, S:=true, TV:= MY_TIMER[I].TV);
END_FOR;

//Example of a dynamic call using a variable of the 
//TIMER data type:
FUNCTION_BLOCK TIMER
VAR_INPUT
 mytimer:TIMER;
END_VAR
.
.
CurrTime:=S_ODT (T_NO:=mytimer,.....);

绑定SCL FB源程序的背景DB

  • 当一个功能块以 S7-SCL 源程序方式生成时,建议在源程序中直接生成背景数据块。如果不在相应的源程序中声明背景数据块,则每当接口(包含在 S7-SCL 的源程序)改变后,背景数据块都要重新生成。否则,在背景数据块和功能块之间将出现冲突。反之,如果背景数据块在源程序中直接生成,则不需要这些步骤。当执行命令“File > Compile”时,背景数据块将被自动生成。这样,功能块的改变将被直接传送到背景数据块中。这也防止了数据冲突的发生。

DATA_BLOCK..END_DATA_BLOCK用来绑定FB22生成的背景DB为DB22,这样可以在编译源文件的时候就把DB22给编译了。缺点是FB22的多次调用变得不太现实,仅适用于仅需分配一个背景数据块给功能块的情况。