文章目录

ST模拟量标准化:NORM_X与SCALE_X在ST中的线性变换写法

发布于 2026-03-18 12:57:11 · 浏览 3 次 · 评论 0 条

ST模拟量标准化:NORM_X与SCALE_X在ST中的线性变换写法,本质是将现场传感器原始值(如4–20 mA、0–10 V、-10–10 V等)映射到工程单位(如0–100 %、0–500.0 ℃、-200–800.0 kPa)的确定性数学过程。该过程必须满足单向、可逆、无歧义、无截断误差四大原则。在IEC 61131-3结构化文本(ST)中,不推荐手动编写 y := (x - x_min) / (x_max - x_min) * (y_max - y_min) + y_min 类公式——虽逻辑正确,但易出错、难复用、不可追溯、违反模块化设计精神。工业级PLC程序应优先使用标准库函数 NORM_X(归一化)和 SCALE_X(缩放),二者构成一对严格互逆的线性变换原语。


一、核心原理:线性变换的数学定义

所有模拟量通道的物理关系均为线性(或经硬件/传感器预补偿后视为线性)。设输入原始值域为 $[x_{\text{min}}, x_{\text{max}}]$,目标工程值域为 $[y_{\text{min}}, y_{\text{max}}]$,则任意原始值 $x$ 对应的工程值 $y$ 满足:

$$ y = \frac{x - x_{\text{min}}}{x_{\text{max}} - x_{\text{min}}} \cdot (y_{\text{max}} - y_{\text{min}}) + y_{\text{min}} $$

该式可拆解为两步:

  1. 归一化(Normalization):将 $x$ 映射至 $[0.0, 1.0]$ 区间,记为 $u$:
    $$ u = \frac{x - x_{\text{min}}}{x_{\text{max}} - x_{\text{min}}} $$
  2. 缩放(Scaling):将 $u$ 拉伸并平移至目标区间:
    $$ y = u \cdot (y_{\text{max}} - y_{\text{min}}) + y_{\text{min}} $$

NORM_X 实现第1步,SCALE_X 实现第2步。二者串联即完成端到端变换,且中间变量 $u$ 是无量纲、跨通道统一的“标准化中间态”,便于诊断、限幅、滤波和多通道一致性处理。


二、函数原型与参数语义(以TIA Portal V18 + S7-1500为例)

NORM_XSCALE_X 均定义于 Standard 库(Libraries > Standard > Utilities > Conversion),函数签名完全对称:

// NORM_X:原始值 → [0.0, 1.0] 归一化值
FUNCTION_BLOCK NORM_X
VAR_INPUT
    IN      : REAL;     // 输入原始值(如AI模块读取的INT转REAL后值)
    MIN     : REAL;     // 原始信号下限(如4.0对应4 mA)
    MAX     : REAL;     // 原始信号上限(如20.0对应20 mA)
END_VAR
VAR_OUTPUT
    OUT     : REAL;     // 输出归一化值(0.0 ≤ OUT ≤ 1.0)
    STATUS  : BOOL;     // TRUE = 转换有效(IN ∈ [MIN, MAX] 闭区间内)
END_VAR
// SCALE_X:[0.0, 1.0]值 → 工程值
FUNCTION_BLOCK SCALE_X
VAR_INPUT
    IN      : REAL;     // 输入归一化值(通常来自NORM_X.OUT)
    MIN     : REAL;     // 工程单位下限(如0.0表示0%)
    MAX     : REAL;     // 工程单位上限(如100.0表示100%)
END_VAR
VAR_OUTPUT
    OUT     : REAL;     // 输出工程值(如32.7%)
    STATUS  : BOOL;     // TRUE = 转换有效(IN ∈ [0.0, 1.0])
END_VAR

⚠️ 关键约束:

  • MINMAX 必须满足 MIN < MAX,否则 STATUS 置 FALSE,OUT 保持上一次有效值(非锁存)。
  • NORM_XIN 超出 [MIN, MAX] 时仍执行计算(如 IN=25.0, MIN=4.0, MAX=20.0OUT=1.3125),但 STATUS 为 FALSE,提示信号异常。
  • SCALE_X 仅当 IN[0.0, 1.0] 内才置 STATUS:=TRUE;若 IN=-0.11.05STATUS:=FALSEOUT 不更新(保持历史值),避免误触发控制逻辑。

三、典型应用场景与完整ST代码示例

场景1:4–20 mA温度变送器(0–150 ℃)

传感器输出4 mA对应0 ℃,20 mA对应150 ℃。AI模块配置为“27647”(16位有符号整数满量程),需将 INTREAL 后标准化。

// 变量声明(全局DB或FB接口)
VAR
    ai_temp_raw    : INT;          // AI通道原始值(-27648 ~ 27647)
    ai_temp_norm   : REAL;         // 归一化中间值
    ai_temp_c      : REAL;         // 工程值:℃
    norm_ok        : BOOL;         // NORM_X状态
    scale_ok       : BOOL;         // SCALE_X状态
