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}} $$
该式可拆解为两步:
- 归一化(Normalization):将 $x$ 映射至 $[0.0, 1.0]$ 区间,记为 $u$:
$$ u = \frac{x - x_{\text{min}}}{x_{\text{max}} - x_{\text{min}}} $$ - 缩放(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_X 和 SCALE_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
⚠️ 关键约束:
MIN和MAX必须满足MIN < MAX,否则STATUS置 FALSE,OUT保持上一次有效值(非锁存)。NORM_X对IN超出[MIN, MAX]时仍执行计算(如IN=25.0,MIN=4.0,MAX=20.0→OUT=1.3125),但STATUS为 FALSE,提示信号异常。SCALE_X仅当IN在[0.0, 1.0]内才置STATUS:=TRUE;若IN=-0.1或1.05,STATUS:=FALSE,OUT不更新(保持历史值),避免误触发控制逻辑。
三、典型应用场景与完整ST代码示例
场景1:4–20 mA温度变送器(0–150 ℃)
传感器输出4 mA对应0 ℃,20 mA对应150 ℃。AI模块配置为“27647”(16位有符号整数满量程),需将 INT 转 REAL 后标准化。
// 变量声明(全局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_inst的MIN/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.0→press_norm = 0.0→press_kpa = -200.0- 当
ai_press_v = 0.0→press_norm = 0.5→press_kpa = (-200 + 800)/2 = 300.0- 当
ai_press_v = +10.0→press_norm = 1.0→press_kpa = 800.0
完全符合线性预期。
四、错误规避:5类高频陷阱与修正方案
| 错误类型 | 典型表现 | 后果 | 修正方法 |
|---|---|---|---|
| 参数倒置 | NORM_X(IN:=x, MIN:=20.0, MAX:=4.0) |
STATUS:=FALSE,OUT 无效 |
严格检查 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 |
| 整数除法截断 | IN 为 INT,MIN/MAX 为 INT,未转 REAL |
编译报错或隐式截断(如 5/2=2) |
所有数值常量加 # 后缀:MIN:=4.0#, MAX:=20.0# |
| 量程混淆 | 将AI硬件量程(如0–27647)误作信号量程(4–20 mA) | 归一化结果整体偏移 | 建立查表或计算函数,将ADC值→物理量(mA/V)作为 NORM_X.IN 输入 |
| 浮点精度累积 | 连续多次 NORM_X→SCALE_X→NORM_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.OUT和SCALE_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功能安全对“故障检测覆盖率”的强制要求。
九、调试黄金法则
- 分段注入测试值:在仿真中,跳过AI读取,直接给
NORM_X.IN := 4.0#、8.0#、20.0#,验证OUT是否为0.0、0.25、1.0; - 监控中间态:将
NORM_X.OUT和SCALE_X.STATUS同时写入在线监控表,一眼识别故障环节; - 边界压测:输入
MIN - 0.1和MAX + 0.1,确认STATUS正确置 FALSE; - 单位一致性审计:所有
REAL变量命名强制带单位缩写(_ma、_v、_c、_kpa),禁止出现value1、data2等模糊标识。
十、总结:标准化不是选项,是规范
NORM_X 与 SCALE_X 不是语法糖,而是IEC 61131-3为解决模拟量工程化落地而内置的契约式接口。它将“量程配置”从代码逻辑中剥离,升格为参数化配置项;将“信号质量判断”从 IF x > 20.5 THEN ... 的散点判断,收敛为统一的 STATUS 旗标;将“跨系统数据交换”锚定在无量纲的 [0.0, 1.0] 中间态。坚持使用,就是坚持让自动化系统具备可测量、可审计、可演进的工程属性。

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