传统做法:每个轴复制一套 MC_MoveAbsolute / MC_Home 代码,修改一处需改多处,新增轴型(步进/伺服)需大改逻辑。OOP 封装后:新增轴只需继承基类、重写差异部分,主程序调用统一接口,完全解耦。
这套架构已在多个半导体设备项目中验证,可管理 16 轴以上的复杂运控系统。
INTERFACE I_Axis // 使能/复位 METHOD Enable : BOOL METHOD Reset : BOOL // 回零 METHOD Home : BOOL // 运动命令 METHOD MoveAbs : BOOL VAR_INPUT fPos : LREAL; fVel : LREAL; END_VAR METHOD MoveRel : BOOL VAR_INPUT fDist : LREAL; fVel : LREAL; END_VAR METHOD Jog : BOOL VAR_INPUT bFwd : BOOL; bBwd : BOOL; END_VAR METHOD Stop : BOOL // 状态属性(只读) PROPERTY IsReady : BOOL GET PROPERTY IsMoving : BOOL GET PROPERTY ActPos : LREAL GET PROPERTY HasError : BOOL GET PROPERTY ErrorID : UDINT GET
FUNCTION_BLOCK FB_AxisBase IMPLEMENTS I_Axis VAR _axis : AXIS_REF; _fbPower : MC_Power; _fbHome : MC_Home; _fbMoveAbs : MC_MoveAbsolute; _fbMoveRel : MC_MoveRelative; _fbJog : MC_Jog; _fbStop : MC_Stop; _fbReset : MC_Reset; _eState : E_AxisState; END_VAR // MoveAbs 方法实现 METHOD MoveAbs : BOOL VAR_INPUT fPos : LREAL; fVel : LREAL; END_VAR _fbMoveAbs( Axis := _axis, Position := fPos, Velocity := fVel, Execute := TRUE ); MoveAbs := _fbMoveAbs.Done;
// 晶圆研磨下压轴:继承基类,扩展压力闭环切换能力 FUNCTION_BLOCK FB_GrindingAxis EXTENDS FB_AxisBase VAR _fbPressureCtrl : FB_PressureLoop; _bPressureMode : BOOL; END_VAR // 重写 Stop —— 增加压力控制器关闭逻辑 METHOD Stop : BOOL _fbPressureCtrl.Enable := FALSE; // 先关压力控制 SUPER^.Stop(); // 再调用基类停止逻辑 Stop := TRUE;
// 用接口数组管理所有轴,主程序无需关心具体轴型 VAR fbLinearAxis : FB_LinearAxis; fbGrindAxis : FB_GrindingAxis; arrAxes : ARRAY[0..1] OF I_Axis; END_VAR arrAxes[0] := fbLinearAxis; arrAxes[1] := fbGrindAxis; // 统一回零:无论直线轴还是研磨轴,调用相同接口 FOR i := 0 TO 1 DO arrAxes[i].Home(); END_FOR
💡 FB_EXTENDS 继承深度建议不超过 3 层:TwinCAT 3 在深度继承链(4 层以上)中可能出现 SUPER^ 调用栈溢出。复杂场景优先考虑组合(Composition)而非深度继承。
完整 OOP 轴控套件(含 I_Axis / FB_AxisBase / FB_LinearAxis / FB_RotaryAxis)已开源,见 github.com/tc3-engineer。