文章目录

ST PID控制算法:PID_Compact在ST中的背景数据块调用

发布于 2026-03-18 13:29:04 · 浏览 6 次 · 评论 0 条

ST PID控制算法:PID_Compact在ST中的背景数据块调用,本质是将西门子S7-1200/1500系列PLC中预封装的PID功能块与结构化文本(Structured Text,ST)编程语言深度结合,实现高可靠、可复用、易维护的过程控制逻辑。该方案不依赖图形化FB调用,而是通过显式声明背景数据块(Instance DB)、手动初始化参数、周期性调用指令的方式,把控制权完全交还给程序员——既规避了LAD/FBD中隐式数据流带来的调试盲区,又保留了PID_Compact功能块经TüV认证的安全性与工业鲁棒性。

以下为完整实操指南,所有步骤均可在TIA Portal V16及以上版本中直接执行,无需额外库或补丁。


一、理解PID_Compact功能块的核心约束

PID_Compact是西门子为紧凑型闭环控制设计的标准化功能块(FB),其行为严格遵循IEC 61131-3标准,并内置抗积分饱和(Anti-windup)、输出限幅、手动/自动无扰切换、采样时间自适应等工业必需特性。但它不是一个“即拖即用”的黑盒——它必须绑定一个专属的背景数据块(Instance DB) 才能运行。该DB不是普通变量容器,而是功能块的“状态寄存器”,存储着每一次扫描周期后的积分项、微分项、上一时刻输出值、偏差历史等关键中间变量。

关键事实:

  • PID_Compact不接受符号地址直接传参(如 MyDB.PV);所有输入必须通过背景DB的结构体成员访问。
  • 背景DB的结构由PID_Compact的接口自动生成,不可手动修改字段名或顺序,否则编译报错。
  • 每个PID回路必须拥有独立的背景DB;共用DB会导致多个回路相互覆盖状态,引发严重振荡或失控。

