回复:PID控制中的几个问题?

你以为你是谁

  • 帖子

    4695
  • 精华

    11
  • 被关注

    317

论坛等级:至圣

注册时间:2007-08-02

钻石 钻石 如何晋级?

发布于 2017-05-25 07:47:24

3楼

 IF COM_RST THEN //PID初始化
        sIanteilAlt := I_ITLVAL ;
        LMN := 0.0 ;
        QLMN_HLM := FALSE ;
        QLMN_LLM := FALSE ;
        LMN_P := 0.0 ;
        LMN_I := 0.0 ;
        LMN_D := 0.0 ;
        LMN_PER := W#16#0 ;
        PV := 0.0 ;
        ER := 0.0 ;
        sInvAlt := 0.0 ;
        sRestInt := 0.0 ;
        SRestDif := 0.0 ;
        sRueck := 0.0 ;
        sLmn := 0.0 ;
        sbArwHLmOn := FALSE ;
        sbArwLLmOn := FALSE ;
    ELSE
        rCycle := DINT_TO_REAL( TIME_TO_DINT( CYCLE ) ) / 1000.0 ;   //采样时间转换为浮点数值
        Istwert := DINT_TO_REAL( INT_TO_DINT( WORD_TO_INT ( PV_PER ) ) ) * 0.003616898 ;
        Istwert := Istwert * PV_FAC + PV_OFF ;    //外设输入转换为浮点数值
        IF NOT PVPER_ON THEN    //过程变量选择
            Istwert := PV_IN ;
        END_IF;
        PV := Istwert ;
        ErKp := SP_INT - PV ;        //计算偏差
        IF ErKp < -DEADB_W THEN
            ER := ErKp + DEADB_W ;
        ELSIF ErKp > DEADB_W THEN
            ER := ErKp - DEADB_W ;
        ELSE
            ER := 0.0 ;
        END_IF;
        ErKp := ER * GAIN ; //偏差比例增益
        rTi := DINT_TO_REAL( TIME_TO_DINT( TI ) ) / 1000.0 ;
        rTd := DINT_TO_REAL( TIME_TO_DINT( TD ) ) / 1000.0 ;
        rTmLag := DINT_TO_REAL( TIME_TO_DINT( TM_LAG ) ) / 1000.0 ;
        IF rTi < rCycle * 0.5 THEN      //积分时间必须 >= 采样时间的0.5倍
            rTi := rCycle * 0.5 ;
        END_IF;
        IF rTd < rCycle THEN            //微分时间必须 >= 采样时间
            rTd := rCycle ;
        END_IF;
        IF rTmLag < rCycle * 0.5 THEN   //微分作用延时时间必须 >= 采样时间的0.5倍
            rTmLag := rCycle * 0.5 ;
        END_IF;
        IF P_SEL THEN   //比例作用投入
            Panteil := ErKp ;
        ELSE
            Panteil := 0.0 ;
        END_IF;
        IF I_SEL THEN   //积分作用投入
            IF I_ITL_ON THEN    //积分初始化
                Ianteil := I_ITLVAL ;
                sRestInt := 0.0 ;
            ELSIF MAN_ON THEN   //手动值输入时的积分量计算,用于用于手动切换自动无扰切换
                Ianteil := sLmn - Panteil - DISV ;
                sRestInt := 0.0 ;
            ELSE    //积分计算
                Iant := ( rCycle / rTi ) * ( ErKp + sInvAlt ) * 0.5 + sRestInt ;
                IF ( ( Iant > 0.0 AND sbArwHLmOn ) OR INT_HOLD ) OR ( Iant < 0.0 AND sbArwLLmOn )THEN //抗积分饱和
                    Iant := 0.0 ;
                END_IF;
                Ianteil := sIanteilAlt + Iant ; //当前积分值 := 上时刻积分值 + 本次积分量
                sRestInt := sIanteilAlt - Ianteil  + Iant ; //感觉 sRestInt一直等于0.0 ;?????不知为何,通过运行发现不为0.0,可能是浮点数计算误差
            END_IF;            
        ELSE
            Ianteil := 0.0 ;
            sRestInt := 0.0 ;
        END_IF;
        Diff := ErKp ;
        IF NOT MAN_ON AND D_SEL THEN    //微分作用投入
            Verstaerk := rTd / ( rCycle * 0.5 + rTmLag ) ;
            Danteil := ( Diff - sRueck ) * Verstaerk ;
            RueckAlt := sRueck ;
            RueckDiff := rCycle / rTd * Danteil + sRestDif ;
            sRueck := RueckDiff + RueckAlt ;
            sRestDif := RueckAlt - sRueck + RueckDiff ; //同积分一样计算微分误差量
        ELSE    //
            Danteil := 0.0 ;
            sRestDif := 0.0 ;
            sRueck := Diff ;
        END_IF;
        dLmn := Panteil + Ianteil + Danteil + DISV ; //PID输出
        IF MAN_ON THEN //PID手动之打开
            dLmn := MAN ;
        ELSE
            IF NOT I_ITL_ON AND I_SEL THEN  //干扰量处理
                IF Ianteil > LMN_HLM - DISV AND dLmn > LMN_HLM AND dLmn - LMN_D > LMN_HLM THEN
                    rVal := LMN_HLM - DISV ;
                    gf := dLmn - LMN_HLM ;
                    rVal := Ianteil - rVal ;
                    IF rVal > gf THEN
                        rVal := gf ;
                    END_IF;
                    Ianteil := Ianteil - rVal ;
                ELSIF Ianteil < LMN_LLM - DISV AND dLmn < LMN_LLM  AND dLmn - LMN_D < LMN_LLM  THEN
                    rVal := LMN_LLM - DISV ;
                    gf := dLmn - LMN_LLM ;
                    rVal := Ianteil - rVal ;
                    IF rVal < gf THEN
                        rVal := gf ;
                    END_IF;
                    Ianteil := Ianteil - rVal ;
                END_IF;
            END_IF;
        END_IF;
        LMN_P := Panteil ;
        LMN_I := Ianteil ;
        LMN_D := Danteil ;
        sInvAlt := Erkp ;
        sIanteilAlt := Ianteil ;
        sbArwHLmOn := FALSE ;
        sbArwLLmOn := FALSE ;
        IF dlmn >= LMN_HLM  THEN    //调节辆限幅(上限)
            QLMN_HLM := TRUE ;
            QLMN_LLM := FALSE ;
            dlmn := LMN_HLM ;
            sbArwHLmOn := TRUE ;
        ELSE
            QLMN_HLM := FALSE ;
            IF dLmn <= LMN_LLM THEN  //调节辆限幅(下限)
                QLMN_LLM := TRUE ;
                dlmn := LMN_LLM ;
                sbArwLLmOn := TRUE ;
            ELSE
                QLMN_LLM := FALSE ;
            END_IF;
        END_IF;
        sLmn := dLmn ;
        dLmn := dLmn * LMN_FAC + LMN_OFF ;
        LMN := dLmn ;
        dLmn := dLmn* 276.48 ;
        IF dLmn >= 32512.0 THEN
            dLmn := 32512.0 ;
        ELSIF dLmn <= -32512.0 THEN
            dLmn := -32512.0 ;
        END_IF;
        LMN_PER := INT_TO_WORD( DINT_TO_INT( REAL_TO_DINT( dLmn) ) ) ;
    END_IF;
END_FUNCTION_BLOCK


PCS7系统爱好者,技术交流:617522577@qq.com
评论
编辑推荐: 关闭

请填写推广理由:

本版热门话题

SIMATIC S7-300/400

共有54761条技术帖

相关推荐

热门标签

相关帖子推荐

guzhang

恭喜,你发布的帖子

评为精华帖!

快扫描右侧二维码晒一晒吧!

再发帖或跟帖交流2条,就能晋升VIP啦!开启更多专属权限!

  • 分享

  • 只看
    楼主

top
X 图片
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。