Skip to main content

变量: VAR_GENERIC CONSTANT

通用常量变量

概述

这个 VAR_GENERIC 扩展为以下内容提供支持 编译时的泛型常量 在功能块中。这允许创建灵活且可重复使用的功能块,这些功能块可以适应不同的配置(例如,缓冲区大小或固定范围) 没有 依赖于动态内存分配。

此功能对于管理数组或其他内存结构的功能块特别有用。此外,它允许进行性能优化的设计,这些设计是类型安全的,并且在编译时可以完全解析

泛型常量是中的一个变量 VAR_GENERIC CONSTANT 功能块的范围。该变量仅在声明函数块实例时定义。

允许在方法中使用泛型常量。这在以下情况下可能特别有用 VAR_IN_OUT 或者 VAR_IN_OUT CONSTANT 范围。

类型声明的语法

声明

带有泛型常量的函数块类型声明的语法

FUNCTION_BLOCK <function block name>
VAR_GENERIC CONSTANT
    <generic constant name> : <integer data type> := <initial value> ; //Initial value will be overwritten
END_VAR

<function block name>

功能块的名称

VAR_GENERIC CONSTANT

END_VAR

泛型常量的范围

你可以在中声明任意数量的泛型常量 VAR_GENERIC CONSTANT 范围。

<generic constant name>

泛型常量的变量名

: <integer data type>

构造哪些类型的泛型常量。

允许使用整数数据类型或整数数据类型的子范围。

示例:

maxlen1 : INT := 4;

maxlen2 : INT(5..10) := 5;

:= <initial value>

可选

初始化

重要

编译检查才需要初始值。在运行时,该值被覆盖

示例:

FUNCTION BLOCK FB
VAR_GENERIC CONSTANT
    size : INT;
END_VAR
VAR
    buffer : ARRAY[0..size] OF BYTE;
END_VAR

举例说明

具有泛型常量的函数模块可以显式实例化为表达式,也可以使用文字参数传递隐式实例化。

以下内容适用:

  • 参数传递的部分是 VAR_GENERIC CONSTANT-区域,用方括号括起来。

  • 通用函数模块必须具有以下参数 全部 可以实例化泛型变量。参数传输必须完成。不允许部分输入,这会导致错误。

  • 要么所有参数都是显式指定的,要么全部隐式提供。不允许混合使用明确或隐含的信息

    • 隐含的

      如果为多个泛型变量传递参数,则所需值必须按其存在顺序作为文字传递 VAR_GENERIC CONSTANT-范围已声明,用逗号分隔在一起。

      <5,10>
    • 用名字明确表示

      如果为多个泛型变量传递了参数,则每个所需的参数都必须作为带括号的表达式传入 更自由 顺序用逗号分隔。像往常一样,表达式用圆括号包围

      该表达式在赋值运算符之后分配命名的泛型常量 := 文字、变量或表达式。将这种明确的参数传递用圆括号括起来很重要

      <(Array2Size := 10), (Array1Size := 5)>

      优点是参数传递易于阅读,因此在更改后易于理解且易于维护。

  • 如果已经声明了更多变量,则必须传递更多参数。它们以赋值运算符命名 := 由串在一起的圆括号包围。

91. 示例

功能模块 FB 使用泛型常量

FUNCTION_BLOCK FB
VAR_GENERIC CONSTANT
    Array1Size : INT := 0;
    Array2Size : INT := 0;
END_VAR
VAR_INPUT
    MyArray1 : ARRAY[0..Array1Size-1] OF REAL;
    MyArray2 : ARRAY[0..Array2Size-1] OF REAL;
END_VAR
VAR
    SomeOtherParameter : INT;
END_VAR


92. 示例

实例化函数模块 FB 通过简单的参数传输。

PROGRAM PLC_PRG
VAR
    MyFB1 : FB<5,10> := (SomeOtherParameter:=20);
END_VAR

VAR
    liArray1Size: LINT;
END_VAR
liArray1Size := UPPER_BOUND(MyFB1.MyArray1,1) + 1;


93. 示例

具有显式参数传递的 myFB2 函数模块实例

PROGRAM PLC_PRG
VAR
    MyFB1 : FB<5,10> := (SomeOtherParameter:=20);
    MyFB2 : FB<(Array2Size:=10), (Array1Size:=5)> := (SomeOtherParameter := 10);
END_VAR

VAR
    Array1Size, Array2Size : LINT;
END_VAR
Array1Size := UPPER_BOUND(MyFB1.MyArray1,1) + 1;
Array2Size := UPPER_BOUND(MyFB1.MyArray2,1) + 1;


使用泛型常量进行继承

泛型常量也可以通过继承传递给基本功能块。

在功能块中使用常量

该常量可以像任何其他常量一样在函数块中使用(例如,在数组或字符串声明中)。它可以用于功能块的方法、属性或操作,但不能从外部访问。这意味着它的行为就像一个私有变量

预编译检查

由于泛型常量的最终值在函数块中不可用,因此预编译检查受到限制。可以按如下方式定义初始化值:

FUNCTION_BLOCK FB
VAR_GENERIC CONSTANT  
    size : INT := 1;
END_VAR
VAR 
   buffer : ARRAY[0..size] OF BYTE;
END_VAR

