TwinCAT OOP PLC编程中如何将实现接口的单个FB实例传递给调用功能块
单实例持久化FB传递规范实现方案
你不需要使用REFERENCE_TO,借助IEC 61131-3标准的接口引用特性即可实现需求,这也是TwinCAT OOP场景下的官方推荐写法,不会出现寻址错误和告警,同时完全满足单实例、避免写入冲突的要求。
具体实现步骤
步骤1:确认接口与功能块的实现
确保你已经定义了标准化的持久化操作接口I_PersistentDataStorage,且FB_WritePersistentData功能块实现了该接口:
// 接口定义示例 INTERFACE I_PersistentDataStorage METHOD WriteData : BOOL VAR_INPUT dataToSave : ANY; END_VAR END_INTERFACE // 功能块实现接口 FUNCTION_BLOCK FB_WritePersistentData IMPLEMENTS I_PersistentDataStorage // 内部实现写入逻辑即可
步骤2:MAIN中定义单实例
和你之前的逻辑一致,在MAIN程序中定义唯一的持久化功能块实例:
// MAIN变量定义 VAR fbWritePersistentData : FB_WritePersistentData; END_VAR
步骤3:调用侧定义接口类型变量
3个子程序、以及所有需要调用持久化写入的内部功能块,都不要直接定义功能块类型的变量,也不需要用VAR_IN_OUT,直接定义接口类型的普通变量即可:
- 子程序变量定义示例:
// prgProgram1 变量定义 VAR persistentStorage : I_PersistentDataStorage; initDone : BOOL; fb1 : FB_1; fb2 : FB_1; END_VAR
- 内部功能块(如FB_1)的定义示例:
FUNCTION_BLOCK FB_1 VAR _persistentStorage : I_PersistentDataStorage; END_VAR // FB_Init方法接收接口参数 METHOD FB_Init : BOOL VAR_INPUT persistentStorage : I_PersistentDataStorage; END_VAR // 接口是引用传递,此处赋值不会生成新的实例,仅指向MAIN中的单实例 _persistentStorage := persistentStorage;
步骤4:逐层传递接口引用
- MAIN调用3个子程序时,传递单实例的接口引用:
// MAIN 运行逻辑 prgProgram1.persistentStorage := fbWritePersistentData; prgProgram1(); prgProgram2.persistentStorage := fbWritePersistentData; prgProgram2(); prgProgram3.persistentStorage := fbWritePersistentData; prgProgram3();
- 子程序内部首次初始化功能块时,传递接口引用即可:
// prgProgram1 运行逻辑 IF NOT initDone THEN fb1 := FB_1(persistentStorage := persistentStorage); fb2 := FB_1(persistentStorage := persistentStorage); initDone := TRUE; END_IF // 正常调用功能块,内部调用_persistentStorage.WriteData即可触发单实例写入 fb1(); fb2();
常见问题说明
- 之前用
VAR_IN_OUT传递功能块实例触发告警、页错误的原因:TwinCAT中跨程序块传递功能块类型的VAR_IN_OUT参数时,容易出现寻址偏移问题,属于非推荐写法,接口本身就是引用传递,不需要额外用VAR_IN_OUT。 - 临时写法
fb1 : FB_1(main.fbSavePersistent)的问题:该写法虽然可以运行,但会让所有内部功能块直接耦合MAIN的全局变量,后续替换持久化实现逻辑时需要修改所有调用位置,可维护性极差。
小提示:如果需要对写入请求做队列管理,避免同一周期多个写入请求冲突,可以在
FB_WritePersistentData内部实现请求队列逻辑,所有调用方提交的写入请求按顺序处理即可。
内容的提问来源于stack exchange,提问作者ziga
相关产品推荐
相关产品推荐

