denghuagong
级别: 探索解密
精华主题: 0
发帖数量: 27 个
工控威望: 174 点
下载积分: 1950 分
在线时间: 74(小时)
注册时间: 2011-10-15
最后登录: 2026-04-01
查看denghuagong的 主题 / 回贴
楼主  发表于: 4天前
SET  
      SAVE  
      =     L     68.1
      A     #COM_RST
      JCN   A7d0
      L     #I_ITLVAL
      T     #sIanteilAlt
      L     0.000000e+00
      T     #LMN
      CLR  
      =     #QLMN_HLM
      =     #QLMN_LLM
      T     #LMN_P
      T     #LMN_I
      T     #LMN_D
      L     W#16#0
      T     #LMN_PER
      TAK  
      T     #PV
      T     #ER
      T     #sInvAlt
      T     #sRestInt
      T     #sRestDif
      T     #sRueck
      T     #sLmn
      =     #sbArwHLmOn
      =     #sbArwLLmOn
      JU    A7d1
A7d0: L     #CYCLE
      DTR  
      L     1.000000e+03
      /R    
      T     #rCycle
      L     #PV_PER
      ITD  
      DTR  
      L     3.616898e-03
      *R    
      T     #Istwert
      L     #PV_FAC
      *R    
      L     #PV_OFF
      +R    
      T     #Istwert
      CLR  
      A     #PVPER_ON
      NOT  
      JCN   A7d2
      L     #PV_IN
      T     #Istwert
A7d2: L     #Istwert
      T     #PV
      L     #SP_INT
      TAK  
      -R    
      T     #ErKp
      L     #DEADB_W
      NEGR  
      <R    
      JCN   A7d3
      L     #ErKp
      L     #DEADB_W
      +R    
      T     #ER
      JU    A7d4
A7d3: L     #ErKp
      L     #DEADB_W
      >R    
      JCN   A7d5
      L     #ErKp
      TAK  
      -R    
      T     #ER
      JU    A7d4
A7d5: L     0.000000e+00
      T     #ER
A7d4: L     #ER
      L     #GAIN
      *R    
      T     #ErKp
      L     #TI
      DTR  
      L     1.000000e+03
      /R    
      T     #rTi
      L     #TD
      DTR  
      L     1.000000e+03
      /R    
      T     #rTd
      L     #TM_LAG
      DTR  
      L     1.000000e+03
      /R    
      T     #rTmLag
      L     #rCycle
      L     5.000000e-01
      *R    
      L     #rTi
      TAK  
      <R    
      JCN   A7d7
      L     #rCycle
      L     5.000000e-01
      *R    
      T     #rTi
A7d7: L     #rTd
      L     #rCycle
      <R    
      JCN   A7d8
      T     #rTd
A7d8: L     #rCycle
      L     5.000000e-01
      *R    
      L     #rTmLag
      TAK  
      <R    
      JCN   A7d9
      L     #rCycle
      L     5.000000e-01
      *R    
      T     #rTmLag
A7d9: CLR  
      A     #P_SEL
      JCN   A7da
      L     #ErKp
      T     #Panteil
      JU    A7db
A7da: L     0.000000e+00
      T     #Panteil
A7db: CLR  
      A     #I_SEL
      JCN   A7dc
      A     #I_ITL_ON
      JCN   A7dd
      L     #I_ITLVAL
      T     #Ianteil
      L     0.000000e+00
      T     #sRestInt
      JU    A7e2
A7dd: CLR  
      A     #MAN_ON
      JCN   A7df
      L     #sLmn
      L     #Panteil
      -R    
      L     #DISV
      -R    
      T     #Ianteil
      L     0.000000e+00
      T     #sRestInt
      JU    A7e0
A7df: L     #rCycle
      L     #rTi
      /R    
      L     #ErKp
      TAK  
      T     LD    70
      TAK  
      L     #sInvAlt
      +R    
      L     LD    70
      *R    
      L     5.000000e-01
      *R    
      L     #sRestInt
      +R    
      T     #Diff
      L     0.000000e+00
      >R    
      A     #sbArwHLmOn
      O     #INT_HOLD
      L     #Diff
      L     0.000000e+00
      =     L     68.2
      <R    
      A     #sbArwLLmOn
      O     L     68.2
      JCN   A7e1
      T     #Diff