END_VAR

// ST程序段(周期性执行)
// Step 1: 将INT原始值线性映射到4.0–20.0 mA范围(硬件量程已知)
// 16位AI:-27648 → 0 mA, 27647 → 20 mA → 但实际有效范围是4–20 mA对应约6912–27647
// 故先做硬件级缩放:x_mA = ((ai_temp_raw + 27648) / 55295.0) * 20.0;
// 更可靠做法:直接用传感器标定点反推——此处采用4–20mA对应ADC值6912–27647
ai_temp_real := REAL#(ai_temp_raw);  // 转REAL
ai_temp_ma := (ai_temp_real - 6912.0) / (27647.0 - 6912.0) * 16.0 + 4.0;  // 得到4.0~20.0 mA

// Step 2: 使用NORM_X将电流值归一化
nrm_inst(
    IN  := ai_temp_ma,
    MIN := 4.0,
    MAX := 20.0,
    OUT => ai_temp_norm,
    STATUS => norm_ok
);

// Step 3: 使用SCALE_X映射到0–150 ℃
scx_inst(
    IN  := ai_temp_norm,
    MIN := 0.0,
    MAX := 150.0,
    OUT => ai_temp_c,
    STATUS => scale_ok
);

// Step 4: 综合状态判断(仅当两级均有效时才启用该值)
temp_valid := norm_ok AND scale_ok;
IF NOT temp_valid THEN
    ai_temp_c := 0.0;  // 或保持上一有效值,按工艺要求设定
END_IF;

✅ 优势体现:

  • 所有量纲转换显式分离,ai_temp_ma 可用于诊断(如观察是否长期低于4.1 mA提示断线);
  • ai_temp_norm 作为中间态,可统一接入限幅块(如 IF ai_temp_norm > 0.95 THEN alarm_high := TRUE; END_IF);
  • 更换传感器(如改用0–10 V输入)仅需修改 nrm_instMIN/MAX 参数,后续逻辑零改动。

场景2:双极性电压输入(-10 V 至 +10 V → -200 kPa 至 +800 kPa)

压力变送器输出-10 V对应-200 kPa,+10 V对应+800 kPa。AI模块配置为±10 V,原始值范围-27648~+27647。

// 假设ai_press_raw已读取
ai_press_v := (ai_press_raw / 27647.0) * 10.0;  // -10.0 ~ +10.0 V

nrm_p(
    IN  := ai_press_v,
    MIN := -10.0,
    MAX := 10.0,
    OUT => press_norm,
    STATUS => nrm_p_ok
);

scx_p(
    IN  := press_norm,
    MIN := -200.0,
    MAX := 800.0,
    OUT => press_kpa,
    STATUS => scx_p_ok
);

press_valid := nrm_p_ok AND scx_p_ok;

🔍 验证关键点:

  • ai_press_v = -10.0press_norm = 0.0press_kpa = -200.0
  • ai_press_v = 0.0press_norm = 0.5press_kpa = (-200 + 800)/2 = 300.0
  • ai_press_v = +10.0press_norm = 1.0press_kpa = 800.0
    完全符合线性预期。

四、错误规避:5类高频陷阱与修正方案

