博途(TIA Portal)中函数块(FB)的形参实参传递是PLC编程的核心机制。理解其原理与操作细节,能显著提升代码复用性与维护效率。
基本概念区分
形参(Formal Parameter)
形参是函数块内部定义的接口占位符,相当于"信箱上的名字标签"。它只在FB内部可见,不占用实际内存,等待外部调用时接收具体数据。
实参(Actual Parameter)
实参是调用FB时实际传递的具体数据,相当于"投入信箱的具体信件"。可以是变量、常量、表达式,必须有确定的内存地址或数值。
三种传递方式详解
博途FB支持三种形参实参绑定模式,适用场景截然不同。
方式一:符号绑定(推荐用于标准化项目)
核心机制:调用FB时,形参自动关联调用者的静态变量,无需手动填写实参。
配置步骤:
- 创建 带多重实例功能的FB(默认即支持)。
- 声明 形参时选择
In、Out、InOut或Static区域。 - 拖拽 FB至程序段,博途自动生成背景数据块(IDB)。
- 展开 FB调用块,观察到形参右侧显示灰色静态变量名(如
Motor1.Speed)。
代码示例:
// FB1: 电机控制块
FUNCTION_BLOCK "FB_MotorControl"
VAR_INPUT
Start : Bool; // 形参:启动命令
Stop : Bool; // 形参:停止命令
SetSpeed : Real; // 形参:设定转速
END_VAR
VAR_OUTPUT
Running : Bool; // 形参:运行状态
ActualSpeed : Real;// 形参:实际转速
END_VAR
VAR
RampGen : Real; // 内部斜坡发生器
END_VAR
// 主程序调用(OB1)
"FB_MotorControl_DB1"( // 自动生成背景DB
Start := "DI_Start_1",
Stop := "DI_Stop_1",
SetSpeed := "HMI_SpeedSet",
Running => "DO_Run_1",
ActualSpeed => "HMI_SpeedAct"
);
关键特性:
| 特性 | 说明 |
|---|---|
| 存储位置 | 形参值存于背景DB,断电保持需勾选 Retain |
| 访问方式 | 外部可通过 FB_MotorControl_DB1.SetSpeed 直接读写 |
| 适用场景 | 设备标准化、大量同类实例(如100台电机) |
方式二:绝对地址绑定(快速调试/临时方案)
核心机制:形参直接关联PLC的绝对地址(如 %I0.0、%QW100)。
操作步骤:
- 打开 FB调用块的参数列表。
- 删除 形参右侧的默认静态变量(选中后按
Delete)。 - 输入 绝对地址或全局变量名,例如:
- 形参
Start←%I0.0或"I_StartButton" - 形参
SetSpeed←%IW64或"AI_SpeedPoti"
- 形参
典型应用:
// 紧急情况下直接绑定硬件地址
"Safety_FB_1"(
EStop_Ch1 := %I10.0, // 急停通道1硬接线
EStop_Ch2 := %I10.1, // 急停通道2硬接线
LightCurtain := %I10.2, // 安全光幕
SafeOut => %Q5.0 // 安全输出
);
风险提示:
| 问题 | 后果 | 规避方法 |
|---|---|---|
| 地址冲突 | 多处写入同一输出导致逻辑混乱 | 建立地址分配表,交叉引用检查 |
| 移植困难 | 更换CPU型号时地址失效 | 优先使用符号名而非裸地址 |
| 调试困难 | 在线监控无法显示直观变量名 | 配合注释详细记录地址功能 |
方式三:表达式传递(计算型实参)
核心机制:实参可以是运算表达式,调用时即时计算后传入。
支持表达式类型:
| 类型 | 示例 | 适用形参方向 |
|---|---|---|
| 算术运算 | Pressure * 0.98 + Offset |
In |
| 比较运算 | Temp > AlarmLimit |
In |
| 位运算 | Status AND 16#0F |
In |
| 类型转换 | Real_To_Int(Speed) |
In |
| 条件选择 | Sel(G:=(x>0), IN0:=0, IN1:=x) |
In |
实例:流量补偿计算:
// FB: 流量累计(需温度压力补偿)
FUNCTION_BLOCK "FB_FlowTotal"
VAR_INPUT
FlowRaw : Real; // 原始流量信号
CompFactor : Real; // 补偿系数(0.8-1.2)
SampleTime : Real; // 采样周期(秒)
END_VAR
// 调用时实时计算补偿系数
"FB_FlowTotal_1"(
FlowRaw := %IW80,
CompFactor := (273.15 + "AI_Temp") / 293.15 * 101325 / "AI_Pressure",
SampleTime := 0.1
);
重要限制:
Out和InOut形参不可接收表达式,只能接收可写入的变量- 复杂表达式建议拆分,避免单次调用行过长
特殊传递机制:InOut 参数
InOut 参数兼具输入输出特性,是实现"按引用传递"的关键。
与普通变量的本质区别
// 假设有全局变量 Global_Var := 10
// 方式A:In参数(值传递)
"FB_Test"(InputVar := Global_Var);
// FB内部修改InputVar不影响Global_Var
// 方式B:InOut参数(引用传递)
"FB_Test"(InOutVar := Global_Var);
// FB内部修改InOutVar直接改变Global_Var
数组与结构体的高效传递
InOut 是传递大体积数据(数组、UDT)的唯一推荐方式,避免数据拷贝开销:
// 定义:100个伺服轴的位置数据
TYPE "UDT_AxisData"
STRUCT
Position : Array[1..100] of Real;
Velocity : Array[1..100] of Real;
Torque : Array[1..100] of Real;
END_STRUCT;
// FB:多轴插补计算
FUNCTION_BLOCK "FB_Interpolation"
VAR_IN_OUT
AxisData : "UDT_AxisData"; // 直接引用外部数据,不复制
END_VAR
// 调用:整个结构体作为单一参数传递
"FB_Interpolation_1"(AxisData := "G_AxisGroup_1");
多重实例与数据存储深度
理解形参数据的最终存储位置,是排查"值丢失"问题的关键。
graph TD
A["调用层级"] --> B["OB1: 主循环"]
B --> C["FB10: 设备管理层"]
C --> D["FB20: 电机控制
(形参: Speed)"] D --> E["FB30: 斜坡函数
(形参: RampTime)"] F["数据存储"] --> G["全局DB
(可选共享)"] F --> H["FB10_IDB
(静态变量区)"] F --> I["FB20_IDB
(嵌套在FB10_IDB内)"] F --> J["FB30_IDB
(嵌套在FB20_IDB内)"] D -.->|"Speed值存储于"| I E -.->|"RampTime值存储于"| J
(形参: Speed)"] D --> E["FB30: 斜坡函数
(形参: RampTime)"] F["数据存储"] --> G["全局DB
(可选共享)"] F --> H["FB10_IDB
(静态变量区)"] F --> I["FB20_IDB
(嵌套在FB10_IDB内)"] F --> J["FB30_IDB
(嵌套在FB20_IDB内)"] D -.->|"Speed值存储于"| I E -.->|"RampTime值存储于"| J
关键结论:
- 多层嵌套调用时,每层FB的形参值存储于各自的背景DB
- 使用
Multi-instance功能时,子FB的IDB嵌入父FB的IDB,形成层级结构 - 查看路径:项目树 → 程序块 → 系统块 → 展开层级查看嵌套关系
常见错误与排查
| 现象 | 根本原因 | 解决方法 |
|---|---|---|
| 形参值始终为0 | 未分配实参或实参变量未初始化 | 检查调用块的参数连接状态,确认变量被赋值 |
| 修改形参后外部变量不变 | 误用In而非InOut |
将方向改为InOut,或改用Out参数返回 |
| 背景DB过大 | 大量使用Static数组存储历史数据 |
将大数据移至全局DB,IDB中只存指针 |
| 编译报错"实参类型不匹配" | 形参Real接Int,或数组维度不符 |
添加类型转换函数,或统一数据类型定义 |
| 在线监控值与预期不符 | 实参被多处赋值,存在冲突 | 使用交叉引用(Ctrl + Alt + C)查找所有写入点 |
最佳实践总结
设计阶段:
- 优先使用符号绑定,建立清晰的变量命名规范(如
设备_功能_类型) - 将设备参数(电机额定电流、减速比等)封装为
UDT,作为InOut传递
编码阶段:
- 复杂计算在调用前完成,避免FB接口处堆砌表达式
- 对
InOut参数添加///文档注释,说明数据流向
维护阶段:
- 定期使用 重新链接 功能(右键程序块 →
重新链接),清理失效的实参引用 - 导出接口描述(
工具→导出→PLC变量),供HMI/SCADA团队同步

暂无评论,快来抢沙发吧!