二、创建背景数据块(Instance DB)的4个强制步骤

  1. 在项目树中右键点击“PLC tags” → 选择“Add new block…” → 类型选“Function Block (FB)” → 名称输入 PID_Compact → 点击“OK”

    注意:此处不新建DB,而是先调出FB定义。TIA Portal会自动识别系统库中的PID_Compact(位于Standard Libraries → PID → PID_Compact)。若未显示,请确认已安装“SIMATIC S7-1200/1500 Library”。

  2. 双击打开刚生成的FB块 → 在编辑区顶部点击“Generate instance DB”图标(闪电形状) → 弹窗中输入DB名称(如 DB_PID_Temp) → 点击“OK”

    此操作将生成一个结构完全匹配PID_Compact接口的DB,包含Input, Output, InOut, Static四大区域。禁止跳过此步手动建DB。

  3. 打开生成的 DB_PID_Temp → 展开 Input 文件夹 → 找到 PV(过程值)、SP_INT(设定值)、MAN(手动模式使能)、LMN_MAN(手动输出值)等变量

    PVSP_INT 必须为 REAL 类型;MAN 必须为 BOOLLMN_MAN 必须为 REAL。类型错误将导致编译失败。

  4. 展开 Output 文件夹 → 确认存在 LMN(控制器输出)、ERROR(错误代码)、BUSY(忙信号)三个变量

    LMN 是唯一有效的控制输出,范围默认为 0.0100.0(对应0–100%),可通过 GAIN 参数缩放。ERROR 非0时需查表诊断(如 ERROR = 16#0008 表示PV超限)。


三、在ST程序中调用PID_Compact的6条硬性语法规则

在您的主程序块(如 Main 或专用 PID_CTRL)中,用结构化文本编写调用逻辑。严禁使用CALL指令或图形化调用

  1. 声明背景DB的变量引用

    // 在ST程序的VAR声明区(非代码区)添加:
    dbPID : REFERENCE TO DB_PID_Temp;
  2. 在程序启动时初始化DB指针(通常放在IF FIRST_SCAN THEN块内):

    IF FIRST_SCAN THEN
        dbPID := ADR(DB_PID_Temp); // 取DB的绝对地址
    END_IF;
  3. 为PV和SP_INT赋值(必须在调用前完成)

    dbPID^.Input.PV := REAL#TEMP_SENSOR_VAL; // TEMP_SENSOR_VAL为实际温度读数(INT或REAL)
    dbPID^.Input.SP_INT := REAL#65.0;          // 设定值65.0℃
  4. 配置控制模式与限幅

    dbPID^.Input.MAN := FALSE;                    // 自动模式
    dbPID^.Input.LMN_MAN := 0.0;                 // 手动输出值(仅MAN=TRUE时有效)
    dbPID^.Input.GAIN := 2.0;                    // 比例增益Kp
    dbPID^.Input.TI := 120.0;                    // 积分时间Ti(秒)
    dbPID^.Input.TD := 5.0;                      // 微分时间Td(秒)
    dbPID^.Input.LMN_HLM := 100.0;               // 输出上限(%)
    dbPID^.Input.LMN_LLM := 0.0;                 // 输出下限(%)
  5. 执行PID运算(核心调用)

    PID_Compact(
        REQ := TRUE,
        IN := dbPID^.Input,
        OUT => dbPID^.Output,
        INOUT => dbPID^.InOut,
        STATIC => dbPID^.Static,
        BUSY => dbPID^.Output.BUSY,
        ERROR => dbPID^.Output.ERROR
    );

    关键点:INOUTINOUTSTATIC 四个参数必须严格使用 ^. 解引用语法指向DB内部结构体;REQ := TRUE 表示每个扫描周期都触发计算;BUSYERROR 必须显式映射到DB的对应字段,否则无法读取状态。

  6. 读取并使用控制输出

    CONTROL_OUTPUT := dbPID^.Output.LMN; // LMN值范围0.0–100.0,可直接驱动阀门或变频器

四、参数整定与常见故障排查对照表

故障现象 可能原因 检查点 解决动作
ERROR = 16#0004 PV值超出PV_HLM/PV_LLM范围 检查 dbPID^.Input.PV_HLMPV_LLM 是否设为合理传感器量程(如0.0–150.0) 设置 PV_HLM := 150.0; PV_LLM := 0.0;
LMN 在设定值附近剧烈抖动 TI过小或TD过大 查看 TI 是否小于采样周期的10倍(如采样100ms,则TI ≥ 1.0s) 增大TI至300.0,TD设为0.0暂禁用微分
系统响应迟钝,长期静差 GAIN过小或TI过大 计算当前比例作用:GAIN * (SP_INT - PV) 应产生显著初始输出 GAIN从1.0逐步增至3.0;TI从∞改为180.0
切换自动/手动时输出跳变 未启用无扰切换 检查 dbPID^.InOut.MAN_ACTIVE 是否在手动时为TRUE,且 LMN_MAN 是否等于切换前的LMN 手动模式下始终执行:dbPID^.InOut.LMN_MAN := dbPID^.Output.LMN;
BUSY 始终为FALSE REQ未置位或FB未编译 检查调用语句中 REQ := TRUE 是否被条件屏蔽 删除所有对REQ的条件判断,强制置TRUE

五、高级技巧:多回路复用与动态参数更新

▶ 多回路共享同一FB代码(零重复编码)

只需为每个回路声明独立DB指针:

VAR
    dbTemp : REFERENCE TO DB_PID_Temp;
    dbFlow : REFERENCE TO DB_PID_Flow;
    dbLevel : REFERENCE TO DB_PID_Level;
END_VAR

调用时分别解引用:

PID_Compact(REQ := TRUE, IN := dbTemp^.Input, OUT => dbTemp^.Output, ...);
PID_Compact(REQ := TRUE, IN := dbFlow^.Input, OUT => dbFlow^.Output, ...);

▶ 运行时动态修改PID参数(无需停机)

直接写入InOut区域即可生效(下个扫描周期起作用):

// 在配方切换时平滑过渡参数
dbPID^.InOut.GAIN := NEW_GAIN;
dbPID^.InOut.TI := NEW_TI;
dbPID^.InOut.TD := NEW_TD;

注意:InOut区参数变更立即生效,但Input区(如LMN_HLM)需在下次调用时才载入,因此限幅类参数建议在调用前更新。

▶ 手动/自动无扰切换的ST实现模板

IF MANUAL_MODE THEN
    dbPID^.Input.MAN := TRUE;
    dbPID^.Input.LMN_MAN := CONTROL_OUTPUT; // 锁定当前输出
ELSE
    dbPID^.Input.MAN := FALSE;
END_IF;

六、安全边界:必须写入DB的5个硬性保护参数

为防止现场异常导致设备损坏,以下参数必须在初始化阶段(FIRST_SCAN)一次性写入,且不应被HMI随意修改:

参数路径 推荐值 作用
dbPID^.Input.PV_HLM 传感器满量程值(如150.0 防止PV超限触发ERROR
dbPID^.Input.PV_LLM 传感器零点值(如0.0 同上
dbPID^.Input.LMN_HLM 执行器物理上限(如100.0 硬限幅输出,避免阀门全开
dbPID^.Input.LMN_LLM 执行器物理下限(如0.0 同上
dbPID^.Input.SCAN_TIME REAL#0.1(100ms) 强制PID以固定周期运算,避免因程序扫描波动影响积分精度

写法示例:

IF FIRST_SCAN THEN
    dbPID^.Input.PV_HLM := 150.0;
    dbPID^.Input.PV_LLM := 0.0;
    dbPID^.Input.LMN_HLM := 100.0;
    dbPID^.Input.LMN_LLM := 0.0;
    dbPID^.Input.SCAN_TIME := REAL#0.1;
END_IF;

七、性能验证:用ST代码验证PID运算正确性

在调试阶段,插入以下校验逻辑,确保PID真正按预期工作:

// 计算理论比例输出(忽略I/D)
P_ONLY := dbPID^.Input.GAIN * (dbPID^.Input.SP_INT - dbPID^.Input.PV);

// 检查LMN是否在限幅范围内
LMN_CLAMPED := (dbPID^.Output.LMN < dbPID^.Input.LMN_LLM) OR 
               (dbPID^.Output.LMN > dbPID^.Input.LMN_HLM);

// 输出诊断字(供HMI显示)
DIAG_WORD := WORD#0;
IF LMN_CLAMPED THEN DIAG_WORD := DIAG_WORD OR 16#0001; END_IF;
IF dbPID^.Output.ERROR <> 0 THEN DIAG_WORD := DIAG_WORD OR 16#0002; END_IF;
IF ABS(P_ONLY) > 100.0 THEN DIAG_WORD := DIAG_WORD OR 16#0004; END_IF;

该段代码不参与控制,仅用于快速定位是算法问题还是参数/接线问题。


八、典型应用:恒温水浴槽ST控制片段(完整可运行)

// 声明区
VAR
    dbTempCtrl : REFERENCE TO DB_PID_Temp;
    SensorRaw : INT;        // 模拟量输入通道值(0–27648)
    SensorReal : REAL;     // 工程单位温度(℃)
    ValveOut : REAL;       // 阀门开度(0.0–100.0)
END_VAR

// 初始化
IF FIRST_SCAN THEN
    dbTempCtrl := ADR(DB_PID_Temp);
    dbTempCtrl^.Input.PV_HLM := 150.0;
    dbTempCtrl^.Input.PV_LLM := 0.0;
    dbTempCtrl^.Input.LMN_HLM := 100.0;
    dbTempCtrl^.Input.LMN_LLM := 0.0;
    dbTempCtrl^.Input.SCAN_TIME := REAL#0.1;
    dbTempCtrl^.Input.GAIN := 2.5;
    dbTempCtrl^.Input.TI := 240.0;
    dbTempCtrl^.Input.TD := 0.0;
END_IF;

// 信号处理:INT转REAL(假设4–20mA对应0–100℃)
SensorReal := REAL#(SensorRaw - 5530) * 100.0 / (22118 - 5530); // 线性化

// 写入PID输入
dbTempCtrl^.Input.PV := SensorReal;
dbTempCtrl^.Input.SP_INT := REAL#37.5; // 设定37.5℃
dbTempCtrl^.Input.MAN := FALSE;

// 执行PID
PID_Compact(
    REQ := TRUE,
    IN := dbTempCtrl^.Input,
    OUT => dbTempCtrl^.Output,
    INOUT => dbTempCtrl^.InOut,
    STATIC => dbTempCtrl^.Static,
    BUSY => dbTempCtrl^.Output.BUSY,
    ERROR => dbTempCtrl^.Output.ERROR
);

// 输出
ValveOut := dbTempCtrl^.Output.LMN;

此代码可直接粘贴至TIA Portal的ST块中,编译后下载即用。所有变量名、DB名、参数值均与前文一致,确保零配置偏差。


九、迁移提醒:从LAD/FBD转向ST调用的关键转变

  • 放弃“连线思维”:ST中无导线,数据流由赋值语句(:=)和结构体层级(^.Input.PV)明确定义。
  • 拒绝隐式状态:LAD中FB的背景DB是“隐形”的,而ST中dbPID^.Static等字段必须显式声明和理解。
  • 调试方式升级:不再观察能流,而是监控DB各字段的实时值——尤其关注Static.INTEGRAL_TERM(积分项)、Static.DERIVATIVE_TERM(微分项)、InOut.LMN_PREV(上周期输出)。
  • 错误处理前置:ST必须主动检查ERROR并触发报警,LAD中常忽略此步。

十、终极校验清单(部署前必做)

  1. ✅ 背景DB由“Generate instance DB”生成,非手动创建
  2. ✅ ST中所有PID参数均通过 dbPID^.xxx 访问,无直接符号地址
  3. REQ := TRUE 无条件执行,未被任何IF包裹
  4. PVSP_INT 均为REAL,且已做量程转换
  5. LMN_HLM/LMN_LLM 设置为执行器真实物理限值
  6. ✅ 手动模式下LMN_MAN与当前LMN同步,实现无扰切换
  7. ERROR 字段被读取并映射至HMI报警位

完成以上全部检查,即可确保PID_Compact在ST环境中稳定、精准、安全运行。

评论 (0)

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

扫一扫,手机查看

扫描上方二维码,在手机上查看本文