SCL(Structured Control Language,结构化控制语言)是一种基于 PASCAL 的高级编程语言。这种语言基于标准 DIN EN 61131-3(国际标准为 IEC 1131-3)。
根据该标准,可对用于可编程逻辑控制器的编程语言进行标准化。SCL 编程语言实现了该标准中定义的 ST 语言 (结构化文本) 的 PLCopen 初级水平。
S7-1200从V2.2版本开始支持SCL语言。
语言元素
SCL 除了包含 PLC 的典型元素(例如,输入、输出、定时器或存储器位)外,还包含高级编程语言。
表达式
赋值运算
运算符
程序控制语句
SCL 提供了简便的指令进行程序控制。例如,创建程序分支、循环或跳转。
应用
因此,SCL 尤其适用于下列应用领域:
数据管理
过程优化
配方管理
数学计算 / 统计任务
表达式
说明:表达式将在程序运行期间进行运算,然后返回一个值。一个表达式由操作数(如常数、变量或函数调用)和与之搭配的操作符(如 *、/、+ 或 -)组成。通过运算符可以将表达式连接在一起或相互嵌套。
运算顺序
表达式将按照下面因素定义的特定顺序进行运算:
相关运算符的优先级,优先级数越小越优先
同等优先级运算符的运算顺序按照从左到右的顺序
赋值运算的计算按照从右到左的顺序进行
括号优先级最高
表达式类型
不同的运算符,分别可使用以下不同类型的表达式:
算术表达式
关系表达式
逻辑表达式
算数表达式
说明:算术表达式既可以是一个数字值,也可以是由带有算术运算符的两个值或表达式组合而成。
算术运算符可以处理当前 CPU 所支持的各种数据类型。如果在该运算中有 2 个操作数,那么可根据以下条件来确定结果的数据类型:
如果这 2 个操作数均为有符号的整数,但长度不同,那么结果将采用长度较长的那个整数数据类型(例如,Int + DInt = DInt)。
如果这 2 个操作数均为无符号整数,但长度不同,那么结果将采用长度较长的那个整数数据类型(例如,USInt + UDInt = UDInt)。
如果一个操作数为有符号整数,另一个为无符号整数,那么结果将采用另一个长度较大的有符号数据类型(其包含此无符号整数)(例如,SInt + USInt = Int)
如果一个操作数为整数,另一个为浮点数,那么结果将采用浮点数的数据类型(例如,Int + Real = Real)。
如果 2 个操作数均为浮点数,但长度不同,结果将采用长度较长的那个浮点数的数据类型(例如,Real + LReal = LReal)。
对于操作数为"Time"和"日期和时间"数据类型组,运算结果的数据类型请参见表1。
算术表达式的数据类型
表1列出了在算术表达式中可使用的数据类型:
运算 | 运算符 | 优先级 | 第一个操作数 | 第二个操作数 | 结果 |
---|---|---|---|---|---|
乘方 | ** | 2 | 整数/浮点数 | 整数/浮点数 | 浮点数 |
正号 | + | 3 | 整数/浮点数 | - | 整数/浮点数 |
Time | Time | ||||
负号 | - | 整数/浮点数 | - | 整数/浮点数 | |
Time | Time | ||||
乘法 | * | 4 | 整数/浮点数 | 整数/浮点数 | 整数/浮点数 |
Time | 整数 | Time | |||
除法 | / | 整数/浮点数 | 整数/浮点数(≠0) | 整数/浮点数 | |
Time | 整数 | Time | |||
取模 | MOD | 整数 | 整数 | 整数 | |
加法 | + | 5 | 整数/浮点数 | 整数/浮点数 | 整数/浮点数 |
Time | Time | Time | |||
Time | DInt | Time | |||
TOD | Time | TOD | |||
TOD | DInt | TOD | |||
Date | TOD | DTL | |||
DTL | Time | DTL | |||
减法 | - | 整数/浮点数 | 整数/浮点数 | 整数/浮点数 | |
Time | Time | Time | |||
Time | DInt | Time | |||
TOD | Time | TOD | |||
TOD | DInt | TOD | |||
TOD | TOD | Time | |||
Date | Date | Time | |||
DTL | Time | DTL | |||
DTL | DTL | Time |
示例
以下为一些算术表达式的示例:
"MyTag1":= "MyTag2" * "MyTag3";
关系表达式
说明:关系表达式将两个操作数的值或数据类型进行比较,然后得到一个布尔值。如果比较结果为真,则结果为 TRUE,否则为 FALSE。
关系运算符可以处理当前 CPU 所支持的各种数据类型。结果的数据类型始终为 Bool。
编写关系表达式时,请注意以下规则:
以下数据类型组中的所有变量都可以进行比较:
整数/浮点数
位、位序列
字符串
对于以下数据类型,只能比较相同类型的变量:
TIME
日期和时间
UDT
Array
Struct
Variant
String 比较是对以 Windows 字符集编码的字符进行比较;而 WSting比较则是对 UTF-16 编码的字符进行比较。在比较过程中,将比较变量的长度及各字符对应的数值。
Array 比较需要数组维度、数组元素数据类型与数量完全相同
UDT、Array、Struct、Variant等进行的比较只能使用S7-1200 V4.2及其以上的版本。
关系表达式的数据类型
表2列出了在关系表达式中可使用的数据类型/数据类型组:
运算 | 运算符 | 优先级 | 第一个操作数 | 第二个操作数 | 结果 |
---|---|---|---|---|---|
小于、小于等于、大于、大于等于 | <、<=、>、>= | 6 | 整数/浮点数 | 整数/浮点数 | Bool |
位序列 | 位序列 | Bool | |||
字符串 | 字符串 | Bool | |||
Time | Time | Bool | |||
日期和时间 | 日期和时间 | Bool | |||
等于、不等于 | ==、<> | 7 | 整数/浮点数 | 整数/浮点数 | Bool |
位序列 | 位序列 | Bool | |||
字符串 | 字符串 | Bool | |||
Time | Time | Bool | |||
日期和时间 | 日期和时间 | Bool | |||
Variant | 任意数据类型 | Bool | |||
UDT | UDT | Bool | |||
Array | Array | Bool | |||
Struct | Struct | Bool |
示例
以下举例说明了一个关系表达式:
IF a > b THEN c:= a;
IF A > 20 AND B < 20 THEN C:= TRUE;
IF A<>(B AND C) THEN C:= FALSE;
逻辑表达式
说明:逻辑表达式由两个操作数和逻辑运算符(AND、OR 或 XOR)或取反操作数 (NOT) 组成。
逻辑运算符可以处理当前 CPU 所支持的各种数据类型。如果两个操作数都是 Bool 数据类型,则逻辑表达式的结果也为 Bool数据类型。如果两个操作数中至少有一个是位序列,则结果也为位序列而且结果是由最高操作数的类型决定。例如,当逻辑表达式的两个操作数分别是 Byte 类型和 Word 类型时,结果为 Word类型。
逻辑表达式中一个操作数为 Bool类型而另一个为位序列时,必须先将 Bool类型的操作数显式转换为位序列类型。
逻辑表达式的数据类型
下表列出了逻辑表达式中可使用的数据类型:
运算 | 运算符 | 优先级 | 第一个操作数 | 第二个操作数 | 结果 |
---|---|---|---|---|---|
取反 | NOT | 3 | Bool | - | Bool |
求反码 | 位序列 | - | 位序列 | ||
与 | AND、& | 8 | Bool | Bool | Bool |
位序列 | 位序列 | 位序列 | |||
异或 | XOR | 9 | Bool | Bool | Bool |
位序列 | 位序列 | 位序列 | |||
或 | OR | 10 | Bool | Bool | Bool |
位序列 | 位序列 | 位序列 |
示例
以下为一个逻辑表达式的示例:
IF "MyTag1" AND NOT "MyTag2" THEN c := a;
MyTag := A OR B;
赋值运算
定义:通过赋值运算,可以将一个表达式的值分配给一个变量。赋值表达式的左侧为变量,右侧为表达式的值。
函数名称也可以作为表达式。赋值运算将调用该函数,并返回其函数值,赋给左侧的变量。
赋值运算的数据类型取决于左边变量的数据类型。右边表达式的数据类型必须与该数据类型一致。
赋值运算的计算按照从右到左的顺序进行。
可通过以下方式编程赋值运算:
单赋值运算:执行单赋值运算时,仅将一个表达式或变量分配给单个变量:
示例:a := b;
多赋值运算:执行多赋值运算时,一个指令中可执行多个赋值运算。
示例:a := b := c;
此时,将执行以下操作:
b := c;
a := b;
组合赋值运算:执行组合赋值运算时,可在赋值运算中组合使用操作符"+"、"-"、"*"和"/":
示例:a += b;
此时,将执行以下操作:
a := a + b;
也可多次组合赋值运算:
a += b += c *= d;
此时,将按以下顺序执行赋值运算:
c := c * d;
b := b + c;
a := a + b;
示例
下表举例说明了单赋值运算的操作:
"MyTag1" := "MyTag2"; | (* 变量赋值 *) |
"MyTag1" := "MyTag2" * "MyTag3"; | (* 表达式赋值 *) |
"MyTag" := "MyFC"(); | (* 调用一个函数,并将函数值赋给 "MyTag" 变量 *) |
#MyStruct.MyStructElement := "MyTag"; | (* 将一个变量赋值给一个结构元素 *) |
#MyArray[2] := "MyTag"; | (* 将一个变量赋值给一个 ARRAY 元素 *) |
"MyTag" := #MyArray[1,4]; | (* 将一个 ARRAY 元素赋值给一个变量 *) |
#MyString[2] := #MyOtherString[5]; | (* 将一个 STRING 元素赋给另一个 STRING 元素 *) |
下表举例说明了多赋值运算的操作:
"MyTag1" := "MyTag2" := "MyTag3"; | (* 变量赋值 *) |
"MyTag1" := "MyTag2" := "MyTag3" * "MyTag4"; | (* 表达式赋值 *) |
"MyTag1" := "MyTag2" := "MyTag3 := "MyFC"(); | (* 调用一个函数,并将函数值赋值给变量 "MyTag1"、"MyTag1" 和 "MyTag1" *) |
#MyStruct.MyStructElement1 := #MyStruct.MyStructElement2 := "MyTag"; | (* 将一个变量赋值给两个结构元素 *) |
#MyArray[2] := #MyArray[32] := "MyTag"; | (* 将一个变量赋值给两个数组元素 *) |
"MyTag1" := "MyTag2" := #MyArray[1,4]; | (* 将一个数组元素赋值给两个变量 *) |
#MyString[2] := #MyString[3]:= #MyOtherString[5]; | ICal-align:middle;padding-t |