在我的 61131 程序中,我有需要在不同程序部分之间共享的对象/信息。什么是最佳实践,需要共享的对象应该是 PRG POU 中的 VAR 还是 GVL 中的全局?
从“高级”编程中,我对全局数据持怀疑态度,但这可能是必要的吗?
感谢 61131 中有关最佳实践架构的任何意见。
在我的 61131 程序中,我有需要在不同程序部分之间共享的对象/信息。什么是最佳实践,需要共享的对象应该是 PRG POU 中的 VAR 还是 GVL 中的全局?
从“高级”编程中,我对全局数据持怀疑态度,但这可能是必要的吗?
感谢 61131 中有关最佳实践架构的任何意见。
我会创建一个STRUCT
全局变量,其中包含一个组件的所有全局数据,例如一个名为的结构ST_CoolingSystem
,它具有处理冷却系统等程序所需的全局数据。
其他方法是PROGRAM
POU 的方法/属性。它当然需要 Codesys 3 或类似版本。这样,您可以为程序或功能块本身的变量/结构创建一个 getter,例如PRG_CoolingSystem.GetData()
返回结构或对它的引用。
更新:
使用 OOP 功能的一种方法是添加一个属性,该属性返回对数据结构的引用。注意:这适用于 TwinCAT 3,也应该适用于具有新功能的其他 IEC 61131-3 系统。
假设我们有一个结构ST_Cooling
TYPE ST_Cooling :
STRUCT
//Commands
RunCooling : REAL;
TemperatureSetpoint : REAL;
//Status
MotorRunning : BOOL;
CurrentTemperature : REAL;
END_STRUCT
END_TYPE
我们还有一个功能块FB_Cooling
FUNCTION_BLOCK FB_Cooling
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
MotorRunCmd AT %Q* : BOOL;
Data_ : ST_Cooling; //"Private" of data struct
END_VAR
IF Data_.RunCooling THEN
//Do something
MotorRunCmd := TRUE;
//Update status
Data_.MotorRunning := TRUE;
ELSE
//Do something
MotorRunCmd := FALSE;
//Update status
data_.MotorRunning := FALSE;
END_IF
我们可以添加一个PROPERTY
可FB_Cooling
用于检索结构并读取和编辑它的对象。因为它返回一个引用(如指针),我们可以删除该属性的 Set 方法。
物业类型:
PROPERTY Data : REFERENCE TO ST_Cooling
添加PROPERTY的Get()的代码:
//FB_Cooling.Data (Get)
//Return reference to the data struct
Data REF= Data_;
现在可以从可以访问功能块实例的任何地方读取和编辑数据。
PROGRAM PRG_Test
VAR
CoolingSystem : FB_Cooling;
END_VAR
//This is how we read
IF CoolingSystem.Data.CurrentTemperature > 40.0 THEN
//This is how to write (because it is a reference)
CoolingSystem.Data.RunCooling := TRUE;
END_IF
//Run the block
CoolingSystem();
也许这张图片也解释了它在项目中的样子。查看 Data 属性,它是自动添加的 Get。
这只是一个例子,一个真实的系统会有更多的代码和数据。可能(应该?)还有更多的结构,每个用于命令、状态和参数。但这只是我的意见:)
VAR
中的APRG_POU
相当于标准 OOP 类型语言中的局部变量。如果你想要一个可以在不同 POU 中使用的对象实例/信息,那么 GVL(全局变量列表)就是你想要放置它的地方。但是如果一个变量只在 1 中使用,POU
那么你会想要VAR
在 that 中设置 this a POU
。从“最佳实践”的角度来看,您通常总是希望将全局变量限制为尽可能小的数量,并尽可能使用更多VAR
的局部变量POU
。