; 将原始 ADC 值()转换为工程量(PV) ; 请把下列常量改成你的模块/传感器实际值 ; 例:AI_Raw_Min=0、AI_Raw_Max=32000;工程量 0~100.0 PV := (AI_Raw - AI_Raw_Min) * (PV_Max - PV_Min) / (AI_Raw_Max - AI_Raw_Min) + PV_Min;
常见原始量程:0~32000、0~27648、0~4000(不同模块不同)。请查拟用模块手册并替换AI_Raw_Min/Max。
; 将 MV(0~100%) 映射到 AO 原始输出 AO_Raw := INT( MV/100.0 * AO_FullScale ); ; AO_FullScale 按模块实际:如 32000 或 4000
若用 4–20mA 执行器,记得在现场器件上做“最小/最大”拨码或参数校准。
优点:完全可控、参数清晰;适合你把变量直接映射到 HMI。
(* 文件:FB_PID.st — 在 ISPSoft 新建 Function Block *)
FUNCTION_BLOCK FB_PID
VAR_INPUT
Enable : BOOL;
SP : REAL; (* 设定 *)
PV : REAL; (* 测量 *)
Kp : REAL; (* 比例增益 *)
Ti_s : REAL; (* 积分时间[s] 0=禁用I *)
Td_s : REAL; (* 微分时间[s] 0=禁用D *)
Ts_s : REAL; (* 采样周期[s] *)
MV_Min : REAL; (* 输出下限[%] *)
MV_Max : REAL; (* 输出上限[%] *)
Mode_Auto : BOOL; (* TRUE=自动; FALSE=手动 *)
ManMV : REAL; (* 手动输出[%] *)
AW_Enable : BOOL; (* 抗积分饱和 *)
D_OnPV : BOOL; (* 微分对PV(推荐TRUE) *)
END_VAR
VAR_OUTPUT
MV : REAL; (* 输出[%] *)
Err : REAL; (* 误差 *)
END_VAR
VAR
Iterm, PrevPV, PrevErr : REAL;
FirstScan : BOOL := TRUE;
P, I, D, U : REAL;
END_VAR
IF NOT Enable THEN
MV := 0.0; Iterm := 0.0; PrevPV := PV; PrevErr := 0.0; RETURN;
END_IF;
Err := SP - PV;
(* P *)
P := Kp * Err;
(* I *)
IF Ti_s > 0.0 THEN
Iterm := Iterm + (Kp * (Ts_s/Ti_s) * Err);
END_IF;
(* D *)
IF Td_s > 0.0 THEN
IF D_OnPV THEN
D := -Kp * (Td_s/Ts_s) * (PV - PrevPV);
ELSE
D := Kp * (Td_s/Ts_s) * (Err - PrevErr);
END_IF;
ELSE
D := 0.0;
END_IF;
(* 手/自动与输出限幅 *)
IF Mode_Auto THEN
U := P + Iterm + D;
(* 限幅 *)
IF U > MV_Max THEN
U := MV_Max;
IF AW_Enable AND Ti_s > 0.0 THEN
(* 抗积分饱和:扣回积分 *)
Iterm := Iterm - (U - MV_Max);
END_IF;
ELSIF U < MV_Min THEN
U := MV_Min;
IF AW_Enable AND Ti_s > 0.0 THEN
Iterm := Iterm - (U - MV_Min);
END_IF;
END_IF;
MV := U;
ELSE
(* 手动 *)
MV := ManMV;
END_IF;
PrevPV := PV;
PrevErr := Err;
END_FUNCTION_BLOCK
(* 文件:PRG_MAIN.st — 周期任务里调用 *) VAR pid : FB_PID; END_VAR (* 采样周期 0.10s。若你的任务周期不同,请改 Ts_s *) pid( Enable := TRUE, SP := SP, PV := PV, Kp := Kp, Ti_s := Ti_s, Td_s := Td_s, Ts_s := 0.10, MV_Min := MV_Min, (* 如 0.0 *) MV_Max := MV_Max, (* 如 100.0 *) Mode_Auto := Mode_Auto, (* HMI 切换 *) ManMV := ManMV, (* 手动输出 *) AW_Enable := AW_Enable, (* 抗饱和 *) D_OnPV := D_OnPV (* 推荐 TRUE *) ); MV := pid.MV; (* 接 AO 标定 *)
| 步骤 | 操作 | 建议值/说明 |
|---|---|---|
| ① 只开 P | 先设Ti_s=0, Td_s=0,逐步提高Kp | 系统刚好不振荡时的 50~70% |
| ② 加 I | 设Ti_s为过程时间常数的 1~3 倍 | 看稳态误差消除速度,过冲大就加大Ti_s |
| ③ 视需要加 D | Td_s占Ti_s的 1/10~1/3 | 抑制超调;信号噪声大时可不加 D |
| ④ 限幅与防饱和 | 设置MV_Min/MV_Max与AW_Enable=TRUE | 保护执行器,避免长时间顶住 |