微软公司宣布不再支持你正在使用的 IE浏览器,这会严重影响浏览网页,请使用微软最新的Edge浏览器
您好, 登录| 注册|

(PSIM仿真)教你C-Block模块巧用结构体变量

  • 2021-09-09 16:00
  • Richie_Li

    LV.0
  • 1697

    浏览

  • 6

    回复

  • 6

    获赞

  • 我们在用C-Block进行数字电源编程的时候,最常用到的是PI控制算法,如下一个常见的电压外环PI代码:

    /**********************************************************************************/

    //INV电压环参数定义

    double Inv_U_PID;

    const double Inv_U_K1=0.205;

    const double Inv_U_K2=0.2;

    double Inv_U_Error_0=0;

    double Inv_U_Error_1=0;

    //INV电流环参数

    Inv_U_Error_1 = Inv_U_Error_0;           //偏差计算(比例) 

    Inv_U_Error_0 =U_bus_avg-U_bus_set;                        //偏差计算(积分)

    Inv_U_PID+= Inv_U_K1 *  Inv_U_Error_0 -  Inv_U_K2 *  Inv_U_Error_1 ;                              

               //PID计算式,更改系数以获得理想的输出

    if( Inv_U_PID<-40)         //限制电压环输出     

      Inv_U_PID=-40;

    if( Inv_U_PID>40)    

            Inv_U_PID=40;

    /**********************************************************************************/

    PI算法的格式都是一样的,中间会涉及多个中间变量,如果我们的系统比较复杂,涉及多个PI环路,那这样我们的变量定义PI算法就会非常冗余,代码的可移植性就比较差;

    比如下面这个三相四桥臂正负序闭环控制系统:

    正序QD轴外环电压内环电流环和负序QD轴外环电压内环电流环,总共有8个PI控制环路,如果直接定义变量,以及各个环路的PI代码,这样代码量就非常大,而且相当冗余;

    怎样才能将代码简洁化,以及可移植性:我们可以用C语言的结构体去定义PI中间参数变量;以及把PI控制算法写成一个函数,单要调用PI算法时,就通过结构体变量调用PI算法函数,这样就可以避免同样结构的代码结构重复性编写;

    //------------------->PID.H<---------------------//
    typedef struct       //定义PI变量结构体
    {
    double   Tag;
    double   Current;
    double   Error_0;
    double   Error_1;
    double   Kp;
    double   Ki;
    double   Output;
    double   OutputMaxLimit;
    double   OutputMinLimit;
    }   stNamePID;
    void pid_set_tag(stNamePID* pPid, double Tag)
    {
    pPid->Tag=Tag;
    }
    void pid_set_Kp(stNamePID* pPid, double Kp)
    {
    pPid->Kp=Kp;
    }
    void pid_set_Ki(stNamePID* pPid, double Ki)
    {
    pPid->Ki=Ki;
    }
    void pid_set_OutputLimit(stNamePID* pPid, double   OutputMaxLimit, double   OutputMinLimit)
    {
    pPid->OutputMaxLimit =OutputMaxLimit;
    pPid->OutputMinLimit  =OutputMinLimit;
    }
    double pi_calc(stNamePID* pPid, double Current)
    {
    pPid->Current=Current;
    pPid->Error_1=pPid->Error_0;
    pPid->Error_0=pPid->Tag-pPid->Current;
    pPid->Output+=(pPid->Kp+ pPid->Ki)*pPid->Error_0 - pPid->Kp*pPid->Error_1;
    if((pPid->Output)>(pPid->OutputMaxLimit))
      pPid->Output = pPid->OutputMaxLimit;
    if((pPid->Output)<(pPid->OutputMinLimit))
     pPid->Output = pPid->OutputMinLimit;
    return   pPid->Output;
    }

    /----------------------------------------------------------------------------------/

    比如我们要用到电压外环,电流内环控制架构的时候;我们只需要定义下面结构体变量:

    /---------------------------------结构体变量定义--------------------------------------------/

    static  stNamePID  InvVoltPid={0}; //电压环PI结构体

    double VpidCalTemp=0;

    static stNamePID  InvCurrPid={0}; //电流环PI结构体

    double pidCalTemp=0;

    /----------------------------------------------------------------------------------/

    //**************电压外环*************//

     Inv_V_ref=U_out_cmd*cos(angle);

     pid_set_tag(&InvVoltPid,Inv_V_ref); 

    pid_set_Kp(&InvVoltPid, 0.02); 

    pid_set_Ki(&InvVoltPid, 0.01); 

    pid_set_OutputLimit(&InvVoltPid,Iout_max,-Iout_max); 

    VpidCalTemp=pi_calc(&InvVoltPid, U_out); 

    //**************电流内环**************//

     Inv_I_ref=VpidCalTemp ;     

     pid_set_tag(&InvCurrPid, Inv_I_ref); 

    pid_set_Kp(&InvCurrPid, 0.05); 

    pid_set_Ki(&InvCurrPid, 0.005); 

    pid_set_OutputLimit(&InvCurrPid,100,-100); 

    pidCalTemp=pi_calc(&InvCurrPid, I_out_avg);

    总结:在编程中学会一些小技巧,我们的代码编程就更加简洁,增强软件可移植性和可读性;

    同是电子工程师,请一定不要吝啬你的赞!

    6人已赞

    编辑 举报

    LV.1

    4257033

    2504993

    23

    781520

    说说你的看法

  • LV.

    @

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    取消
    发送
  • 现在还没有回复呢,说说你的想法

    现在还没有回复呢,说说你的想法

    全部回复(6)

  • yujunice

    LV.1

    2021-09-16 22:49

    @

    很不错的PI控制算法资料,收藏学习了!

    0

    设为最佳答案

    置顶

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    4257101

    2504993

    23

    786567

    取消
    发送
    2
  • iszjt

    LV.1

    2021-09-27 11:08

    @

    C block编程就是通过ACR的输出信号来控制四个开关管导通关断。 要实现四象限运行.

    0

    设为最佳答案

    置顶

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    4257204

    2504993

    23

    736255

    取消
    发送
    3
  • ruohan

    LV.1

    2021-11-08 11:16

    @iszjt

    C block编程就是通过ACR的输出信号来控制四个开关管导通关断。 要实现四象限运行.

    pPid->Output+=(pPid->Kp+ pPid->Ki)*pPid->Error_0 - pPid->Kp*pPid->Error_1;

    这个PI调节是(Kp+Ki)*Error0  -  Kp*Error1吗

    0

    设为最佳答案

    置顶

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    4257905

    2504993

    23

    213

    取消
    发送
    4
  • ruohan

    LV.1

    2021-11-08 11:40

    @

    电流环里面Inv_I_ref=VpidCalTemp ;     ,怎么把PID的量付给电流设定值啊,

    后边pidCalTemp=pi_calc(&InvCurrPid, I_out_avg);

    这样可以吗,

    0

    设为最佳答案

    置顶

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    4257907

    2504993

    23

    213

    取消
    发送
    5
  • Richie_Li

    LV.1

    2021-11-09 08:29

    @ruohan

    电流环里面Inv_I_ref=VpidCalTemp ;     ,怎么把PID的量付给电流设定值啊,

    后边pidCalTemp=pi_calc(&InvCurrPid, I_out_avg);

    这样可以吗,

    里面有个 pid_set_tag()函数,用来给定设定值的

    0

    设为最佳答案

    置顶

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    4257916

    2504993

    23

    781520

    取消
    发送
    6
  • Richie_Li

    LV.1

    2021-11-09 08:29

    @ruohan

    pPid->Output+=(pPid->Kp+ pPid->Ki)*pPid->Error_0 - pPid->Kp*pPid->Error_1;

    这个PI调节是(Kp+Ki)*Error0  -  Kp*Error1吗

    正确来说是这样的:

    pPid->Output=pPid->Output+(pPid->Kp+ pPid->Ki)*pPid->Error_0 - pPid->Kp*pPid->Error_1;

    0

    设为最佳答案

    置顶

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    4257917

    2504993

    23

    781520

    取消
    发送
    7
  • 现在还没有回复呢,说说你的想法

  • 回复

  • 收藏

  • 点赞

  • 举报有害信息

  • 已超出发布时间24小时,无法编辑与删除
    关于我们 联系方法 广告服务 会议服务 电子星球APP 网站地图 不良信息举报 热线:400-003-2006
    © 2002-2023 Netbroad(网博互动)公司版权所有 津ICP备 11006234号-2 联网备案号:12010402000747 增值电信业务经营许可证:津B2-20120058