ST

·7 min read

ST语言概述

ST(结构化文本)是一种通用的高级文本语言,其语法类似于Pascal语言。 适用于包含数值分析或复杂算法的程序。 它可以在程序中,功能或功能块的主体中​​使用,以及用于描述SFC元素内的动作和转换。 根据IEC 61131-3,关键字必须以大写字母输入。 空格和制表符不影响语法;可以在任何地方使用它们。

ST中的表达式与Pascal中的表达式完全相同:

[变量] := [值];

它们的执行顺序是从右到左。 表达式由操作数和运算符组成。 操作数是文字,变量,结构化变量,结构化变量的组成部分,函数调用或直接地址。

数据类型

根据IEC 61131-3标准,ST语言支持全部必需的类型集,类似于经典编程语言。 整数类型: SINT(字符),USINT(无符号字符),INT(短整数),UINT(无符号整数),DINT(长整数),UDINT(无符号长整数),LINT(64位整数),ULINT(64位整数,无签字)。 有效类型为:REAL(浮点型),LREAL(双精度型)。 特殊类型BYTE,WORD,DWORD,LWORD分别是8位,16位,32位和64位长度的位串。 ST中没有位字段。 可以逐位直接访问位串。 例如:

a.3:= 1; (设置变量的第3位)

布尔类型BOOL可以为TRUE或FALSE。 在物理上,BOOL类型的变量可以对应一位。 字符串STRING是字符串,而不是数组。 可以使用标准运算符比较和复制字符串。 例如:

strA:= strB;

有一组用于处理字符串的标准函数(请参见附录2,"带有STRING类型的变量的字符串操作"一节)。

IEC标准中的特殊类型定义为持续时间(TIME),一天中的时间(TOD),日历日期(DATE)和时间点(DT)。

表3.1列出了与上述类型相对应的默认值。

表3.1-IEC 61131-3数据类型的默认值

|数据类型| 值| |-|-| |BOOL,SINT,INT,DINT,LINT |0| |USINT,UINT,UDINT,ULINT |0| |BYTE,WORD,DWORD,LWORD |0| |REAL| 0.0 |TIME| T#0S |DATE| D#0001-01-01 |TIME_OF_DAY| TOD#00:00 00 |DATE_AND_TIME| DT#0001-01-01-00:00:00 |STRING| ''(空字符串) 默认情况下,所有变量都初始化为零。 声明变量时,可以显式指定其他值。 例如:

str1:STRING:='Hello world';

在某些情况下,开发软件模块时,可以方便地使用类型概括。 一组数据类型的一般命名。 这些概括在表3.2中给出。

表3.2-IEC 61131-3数据类型概括

|ANY |||| |-|-|-|-| |ANY_BIT| ANY_NUM| ANY_DATE |TIME

STRING和其他数据类型 |BOOLBYTEWORDDWORDLWORD|ANY_INT| ANY_REAL |DATETIME_OF_DAYDATE_AND_TIME ||INTSINTDINTLINT|UINTUSINTUDINTULINT|REALLREAL

语言设计

ST语言构造包括:

  • 算术运算;
  • 逻辑(按位)操作;
  • 比较操作;
  • 赋值操作;
  • IF-ELSEIF-ELSE结构;
  • FOR循环
  • DO WHILE循环
  • REPAET UNTIL循环
  • CASE分支

编写算术表达式时,允许使用括号来表示计算顺序。 编写表达式时,允许使用变量(局部和全局)和常量。

算术运算

算术运算包括:

  • " +"-加法;
  • "-"-减法;
  • " *"-乘法;
  • " /"-除;
  • " Mod"是整数除法的余数。

表3.4中显示了表达式中运算的优先级(优先级越高,执行操作越早)。

逻辑(按位)操作 这些操作包括:

" OR"-逻辑(按位)加法; " AND"-逻辑(按位)乘法; " XOR"-逻辑(按位)"异或"; " NOT"-逻辑(按位)取反。 比较运算 支持以下比较操作:

" ="-比较是否相等; " <>"-不平等的比较; ">"-比较更多; "> =-比较不少; " <"-比较少; " <="-不再进行比较。 比较的结果总是使用BOOL类型的值。

赋值 为了指示赋值,使用了双符号":="。 表达式的左右部分必须包含相同类型的操作数(不提供自动类型转换)。 在表达式的左侧(接收侧)只能使用变量。 右侧可以包含表达式或常量。

表3.4显示了执行上述操作的优先级。

表3.4-操作优先级

|操作| 优先级| |-|-| |对照| 1 |加,减| 2 |乘法,除法| 3 |OR| 4 |与,异或| 5 |NOT| 6 |一元减| 7 |函数调用 |8

建设IF-ELSEIF-ELSE

使用大括号和方括号来描述某些语言构造很方便。 据信:

花括号中的表达式可以连续使用零次或多次。 方括号中的表达式是可选的。 IF-ELSEIF-ELSE构造具有以下格式:

IF <布尔表达式> THEN <语句列表>

[ELSEIF <布尔表达式> THEN <语句列表>]

[ELSE <声明列表>]

END_IF;

例如:

如果Var <> 0

然后变量:= 1

ELSEIF Var> 0

然后变量:= 0;

ELSE Var:= 10;

END_IF;

该设计允许嵌套,即 在一个IF内可以再有一个,依此类推。 例如:

如果Var> 10 THEN

如果Var <Var2 + 1

然后变量:= 10;

ELSE Var:= 0;

END_IF;