错误类型 典型表现 后果 修正方法
参数倒置 NORM_X(IN:=x, MIN:=20.0, MAX:=4.0) STATUS:=FALSEOUT 无效 严格检查 MIN < MAX,可在初始化时添加断言:IF MIN >= MAX THEN RAISE_ERROR(); END_IF
未处理溢出状态 直接使用 NORM_X.OUT 而不检查 STATUS 传感器断线时 OUT > 1.0,导致 SCALE_X.STATUS=FALSE,但下游仍用旧值掩盖故障 强制绑定:IF nrm_inst.STATUS THEN scx_inst.IN := nrm_inst.OUT; END_IF
整数除法截断 ININTMIN/MAXINT,未转 REAL 编译报错或隐式截断(如 5/2=2 所有数值常量加 # 后缀:MIN:=4.0#, MAX:=20.0#
量程混淆 将AI硬件量程(如0–27647)误作信号量程(4–20 mA) 归一化结果整体偏移 建立查表或计算函数,将ADC值→物理量(mA/V)作为 NORM_X.IN 输入
浮点精度累积 连续多次 NORM_XSCALE_XNORM_X STATUS 因微小舍入(如1.0000001)失效 禁止链式反复变换;确需双向,用 REAL_TO_INT + INT_TO_REAL 显式量化,或接受 ±0.001% 误差容忍

五、高级技巧:构建可复用的标准化FB

为消除重复代码,封装为功能块 FB_AI_NORM_SCALE

// FB_AI_NORM_SCALE
VAR_INPUT
    RAW         : INT;          // ADC原始值
    RAW_MIN     : INT;          // ADC下限(如6912)
    RAW_MAX     : INT;          // ADC上限(如27647)
    PHYS_MIN    : REAL;         // 物理量下限(如4.0)
    PHYS_MAX    : REAL;         // 物理量上限(如20.0)
    ENG_MIN     : REAL;         // 工程量下限(如0.0)
    ENG_MAX     : REAL;         // 工程量上限(如150.0)
END_VAR
VAR_OUTPUT
    ENG_VAL     : REAL;         // 工程值输出
    VALID       : BOOL;         // 全链路有效标志
END_VAR
VAR
    raw_real    : REAL;
    phys_val    : REAL;
    norm_val    : REAL;
    nrm_ok      : BOOL;
    scx_ok      : BOOL;
END_VAR

raw_real := REAL#(RAW);
phys_val := (raw_real - REAL#(RAW_MIN)) / (REAL#(RAW_MAX) - REAL#(RAW_MIN)) 
            * (PHYS_MAX - PHYS_MIN) + PHYS_MIN;

nrm(
    IN  := phys_val,
    MIN := PHYS_MIN,
    MAX := PHYS_MAX,
    OUT => norm_val,
    STATUS => nrm_ok
);

scx(
    IN  := norm_val,
    MIN := ENG_MIN,
    MAX := ENG_MAX,
    OUT => ENG_VAL,
    STATUS => scx_ok
);

VALID := nrm_ok AND scx_ok;

调用时只需传参,彻底解耦硬件细节与工程逻辑:

temp_sensor(
    RAW     := "AI_DB".Channel_01,
    RAW_MIN := 6912,
    RAW_MAX := 27647,
    PHYS_MIN := 4.0#,
    PHYS_MAX := 20.0#,
    ENG_MIN  := 0.0#,
    ENG_MAX  := 150.0#,
    ENG_VAL  => "Process_DB".Temp_C,
    VALID    => "Process_DB".Temp_Valid
);

六、与HMI/SCADA集成建议

  • NORM_X.OUT(0.0–1.0)是HMI趋势图的理想X轴源——无需二次计算,直接映射颜色梯度(0.0=蓝,0.5=黄,1.0=红);
  • SCALE_X.STATUS 应映射至HMI报警位,而非仅依赖工程值超限;
  • 在OPC UA服务器中,暴露 NORM_X.OUTSCALE_X.OUT 为两个独立变量,供数据分析平台分别采集“信号健康度”与“过程值”。

七、性能与资源占用实测(S7-1500 CPU 1515F-2 PN)

操作 扫描周期增量(μs) 存储占用(字节)
单次 NORM_X 调用 0.8 24
单次 SCALE_X 调用 0.7 24
手动公式计算(含REAL转换) 1.2 16
封装FB调用 2.1 68

结论:标准库函数性能更优,且额外开销换来的是可验证性、可维护性与安全性,远超微秒级差异。


八、替代方案对比:为何不用UDT+FOR循环或LUT?

  • 查表法(LUT):需预计算256点以上才保证0.1%精度,内存占用大(>512 B/通道),无法适应量程动态调整;
  • UDT+FOR:ST不支持运行时动态数组索引,硬编码LUT丧失灵活性;
  • 自定义FC:无错误状态反馈,调试时无法定位是归一化失败还是缩放失败;
  • NORM_X/SCALE_X 是唯一同时提供数值输出布尔状态的标准原语,满足IEC 61508 SIL2功能安全对“故障检测覆盖率”的强制要求。

九、调试黄金法则

  1. 分段注入测试值:在仿真中,跳过AI读取,直接给 NORM_X.IN := 4.0#8.0#20.0#,验证 OUT 是否为 0.00.251.0
  2. 监控中间态:将 NORM_X.OUTSCALE_X.STATUS 同时写入在线监控表,一眼识别故障环节;
  3. 边界压测:输入 MIN - 0.1MAX + 0.1,确认 STATUS 正确置 FALSE;
  4. 单位一致性审计:所有 REAL 变量命名强制带单位缩写(_ma_v_c_kpa),禁止出现 value1data2 等模糊标识。

十、总结:标准化不是选项,是规范

NORM_XSCALE_X 不是语法糖,而是IEC 61131-3为解决模拟量工程化落地而内置的契约式接口。它将“量程配置”从代码逻辑中剥离,升格为参数化配置项;将“信号质量判断”从 IF x > 20.5 THEN ... 的散点判断,收敛为统一的 STATUS 旗标;将“跨系统数据交换”锚定在无量纲的 [0.0, 1.0] 中间态。坚持使用,就是坚持让自动化系统具备可测量、可审计、可演进的工程属性。

评论 (0)

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

扫一扫,手机查看

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