紫外工控论坛

 找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

搜索
查看: 3626|回复: 0

C语言实现PID算法

[复制链接]
冰糖 发表于 2010-7-13 21:15:52 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
C语言实现PID算法
关键词 PID pid算法 pid控制算法 pid程序 pid调节


BC31 TC30 编译过,可运行。
  
  
 
  1.  #include
  2.   #include
  3.   
  4.   struct _pid {
  5.    int pv; /*integer that contains the process value*/
  6.    int sp; /*integer that contains the set point*/
  7.    float integral;
  8.    float pgain;
  9.    float igain;
  10.    float dgain;
  11.    int deadband;
  12.    int last_error;
  13.   };
  14.   
  15.   struct _pid warm,*pid;
  16.   int process_point, set_point,dead_band;
  17.   float p_gain, i_gain, d_gain, integral_val,new_integ;;
  18.   
  19.   
  20.   
  21.   /*------------------------------------------------------------------------
  22.   pid_init
  23.   
  24.   DESCRIPTION This function initializes the pointers in the _pid structure
  25.   to the process variable and the setpoint. *pv and *sp are
  26.   integer pointers.
  27.   ------------------------------------------------------------------------*/
  28.   void pid_init(struct _pid *warm, int process_point, int set_point)
  29.   {
  30.    struct _pid *pid;
  31.   
  32.    pid = warm;
  33.    pid->pv = process_point;
  34.    pid->sp = set_point;
  35.   }
  36.   
  37.   
  38.   /*------------------------------------------------------------------------
  39.   pid_tune
  40.   
  41.   DESCRIPTION Sets the proportional gain (p_gain), integral gain (i_gain),
  42.   derivitive gain (d_gain), and the dead band (dead_band) of
  43.   a pid control structure _pid.
  44.   ------------------------------------------------------------------------*/
  45.   
  46.   void pid_tune(struct _pid *pid, float p_gain, float i_gain, float d_gain, int dead_band)
  47.   {
  48.    pid->pgain = p_gain;
  49.    pid->igain = i_gain;
  50.    pid->dgain = d_gain;
  51.    pid->deadband = dead_band;
  52.    pid->integral= integral_val;
  53.    pid->last_error=0;
  54.   }
  55.   
  56.   /*------------------------------------------------------------------------
  57.   pid_setinteg
  58.   
  59.   DESCRIPTION Set a new value for the integral term of the pid equation.
  60.   This is useful for setting the initial output of the
  61.   pid controller at start up.
  62.   ------------------------------------------------------------------------*/
  63.   void pid_setinteg(struct _pid *pid,float new_integ)
  64.   {
  65.    pid->integral = new_integ;
  66.    pid->last_error = 0;
  67.   }
  68.   
  69.   /*------------------------------------------------------------------------
  70.   pid_bumpless
  71.   
  72.   DESCRIPTION Bumpless transfer algorithim. When suddenly changing
  73.   setpoints,   or when restarting the PID equation after an
  74.   extended pause, the derivative of the equation can cause
  75.   a bump in the controller output. This function will help
  76.   smooth out that bump. The process value in *pv should
  77.   be the updated just before this function is used.
  78.   ------------------------------------------------------------------------*/
  79.   void pid_bumpless(struct _pid *pid)
  80.   {
  81.   
  82.    pid->last_error = (pid->sp)-(pid->pv);
  83.   
  84.   }
  85.   
  86.   /*------------------------------------------------------------------------
  87.   pid_calc
  88.   
  89.   DESCRIPTION Performs PID calculations for the _pid structure *a. This function uses the positional form of the pid equation, and incorporates an integral windup prevention algorithim. Rectangular integration is used, so this function must be repeated on a consistent time basis for accurate control.
  90.   
  91.   RETURN VALUE The new output value for the pid loop.
  92.   
  93.   USAGE #include "control.h"*/
  94.   
  95.   
  96.   float pid_calc(struct _pid *pid)
  97.   {
  98.    int err;
  99.    float pterm, dterm, result, ferror;
  100.   
  101.    err = (pid->sp) - (pid->pv);
  102.    if (abs(err) > pid->deadband)
  103.    {
  104.    ferror = (float) err; /*do integer to float conversion only once*/
  105.    pterm = pid->pgain * ferror;
  106.    if (pterm > 100 || pterm < -100)
  107.    {
  108.    pid->integral = 0.0;
  109.    }
  110.    else
  111.    {
  112.    pid->integral += pid->igain * ferror;
  113.    if (pid->integral > 100.0)
  114.    {
  115.    pid->integral = 100.0;
  116.    }
  117.    else if (pid->integral < 0.0) pid->integral = 0.0;
  118.    }
  119.    dterm = ((float)(err - pid->last_error)) * pid->dgain;
  120.    result = pterm + pid->integral + dterm;
  121.    }
  122.    else result = pid->integral;
  123.    pid->last_error = err;
  124.    return (result);
  125.   }
  126.   
  127.   
  128.   void main(void)
  129.   {
  130.    float display_value;
  131.    int count=0;
  132.   
  133.    pid = &warm;
  134.   
  135.   // printf("Enter the values of Process point, Set point, P gain, I gain, D gain \n");
  136.   // scanf("%d%d%f%f%f", &process_point, &set_point, &p_gain, &i_gain, &d_gain);
  137.   
  138.   
  139.   
  140.    process_point = 30;
  141.    set_point = 40;
  142.    p_gain = (float)(5.2);
  143.    i_gain = (float)(0.77);
  144.    d_gain = (float)(0.18);
  145.   
  146.   
  147.   
  148.    dead_band = 2;
  149.    integral_val =(float)(0.01);
  150.   
  151.   
  152.    printf("The values of Process point, Set point, P gain, I gain, D gain \n");
  153.    printf(" %6d %6d %4f %4f %4f\n", process_point, set_point, p_gain, i_gain, d_gain);
  154.   
  155.    printf("Enter the values of Process point\n");
  156.   
  157.    while(count<=20)
  158.    {
  159.   
  160.   
  161.   
  162.    scanf("%d",&process_point);
  163.   
  164.    pid_init(&warm, process_point, set_point);
  165.    pid_tune(&warm, p_gain,i_gain,d_gain,dead_band);
  166.    pid_setinteg(&warm,0.0); //pid_setinteg(&warm,30.0);
  167.   
  168.    //Get input value for process point
  169.    pid_bumpless(&warm);
  170.   
  171.    // how to display output
  172.    display_value = pid_calc(&warm);
  173.    printf("%f\n", display_value);
  174.    //printf("\n%f%f%f%f",warm.pv,warm.sp,warm.igain,warm.dgain);
  175.    count++;
  176.   
  177.    }
  178.   
  179.   }
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


--------------------------------------------------------------------------------------------------------------------
本站是工控技术交流站点,论坛内容均为网络收集或会员所发表,并不代表本站立场,会员拥有该内容的所有权力及责任!
本站内容如有侵犯您的版权,请按下面方式联系本站管理员,我们将及时删除处理
管理员:冰糖 QQ:5483695(请直击主题), Mail:admin#ziwai.net(#改成@) 其它非本人.
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论!

QQ|Archiver|手机版|小黑屋|紫外工控论坛. ( 苏ICP备11032118号-1 )

GMT+8, 2024-5-14 10:30 , Processed in 0.265625 second(s), 17 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表