博文

IEC61131-3 ST语言核心 - 函数与功能块编程详解

ST/PLC

IEC61131-3 ST 语言核心 - 函数与功能块编程详解

函数 vs 功能块

特性FUNCTION(函数)FUNCTION_BLOCK(功能块)
返回值有(函数名即返回值)
状态保持有(内部变量保持值)
多实例不支持可创建多个实例
典型用途计算、转换、查询设备控制、状态管理

1. FUNCTION(函数)

1.1 简单函数

FUNCTION FC_Add : INT
VAR_INPUT
    A : INT;
    B : INT;
END_VAR

FC_Add := A + B;

END_FUNCTION

1.2 多返回值函数

通过 VAR_OUTPUT 实现多个输出:

FUNCTION FC_Calc : BOOL
VAR_INPUT
    Input1 : REAL;
    Input2 : REAL;
END_VAR
VAR_OUTPUT
    Sum : REAL;
    Product : REAL;
END_VAR
VAR
    Valid : BOOL;
END_VAR

Valid := (Input1 <> 0.0) AND (Input2 <> 0.0);

IF Valid THEN
    Sum := Input1 + Input2;
    Product := Input1 * Input2;
END_IF;

FC_Calc := Valid;

END_FUNCTION

// 调用示例
Result := FC_Calc(Input1 := 10.0, Input2 := 5.0, 
                  Sum => Total, Product => Prod);

1.3 函数调用方式

// 位置参数(按顺序)
Result := FC_Add(10, 20);

// 命名参数(推荐,更清晰)
Result := FC_Add(A := 10, B := 20);

// 混合使用
Result := FC_Calc(10.0, Input2 := 5.0, Sum => Total);

2. FUNCTION_BLOCK(功能块)

2.1 基本功能块

FUNCTION_BLOCK FB_Motor
VAR_INPUT
    Start : BOOL;
    Stop : BOOL;
    Speed_Set : INT;
END_VAR
VAR_OUTPUT
    Running : BOOL;
    Current_Speed : INT;
END_VAR
VAR
    Internal_Timer : TON;
END_VAR

IF Start AND NOT Stop THEN
    Running := TRUE;
    Current_Speed := Speed_Set;
END_IF;

IF Stop THEN
    Running := FALSE;
    Current_Speed := 0;
END_IF;

END_FUNCTION_BLOCK

2.2 功能块实例化

PROGRAM Main
VAR
    Motor1 : FB_Motor;
    Motor2 : FB_Motor;
    Conveyor : FB_Motor;
END_VAR

// 调用功能块
Motor1(
    Start := Start_Btn_1,
    Stop := Stop_Btn_1,
    Speed_Set := 1500,
    Running => Motor1_Running,
    Current_Speed => Motor1_Speed
);

// 简洁调用(只传输入)
Motor2(Start := Start_Btn_2, Stop := Stop_Btn_2, Speed_Set := 1200);

// 访问输出
IF Motor1.Running THEN
    Indicator_1 := TRUE;
END_IF;

END_PROGRAM

3. 完整实战:PID 控制器

3.1 PID 功能块实现

FUNCTION_BLOCK FB_PID
VAR_INPUT
    SetPoint : REAL;      // 设定值
    ProcessValue : REAL;  // 过程值
    AutoTune : BOOL;      // 自整定
    Reset : BOOL;         // 复位
    Enable : BOOL;        // 使能
END_VAR
VAR_OUTPUT
    Output : REAL;        // 输出值
    Error : REAL;         // 当前误差
    Status : INT;         // 状态码
    IntegralTerm : REAL;  // 积分项(调试用)
END_VAR
VAR
    // PID 参数
    Kp : REAL := 1.0;     // 比例系数
    Ki : REAL := 0.1;     // 积分系数
    Kd : REAL := 0.01;    // 微分系数
    
    // 内部状态
    PrevError : REAL := 0.0;
    Integral : REAL := 0.0;
    FirstCycle : BOOL := TRUE;
    CycleTime : TIME := T#10ms;
END_VAR

// 未使能时直接退出
IF NOT Enable THEN
    Output := 0.0;
    Status := 0;
    RETURN;
END_IF;

// 误差计算
Error := SetPoint - ProcessValue;

// 复位处理
IF Reset THEN
    Integral := 0.0;
    PrevError := 0.0;
    FirstCycle := TRUE;
    Output := 0.0;
    Status := 0;
    RETURN;
END_IF;