END_IF;

周期 用于设置具有固定迭代次数的循环。 设计格式如下:

FOR <控制变量>:= <表达式1>到<表达式2>

[BY ]做

<声明清单>

END_FOR;

指定循环条件时,假定<控制变量>,<表达式1> ... <表达式3>的类型为INT。 如果循环变量的值超过值,则循环将退出。 例如:

对于i:= 1到10乘2 DO

k:= k * 2;

END_FOR;

BY运算符指定循环变量的增量(在这种情况下,每次循环时,我将增加2)。 如果未指定BY运算符,则增量为1。例如:

对于i:= 1 TO k / 2 DO

var:= var + k;

k:= k-1;

END_FOR;

在循环内部,可以使用其他循环,IF和CASE语句。 EXIT语句可用于退出循环(任何类型)。 例如:

对于i:= 1到10乘2 DO

k:= k * 2;

如果k> 20 THEN

EXIT;

END_IF;

END_FOR;

注1:表达式 ... 是在进入循环之前计算的,因此,在这些表达式中的任何一个中更改变量的值都不会更改迭代次数。 例如:

01:k:= 10;

02:对于I:= 1 TO k / 2 DO

03:k:= 20;

04:END_FOR;

在第3行中,变量k被更改,但是该循环仍将仅执行五次。 注2:循环变量的值可以在循环体内改变,但是在下一次迭代开始时,将根据循环条件设置该变量的值。 例如:

01:对于我:= 1至5

02:我:= 55;

03:END_FOR;

在第一次通过时,I的值将等于1,然后在第2行中将其更改为55,但是在第二次通过时,I的值将等于2-根据循环条件的下一个值。

循环周期 它用于确定带有先决条件的循环。 循环将一直运行,直到WHILE子句中的表达式返回TRUE。 设计格式如下:

WHILE <布尔表达式> DO

<声明清单>

END_WHILE;

在每次迭代时检查的值。 如果表达式返回FALSE,则循环将结束。 例如:

k:= 10;

当k> 0时

i:= I + k;

k:= k –1;

END_WHILE;

在循环内部,可以使用其他循环,IF和CASE语句。 为了尽早终止循环,请使用EXIT运算符(请参见FOR循环说明中的示例)。

重复直到循环 它用于确定具有后置条件的循环。 当UNTIL子句中的表达式返回FALSE时,循环将结束。 换句话说:循环将执行直到满足UNTIL子句中的条件。 设计格式如下:

REPEAT

<声明清单>

UNTIL <布尔表达式>;

END_REPEAT;

例如:

k:= 10;

REPEAT

i:= i + k;

k:= k-1;

直到k = 0;

END_REPEAT;

在循环内部,可以使用其他循环,IF和CASE语句。 为了尽早终止循环,请使用EXIT运算符(请参见FOR循环说明中的示例)。

施工case 该设计用于组织从一系列值中进行选择。 设计格式如下:

case<表达式>

CASE_ELEMENT {CASE_ELEMENT}

[ELSE <声明列表>]

END_CASE;

CASE_ELEMENT是值列表,以逗号分隔。 列表项可以是整数或整数范围。 范围设置如下BEGIN_VAL .. END_VAL。

如果当前值不属于任何CASE_ELEMENT,则控制权将转移到ELSE子句。 如果未指定ELSE子句,则不会采取任何措施。

的值只能是整数。 例如:

01:CASE k OF

02:1:

03:k:= k * 10;

04:2..5:

05:k:= k * 5;

06:i:= 0;

07:6,9..20:

08:k:= k-1;

09:其他

10:k:= 0;

11:i:= 1;

12:END_CASE;

第4行包含一系列值。 如果k的值属于数字段[2,5],则将执行第5和第6行。

第7行使用值列表。 如果值k等于6或属于数字段[9,20],则将执行第8行。

如果k <1或6 <k <9或k> 20,则将执行第10行和第11行(在这种情况下,ELSE子句将起作用)。

指定值列表时,必须满足以下条件:

同一CASE中的一组值不应重叠; 指定值范围时,该范围的开始应小于其结束。 表3.5显示了CASE构造的正确和错误记录代码的示例。

为处理每种CASE情况而提供的操作可以使用循环,IF语句和CASE语句。

表3.5-CASE施工记录

记录不正确 正确记录 01:CASE k OF

02:1:

03:k:= k * 10;

04:2..5:

05:k:= k * 5;

06:i:= 0;

07:5,9..20:

08:k:= k-1;

09:其他

10:k:= 0;

11:i:= 1;

12:END_CASE;

第4行和第7行的范围相交

01:CASE k OF

02:1:

03:k:= k * 10;

04:2..5:

05:k:= k * 5;

06:i:= 0;

07:6,9..20:

08:k:= k-1;

09:其他

10:k:= 0;

11:i:= 1;

12:END_CASE;

01:CASE k OF

02:1:

03:k:= k * 10;

04:2..5:

05:k:= k * 5;

06:i:= 0;

07:6,20..9:

08:k:= k-1;

09:其他

10:k:= 0;

11:i:= 1;

12:END_CASE;

在第7行中,值的范围设置不正确。

01:CASE k OF

02:1:

03:k:= k * 10;

04:2..5:

05:k:= k * 5;

06:i:= 0;

07:6,9..20:

08:k:= k-1;

09:其他

10:k:= 0;

11:i:= 1;

12:END_CASE;

在ST上编写程序时,可以使用标准和用户定义的功能以及功能块。