今天向DeepSeek问了关于博图软件单元的问题,起因是在看西门子的AF框架,里面提到了软件单元。从DeepSeek给的回答看很兴奋,已经很接近IT行业的面向对象编程了,至少做得比较到位了。
只是回答中提到的每个模块可以独立下载,不会影响其他单元,这个需要实际测试,不知道有人使用过吗?
我把回答的一些关键点罗列出来,给大家参考:
你的方式:传统项目 + FB + 严格接口
text
整个PLC项目 [一个大仓库]
├── FB_Motor (接口规范: in/out)
├── FB_Pump (接口规范: in/out)
├── FB_Cylinder (接口规范: in/out)
├── DB_Global (仍然存在,尽管你尽量少用)
└── OB1 [调用所有FB]
// 尽管你努力规范,但本质上:
// - 所有FB都在同一个命名空间
// - 所有代码都在同一个编译单元
// - 修改FB_Pump的接口 → 可能需要重新编译整个项目
// - 团队开发时,A和B工程师仍在同一个项目文件
软件单元方式
text
PLC项目 [独立公寓楼]
├── 单元A:进料 [独立公寓]
│ ├── FB_Motor (可同名)
│ ├── 私有DB
│ └── OB1
├── 单元B:灌装 [独立公寓]
│ ├── FB_Pump (可同名)
│ ├── 私有DB
│ └── OB1
└── 公共区域 [接口]
// 本质区别:
// - 每个单元独立编译
// - 单元内FB可重名
// - 修改单元B不需要动单元A
// - 团队开发互不干扰
设计阶段:先规划软件单元的接口
在开始写程序模块之前,你要先想清楚:单元之间需要交换什么信息?
实施阶段:在程序模块中调用
1. 首先,在单元内部编写程序模块
2. 然后,在单元的主循环中调用这些模块
3. 不同单元间的调用关系
注意:你不能在一个单元里直接调用另一个单元的FB。正确的做法是:
text
// ? 错误:在单元A里直接调用单元B的FB
"单元B.FB_Pump"(Start:=TRUE); // 这样不行!
// ? 正确:通过单元接**换信号
// 单元A设置接口信号
"单元A接口".启动灌装命令 := TRUE;
// 单元B在自己的循环中读取这个信号并执行
IF "单元A接口".启动灌装命令 THEN
"FB_Pump_Instance"(Start:=TRUE);
END_IF;
——————————————————————————————————————
在一个单元A中不能直接调用另一个单元的FB,类似于不能像传统设计在FBA中内部静态数据区设计一个FBB实例,这样修改了FBB也需要更新FBA。
通过接口调用,类似于把FBB作为实例参数传给FBA,使用inout接口。
接口被设计成专门的一个语言元素,这个还没用使用过。
传统方式我们可以通过实例直接访问实例的static数据,软件单元禁止这样做了吗?
如果禁止了,以前设计的HMI接口要重新写了。