// 首次执行初始化
IF FirstCycle THEN
    PrevError := Error;
    FirstCycle := FALSE;
    Status := 1;  // 初始化完成
    RETURN;
END_IF;

// 比例项
Output := Kp * Error;

// 积分项(带抗积分饱和)
Integral := Integral + (Ki * Error * TIME_TO_REAL(CycleTime));
Output := Output + Integral;

// 微分项
Output := Output + Kd * (Error - PrevError) / TIME_TO_REAL(CycleTime);

// 更新
PrevError := Error;
Status := 2;  // 正常运行

// 限幅 0-100%
IF Output > 100.0 THEN
    Output := 100.0;
ELSIF Output < 0.0 THEN
    Output := 0.0;
END_IF;

IntegralTerm := Integral;

END_FUNCTION_BLOCK

3.2 PID 使用示例

PROGRAM TempControl
VAR
    PID_Controller : FB_PID;
    Target_Temp : REAL := 80.0;
    Current_Temp : REAL;
    Heater_Output : REAL;
    PID_Auto : BOOL := TRUE;
    PID_Reset : BOOL := FALSE;
END_VAR

// 读取实际温度(模拟)
Current_Temp := Read_Temp_Sensor();

// 调用 PID
PID_Controller(
    SetPoint := Target_Temp,
    ProcessValue := Current_Temp,
    Enable := PID_Auto,
    Reset := PID_Reset,
    Output => Heater_Output
);

// 输出到加热器
Set_Heater_Output(Heater_Output);

// 清除复位信号
PID_Reset := FALSE;

END_PROGRAM

4. METHOD(方法)

在功能块中添加方法,实现封装:

FUNCTION_BLOCK FB_StateMachine
VAR
    State : INT := 0;
END_VAR

// 方法:状态转移
METHOD Transition : BOOL
VAR_INPUT
    NewState : INT;
    Condition : BOOL;
END_VAR

IF Condition THEN
    State := NewState;
    Transition := TRUE;
ELSE
    Transition := FALSE;
END_IF;

END_METHOD

// 方法:获取当前状态
METHOD GetCurrentState : INT
GetCurrentState := State;
END_METHOD

// 方法:强制复位
METHOD Reset
    State := 0;
END_METHOD

END_FUNCTION_BLOCK

5. 实战:电机控制功能块

FUNCTION_BLOCK FB_MotorControl
VAR_INPUT
    Start : BOOL;
    Stop : BOOL;
    EmergencyStop : BOOL;
    Speed_Reference : INT;    // 0-100%
END_VAR
VAR_OUTPUT
    Running : BOOL;
    Actual_Speed : INT;
    Fault : BOOL;
    FaultCode : INT;
END_VAR
VAR
    // 内部状态
    State : INT := 0;         // 0:停止 1:启动中 2:运行 3:故障
    Ramp_Timer : TON;
    Current_Ramp : INT := 0;
    Ramp_Step : INT := 10;    // 每次加速 10%
END_VAR

CASE State OF
    0:  // 停止
        Running := FALSE;
        Current_Ramp := 0;
        
        IF Start AND NOT EmergencyStop THEN
            State := 1;
        END_IF;
        
        IF EmergencyStop THEN
            State := 3;
            FaultCode := 1;
        END_IF;
    
    1:  // 启动中(加速)
        Ramp_Timer(IN := TRUE, PT := T#100ms);
        
        IF Ramp_Timer.Q THEN
            Ramp_Timer(IN := FALSE);
            Current_Ramp := Current_Ramp + Ramp_Step;
            
            IF Current_Ramp >= Speed_Reference THEN
                Current_Ramp := Speed_Reference;
                State := 2;
            END_IF;
        END_IF;
        
        IF EmergencyStop THEN
            State := 3;
            FaultCode := 1;
        END_IF;
    
    2:  // 运行中
        Current_Ramp := Speed_Reference;
        IF Stop THEN
            State := 0;
        END_IF;
        IF EmergencyStop THEN
            State := 3;
            FaultCode := 1;
        END_IF;
    
    3:  // 故障
        Running := FALSE;
        Current_Ramp := 0;
        Fault := TRUE;
        
        IF NOT EmergencyStop AND Stop THEN
            Fault := FALSE;
            FaultCode := 0;
            State := 0;
        END_IF;
END_CASE;

Actual_Speed := Current_Ramp;
Running := (State = 2);

END_FUNCTION_BLOCK

文档版本:1.0 | 更新日期:2026-04-28 | 作者:JianLin Studio

← 返回博文列表