A7e1: L     #sIanteilAlt
      L     #Diff
      +R    
      T     #Ianteil
      L     #sIanteilAlt
      TAK  
      -R    
      L     #Diff
      +R    
      T     #sRestInt
A7e0: JU    A7e2
A7dc: L     0.000000e+00
      T     #Ianteil
      T     #sRestInt
A7e2: L     #ErKp
      T     #Diff
      CLR  
      A     #MAN_ON
      NOT  
      A     #D_SEL
      JCN   A7e3
      L     #rCycle
      L     5.000000e-01
      *R    
      L     #rTmLag
      +R    
      L     #rTd
      TAK  
      /R    
      T     #Verstaerk
      L     #Diff
      L     #sRueck
      -R    
      L     #Verstaerk
      *R    
      T     #Danteil
      L     #sRueck
      T     #RueckAlt
      L     #rCycle
      L     #rTd
      /R    
      L     #Danteil
      *R    
      L     #sRestDif
      +R    
      T     #RueckDiff
      L     #RueckAlt
      +R    
      T     #sRueck
      L     #RueckAlt
      TAK  
      -R    
      L     #RueckDiff
      +R    
      T     #sRestDif
      JU    A7e4
A7e3: L     0.000000e+00
      T     #Danteil
      T     #sRestDif
      L     #Diff
      T     #sRueck
A7e4: L     #Panteil
      L     #Ianteil
      +R    
      L     #Danteil
      +R    
      L     #DISV
      +R    
      T     #dLmn
      CLR  
      A     #MAN_ON
      JCN   A7e5
      L     #MAN
      T     #dLmn
      JU    A7e7
A7e5: CLR  
      A     #I_ITL_ON
      NOT  
      A     #I_SEL
      JCN   A7e7
      L     #LMN_HLM
      L     #DISV
      -R    
      L     #Ianteil
      TAK  
      >R    
      L     #dLmn
      L     #LMN_HLM
      =     L     68.2
      >R    
      A     L     68.2
      L     #dLmn
      L     #LMN_D
      -R    
      L     #LMN_HLM
      =     L     68.2
      >R    
      A     L     68.2
      JCN   A7e8
      L     #DISV
      -R    
      T     #rVal
      L     #dLmn
      L     #LMN_HLM
      -R    
      T     #gf
      L     #Ianteil
      L     #rVal
      -R    
      T     #rVal
      L     #gf
      >R    
      JCN   A7e9
      T     #rVal
A7e9: L     #Ianteil
      L     #rVal
      -R    
      T     #Ianteil
      JU    A7e7
A7e8: L     #LMN_LLM
      L     #DISV
      -R    
      L     #Ianteil
      TAK  
      <R    
      L     #dLmn
      L     #LMN_LLM
      =     L     68.2
      <R    
      A     L     68.2
      L     #dLmn
      L     #LMN_D
      -R    
      L     #LMN_LLM
      =     L     68.2
      <R    
      A     L     68.2
      JCN   A7e7
      L     #DISV
      -R    
      T     #rVal
      L     #dLmn
      L     #LMN_LLM
      -R    
      T     #gf
      L     #Ianteil
      L     #rVal
      -R    
      T     #rVal
      L     #gf
      <R    
      JCN   A7ec
      T     #rVal
A7ec: L     #Ianteil
      L     #rVal
      -R    
      T     #Ianteil
A7e7: L     #Panteil
      T     #LMN_P
      L     #Ianteil
      T     #LMN_I
      L     #Danteil
      T     #LMN_D
      L     #ErKp
      T     #sInvAlt
      L     #Ianteil
      T     #sIanteilAlt
      CLR  
      =     #sbArwHLmOn
      =     #sbArwLLmOn
      L     #dLmn
      L     #LMN_HLM
      >=R  
      JCN   A7ed
      SET  
      =     #QLMN_HLM
      CLR  
      =     #QLMN_LLM
      T     #dLmn
      SET  
      =     #sbArwHLmOn
      JU    A7ee
A7ed: CLR  
      =     #QLMN_HLM
      L     #dLmn
      L     #LMN_LLM
      <=R  
      JCN   A7ef
      SET  
      =     #QLMN_LLM
      T     #dLmn
      =     #sbArwLLmOn
      JU    A7ee
A7ef: CLR  
      =     #QLMN_LLM
