CoDeSys一些基本概念,欢迎指教,仅供参考
程序:程序可以被其他的POU调用,但函数中不可以调用程序,程序也没有实例。程序被某POU调用后其值会发生改变,这些改变将保持,直到下一次被该POU调用的时候,这期间被其他POU调用对该POU对该程序的调用没有影响。
程序可以在程序名后面的圆括号中给各个参数赋值。对于输入参数,用":="赋值,就像在变量声明部分初始化变量一样。对于输出参数,则使用"=>"。
函数:函数只有一个返回值,但可以有多个输出。
函数每次调用后不保存内部状态信息变量的值,也就是说,如果调用时给的参数一样,返回值一定一样,但如果函数中包含全局变量,则对返回值就会有影响,所以函数内可能最好不会要包含全局变量和地址。
功能块:可提供一个或多个输出;不论被哪一个POU调用,其输出变量值和内部的值均会发生改变。
可实例化,一般通过功能块的实例来调用该功能块。
注意:
从功能块实例的外部,只能访问功能块的输入和输出参数,不能访问功能块的内部变量。
声明为某个POU局部变量的功能块实例,仅可以被该POU调用;声明为全局变量的功能块实例,各POU都可以调用。
可以在调用功能块时给功能块的参数赋值。
在下面的例子中,调用定时器功能块CMD_TMR的同时,为其参数IN和PT赋值,功能块的运算结果Q保存在变量A中。
CMD_TMR(IN := %IX5, PT := 300);
A:=CMD_TMR.Q
请注意,功能块的输入输出参数(VAR_IN_OUT)是通过指针进行传递的。
一个功能块实例可以作为另外一个功能块或函数的输入参数。
在SFC功能块中,只能进行逐步调用。
功能块的扩展(不支持一个子功能块继承多个父功能块):
定义功能块fbA:
FUNCTION_BLOCK fbA
VAR_INPUT
x:int;
....
定义功能块fbB:
FUNCTION_BLOCK fbB EXTENDS fbA
VAR_INPUT
ivar:int;
....
上面的扩展含义如下:
功能块fbB包含功能块fbA中所有的变量和方法,在使用功能块fbA的地方都可以用fbB代替。
在功能块fbB中可以重写fbA中原有的方法。即可以在fbB中重新声明一个fbA中已有的方法,它的名称、输入、输出和fbA中的原有方法一样。
fbB中不允许使用与fbA中同样名称的功能块变量。这种情况下,编译器会报错。
使用功能块fbB时,可以直接使用fbA中的变量和方法,加上关键字“SUPER”即可(SUPER^.<method>)。
接口:首先定义一个接口,接口中包含若干方法,比如I1接口中包含方法Method1。
然后需要在功能块中实现该接口。
例如,功能块A实现了接口I1:
FUNCTION_BLOCK A IMPLEMENTS I1
当功能块A添加到对象树中时,I1中的"Method1"方法会自动出现在对应的功能块下面,我们所需要做的,就是将该方法所实现的功能补充上。
在调用该接口内的方法前,必须先给该接口型变量赋值,将一个实现了该接口的功能块实例赋给它。例如:
l_i := A_instance;
A_instance是功能块A的一个实例。
DUT:
结构体可以扩展,在创建时可以指明其为某个已有结构体DUT的扩展。
方法:在接口中可以定义诸多方法,然后在功能块声明实现该接口,并实现该接口的方法。
方法中的所有数据都是临时性的,并且只有在方法执行的时候才有效(这些数据都存储在栈中)。
在功能块内对方法的实现代码中,可以定义局部变量。
您可以使用标识符“THIS”来直接引用默认的功能块实例。注意,如果功能块内有和方法中同名的局部变量,那么引用这个变量名时会优先使用功能块内的局部变量。所以上例中的语句“THIS^.x”,并不是功能块内方法的输入参数x,而是功能块的局部变量x。
功能块中的VAR_IN_OUT或者VAR_TEMP变量不能在方法中访问。
在接口中定义的方法中只可以包含输入型、输出型和输入输出型参数,不允许有实现部分。
与函数类似,方法也可以有附加的输出参数。这些输出参数必须在方法调用的时候赋值。
属性:“属性”也是一种对象,可以通过右键菜单中的“添加对象/属性”命令是插入到对象树中的程序或者功能块中。在添加属性对话框中,您需要指定它的返回类型和实现语言。
与函数和方法相比,“属性”可以有附加的局部变量,但是不允许有附加的输入或输出参数。
动作:动作与其所属的功能块或程序的数据一起工作,使用这个功能块或程序的输入/输出变量和局部变量,没有自己的变量声明。
调用动作:
调用动作的格式为
<Program_name>.<Action_name>
或
<Instance_name>.<Action_name>
如果需要在本身的功能块中调用动作,也即是在动作所属的程序或者功能块中,只需使用动作的名称即可。
页:
[1]