此初始化值(示例中的值 1)用于函数块内的预编译检查,但它没有任何其他作用。

例子

94. 使用多个泛型常量的示例
FUNCTION_BLOCK FB_Pou
VAR_GENERIC CONSTANT
    lnstring : DINT := 10;
    numstring : DINT := 100;
END_VAR
VAR
    arraystring : ARRAY[0..numstring-1] OF STRING(lnstring);
END_VAR
PROGRAM PLC_PRG
VAR
    fbPou : FB_Pou<100, 1000>;
END_VAR


95. 示例:子作用域类型的通用常量

子范围类型可用作泛型参数,以指定编译器检查的允许值范围。

FUNCTION_BLOCK FB_SrString 
VAR_GENERIC CONSTANT
    maxlen2 : INT(5..10) := 5;    //subrange data type
END_VAR
VAR
    arrTest : ARRAY[0..maxlen-1] OF BYTE;
END_VAR
;
PROGRAM SrMain
VAR CONSTANT
    cconst: INT(5..10) := 5;
END_VAR
VAR    
    fbMyString1 : FB_SrString<5>;
    fbMyString2 : FB_SrString<(2 * cconst)>;
    fbMyString3 : FB_SrcString<123>;
    // ERROR: An error is reported here because 123 is not within the value range 5..10.
    arrMyString : ARRAY [0..5] OF FB_SrString<6>;
END_VAR


96. 示例:带有可参数化数组变量的通用功能块

以下代码演示如何定义可以处理任意长度数组的函数块。该功能块具有通用但长度恒定的数组。“常量” 意味着,尽管每个函数块实例的数组长度各不相同,但在对象的生命周期内它是恒定的。

例如,对于想要实现通用库 POU 的库程序员来说,这种结构是有益的。

FUNCTION_BLOCK FB_MyString 
VAR_GENERIC CONSTANT
    maxlen : UDINT := 1;
END_VAR
VAR
    test : ARRAY[0..maxlen-1] OF BYTE;
END_VAR
PROGRAM PLC_PRG
VAR CONSTANT
    cconst: DINT := 1000;
END_VAR
VAR    
    fbMyString1 : FB_MyString<100>;
    fbMyString2 : FB_MyString<(2 * cconst)>;   
    arrMyString : ARRAY[0..5] OF FB_MyString<6>;    
END_VAR


遗产

函数模块可以从具有泛型常量的基本函数模块中派生 (EXTENDS) 继承。继承函数模块需要自己的泛型常量。然后可以从外部转移特定的值。

语法:

FUNCTION_BLOCK <function block name> 
VAR_GENERIC CONSTANT        
    <generic constant name> : <integer data type> ; 
END_VAR 
EXTENDS <function block base> < <generic constant name> >

具有泛型常量的函数模块可以实现接口 (IMPLEMENTS)。该接口声明了一个属性PROPERTY) 它可以用来从外部访问指定的值。接口本身不得声明泛型常量或局部变量。接口没有实现。

语法:

FUNCTION_BLOCK <function block name>
VAR_GENERIC CONSTANT
    <generic constant name> : <integer data type> ;
END_VAR
IMPLEMENTS <interface name>

重要

编码时,确保先插入泛型常量的声明,然后插入 EXTENDSIMPLEMENTS。这需要一些时间来适应,但原因是泛型常量也可以与基类一起使用

97. 示例

的定义 IString 通用功能块的接口。

强烈建议为通用功能块定义接口。该接口应允许在不了解泛型常量的情况下使用泛型功能块实例

这个 Length 属性允许访问通用常量。

INTERFACE IString 
METHOD Append : BOOL 
VAR_INPUT     
    strAppend : IString; 
END_VAR 

METHOD Assign : BOOL
VAR_INPUT     
    stringIn : STRING; 
END_VAR 

METHOD ToString : STRING
VAR_INPUT 
END_VAR 

PROPERTY Length : DINT

功能块的声明 FB_MyString 使用通用常量 maxlen

FUNCTION_BLOCK FB_MyString 
VAR_GENERIC CONSTANT        
    maxlen : UDINT; 
END_VAR 
IMPLEMENTS IString 

功能块 FB_LongString 是指定功能块的扩展 FB_MyString

FUNCTION_BLOCK FB_LongString EXTENDS FB_MyString<1000>

功能块的声明 FB_MySpecialString 使用通用常量 maxlen2 作为指定功能块的扩展 FB_MyString。该功能块由该方法扩展 METH_ToLatin

FUNCTION_BLOCK FB_MySpecialString 
VAR_GENERIC CONSTANT        
    maxlen2 : UDINT:= 1; 
END_VAR 
EXTENDS FB_MyString<maxlen2>
METHOD METH_ToLatin : STRING
VAR_INPUT
END_VAR

使用特定常量对功能块进行实例化

PROGRAM PLC_PRG 
VAR CONSTANT     
    cconst: DINT := 1000; 
END_VAR
VAR     
    string1 : FB_MyString<100>;
    string2 : FB_MyString<(2 * cconst)>;
    derived1 : FB_LongString;
    derived2 : FB_MySpecialString<100>;
END_VAR 

通话

string1.METH_Assign ('Welt'); 
string2.METH_Assign ('Hallo '); 
string2.METH_Append(string1); 
derived2.METH_ToLatin('Hello World');