A7ee: L     #dLmn
      T     #sLmn
      L     #LMN_FAC
      *R    
      L     #LMN_OFF
      +R    
      T     #dLmn
      T     #LMN
      L     2.764800e+02
      *R    
      T     #dLmn
      L     3.251100e+04
      >=R  
      JCN   A7f1
      T     #dLmn
      JU    A7f2
A7f1: L     #dLmn
      L     -3.251200e+04
      <=R  
      JCN   A7f2
      T     #dLmn
A7f2: L     #dLmn
      RND  
      T     #LMN_PER
A7d1: CLR  
      A     L     68.1
      SAVE  
      BE    
附件: STL.doc (40 K) 下载次数:10
zx1234
级别: 论坛先锋
精华主题: 0
发帖数量: 923 个
工控威望: 1285 点
下载积分: 8177 分
在线时间: 654(小时)
注册时间: 2012-10-02
最后登录: 2026-04-01
查看zx1234的 主题 / 回贴
1楼  发表于: 4天前
这段代码是西门子S7系列PLC的标准PID控制功能块(FB41 "CONT_C")的STL语句表源码,是工业控制中最经典的连续量PID算法实现,我帮你完整解析其结构、原理和每段逻辑作用:

一、整体功能定位

这是CONT_C FB41的核心STL实现,用于连续量PID调节,包含:

- 复位初始化
- 过程值PV处理与标定
- 死区非线性处理
- 比例P、积分I、微分D分离计算
- 抗积分饱和(Clamping Anti-Windup)
- 手动/自动切换
- 输出限幅与百分比转换
- 周期时间标定与离散化处理

二、代码分段详细解析

1. 复位初始化段(A7d0之前)

SET
SAVE
=     L     68.1
A     #COM_RST
JCN   A7d0
 

-  COM_RST=1  时执行冷启动复位
- 清零所有中间变量、PID分量、状态位
- 初始化历史值寄存器( sIanteilAlt 、 sRueck 等)
- 跳转到A7d1结束本次扫描

2. 周期时间与过程值PV处理(A7d0开始)

L     #CYCLE
DTR
L     1.000000e+03
/R
T     #rCycle
 

- 将调用周期 CYCLE (ms)转为秒 rCycle ,用于离散PID计算

L     #PV_PER
ITD
DTR
L     3.616898e-03
*R
T     #Istwert
L     #PV_FAC
*R
L     #PV_OFF
+R
T     #Istwert
 

- 模拟量输入 PV_PER (0~27648)标定转换为工程值 Istwert 
- 支持 PVPER_ON 选择直接使用 PV_IN 浮点数

3. 偏差计算与死区处理

L     #SP_INT
TAK
-R
T     #ErKp
L     #DEADB_W
NEGR
<R
JCN   A7d3
...
 

- 计算设定值SP与过程值PV的偏差 ErKp 
- 死区 DEADB_W 判断:死区内偏差ER=0,抑制小幅度振荡

4. PID参数时间常数转换

L     #TI
DTR
L     1.000000e+03
/R
T     #rTi

L     #TD
DTR
L     1.000000e+03
/R
T     #rTd
 

- 积分时间TI、微分时间TD(ms)→ 秒 rTi / rTd 
- 同时做最小时间钳位,避免分母为0或算法不稳定

5. 比例分量P计算

A     #P_SEL
JCN   A7da
L     #ErKp
T     #Panteil
 

-  P_SEL=1 启用比例, Panteil = GAIN * ER 
- 否则P分量清零

6. 积分分量I计算(核心抗积分饱和)

A     #I_ITL_ON
JCN   A7dd
L     #I_ITLVAL
T     #Ianteil
 

-  I_ITL_ON 积分初始化赋值
- 手动模式 MAN_ON 时积分跟踪输出,实现无扰切换
- 采用**梯形积分(Trapezoidal Integration)**提高精度
- 关键逻辑:输出限幅时抑制积分累积(Anti-Windup)
-  sbArwHLmOn / sbArwLLmOn 饱和标志
- 积分增量被钳位,防止积分饱和失控

7. 微分分量D计算

A     #D_SEL
JCN   A7e3
L     #rCycle
L     5.000000e-01
*R
L     #rTmLag
+R
L     #rTd
TAK
/R
T     #Verstaerk
 

- 带一阶滤波 TM_LAG 的微分算法,抑制噪声
- 微分针对偏差变化率计算,避免设定值跳变引起冲击

8. 输出合成与手动/自动切换

L     #Panteil
L

这是豆包解读的