标准PID源程序:) 点击:10120 | 回复:49



gongkongedit

    
  • 精华:1099帖
  • 求助:0帖
  • 帖子:14392帖 | 54470回
  • 年度积分:0
  • 历史总积分:622
  • 注册:2008年9月08日
发表于:2004-02-24 12:57:00
楼主
标准的PID处理例程 --- 工业控制中常用算法 --- /*==================================================================================================== 这是从网上找来的一个比较典型的PID处理程序,在使用单片机作为控制cpu时,请稍作简化,具体的PID 参数必须由具体对象通过实验确定。由于单片机的处理速度和ram资源的限制,一般不采用浮点数运算, 而将所有参数全部用整数,运算到最后再除以一个2的N次方数据(相当于移位),作类似定点数运算,可 大大提高运算速度,根据控制精度的不同要求,当精度要求很高时,注意保留移位引起的“余数”,做好余 数补偿。这个程序只是一般常用pid算法的基本架构,没有包含输入输出处理部分。 =====================================================================================================*/ #include <string.h> #include <stdio.h> /*==================================================================================================== PID Function The PID (比例、积分、微分) function is used in mainly control applications. PIDCalc performs one iteration of the PID algorithm. While the PID function works, main is just a dummy program showing a typical usage. =====================================================================================================*/ typedef struct PID { double SetPoint; // 设定目标 Desired Value double Proportion; // 比例常数 Proportional Const double Integral; // 积分常数 Integral Const double Derivative; // 微分常数 Derivative Const double LastError; // Error[-1] double PrevError; // Error[-2] double SumError; // Sums of Errors } PID; /*==================================================================================================== PID计算部分 =====================================================================================================*/ double PIDCalc( PID *pp, double NextPoint ) { double dError, Error; Error = pp->SetPoint - NextPoint; // 偏差 pp->SumError += Error; // 积分 dError = pp->LastError - pp->PrevError; // 当前微分 pp->PrevError = pp->LastError; pp->LastError = Error; return (pp->Proportion * Error // 比例项 + pp->Integral * pp->SumError // 积分项 + pp->Derivative * dError // 微分项 ); } /*==================================================================================================== Initialize PID Structure =====================================================================================================*/ void PIDInit (PID *pp) { memset ( pp,0,sizeof(PID)); } /*==================================================================================================== Main Program =====================================================================================================*/ double sensor (void) // Dummy Sensor Function { return 100.0; } void actuator(double rDelta) // Dummy Actuator Function {} void main(void) { PID sPID; // PID Control Structure double rOut; // PID Response (Output) double rIn; // PID Feedback (Input) PIDInit ( &sPID ); // Initialize Structure sPID.Proportion = 0.5; // Set PID Coefficients sPID.Integral = 0.5; sPID.Derivative = 0.0; sPID.SetPoint = 100.0; // Set PID Setpoint for (;;) { // Mock Up of PID Processing rIn = sensor (); // Read Input rOut = PIDCalc ( &sPID,rIn ); // Perform PID Interation actuator ( rOut ); // Effect Needed Changes } }



hotboy

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 7回
  • 年度积分:0
  • 历史总积分:60
  • 注册:2003年12月08日
发表于:2003-12-29 17:03:00
21楼
TO:楼主 万分感谢!雪中送炭! 能否留个联系方式

謝聰敏

  • 精华:0帖
  • 求助:0帖
  • 帖子:2帖 | 246回
  • 年度积分:0
  • 历史总积分:351
  • 注册:2002年9月23日
发表于:2003-12-30 15:49:00
22楼
To: hotboy 您可以撥021-6247-1722找到他.

yhsu

  • 精华:1帖
  • 求助:0帖
  • 帖子:5帖 | 98回
  • 年度积分:0
  • 历史总积分:126
  • 注册:2002年7月04日
发表于:2003-12-30 16:13:00
23楼
我是 苏元华 电话:021-62471724 MSN:suyuanhua@hotmail.com ASM的你用c编译后,用ASM的工具打开EXE看喽:) 最初的帖子是用整数的。 下面的代码是用浮点的源码: #include <stdio.h> #include<math.h> struct _pid { int pv; /*integer that contains the process value Êä³ö*/ int sp; /*integer that contains the set point É趨µã*/ float integral; //»ý·Ö float pgain; float igain; float dgain; int deadband; int last_error; }; struct _pid warm,cold,*pid; int process_point, set_point,dead_band; float p_gain, i_gain, d_gain, integral_val,new_integ;; /*------------------------------------------------------------------------ pid_init DESCRIPTION This function initializes the pointers in the _pid structure to the process variable and the setpoint. *pv and *sp are integer pointers. ------------------------------------------------------------------------*/ void pid_init(struct _pid *warm, int process_point, int set_point) { struct _pid *pid; pid = warm; pid->pv = process_point; pid->sp = set_point; } /*------------------------------------------------------------------------ pid_tune DESCRIPTION Sets the proportional gain (p_gain), integral gain (i_gain), derivitive gain (d_gain), and the dead band (dead_band) of a pid control structure _pid. ------------------------------------------------------------------------*/ void pid_tune(struct _pid *pid, float p_gain, float i_gain, float d_gain, int dead_band) { pid->pgain = p_gain; pid->igain = i_gain; pid->dgain = d_gain; pid->deadband = dead_band; pid->integral= integral_val; pid->last_error=0; } /*------------------------------------------------------------------------ pid_setinteg DESCRIPTION Set a new value for the integral term of the pid equation. This is useful for setting the initial output of the pid controller at start up. ------------------------------------------------------------------------*/ void pid_setinteg(struct _pid *pid,float new_integ) { pid->integral = new_integ; pid->last_error = 0; } /*------------------------------------------------------------------------ pid_bumpless DESCRIPTION Bumpless transfer algorithim. When suddenly changing setpoints, or when restarting the PID equation after an extended pause, the derivative of the equation can cause a bump in the controller output. This function will help smooth out that bump. The process value in *pv should be the updated just before this function is used. ------------------------------------------------------------------------*/ void pid_bumpless(struct _pid *pid) { pid->last_error = (pid->sp)-(pid->pv); } /*------------------------------------------------------------------------ pid_calc 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. RETURN VALUE The new output value for the pid loop. USAGE #include "control.h"*/ float pid_calc(struct _pid *pid) { int err; float pterm, dterm, result, ferror; err = (pid->sp) - (pid->pv); if (abs(err) > pid->deadband) { ferror = (float) err; /*do integer to float conversion only once*/ pterm = pid->pgain * ferror; if (pterm > 100 || pterm < -100) { pid->integral = 0.0; } else { pid->integral += pid->igain * ferror; if (pid->integral > 100.0) { pid->integral = 100.0; } else if (pid->integral < 0.0) pid->integral = 0.0; } dterm = ((float)(err - pid->last_error)) * pid->dgain; result = pterm + pid->integral + dterm; } else result = pid->integral; pid->last_error = err; return (result); } void main(void) { float display_value; int count=0; pid = &warm; printf("Enter the values of Process point, Set point, P gain, I gain, D gain \n"); scanf("%d%d%f%f%f", &process_point, &set_point, &p_gain, &i_gain, &d_gain); //process_point = 30; //set_point = 40; //p_gain = (float)(5.2); //i_gain = (float)(0.77); //d_gain = (float)(0.18); dead_band = 2; integral_val =(float)(0.01); pid_init(&warm, process_point, set_point); pid_tune(&warm, p_gain,i_gain,d_gain,dead_band); pid_setinteg(&warm,30.0); //Get input value for process point pid_bumpless(&warm); while(count<=20) { // how to display output display_value = pid_calc(&warm); printf("%f\n", display_value); //printf("\n%f%f%f%f",warm.pv,warm.sp,warm.igain,warm.dgain); count++; } }

hotboy

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 7回
  • 年度积分:0
  • 历史总积分:60
  • 注册:2003年12月08日
发表于:2004-01-02 15:07:00
24楼
to JackyHsieh: 谢谢,我不明白C中的数据怎样与汇编中的传递。请赐教

hwj

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 6回
  • 年度积分:0
  • 历史总积分:69
  • 注册:2003年12月10日
发表于:2004-01-06 09:36:00
25楼
很好,那位有自整定的代码啊?

zqy

  • 精华:0帖
  • 求助:0帖
  • 帖子:2帖 | 9回
  • 年度积分:0
  • 历史总积分:66
  • 注册:2002年7月30日
发表于:2004-01-14 04:02:00
26楼
哪位高人有模拟量信号的积分算法?zszzm@163.com

金箍一棒

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 1回
  • 年度积分:0
  • 历史总积分:31
  • 注册:2004年1月14日
发表于:2004-01-14 10:36:00
27楼
谢谢,这样的东西越多越好。

gongkongedit

  • 精华:1099帖
  • 求助:0帖
  • 帖子:14392帖 | 54470回
  • 年度积分:0
  • 历史总积分:622
  • 注册:2008年9月08日
发表于:2004-02-24 12:57:00
28楼
哪位高人可有双变量解耦的程序算法,万分感激。

gongkongedit

  • 精华:1099帖
  • 求助:0帖
  • 帖子:14392帖 | 54470回
  • 年度积分:0
  • 历史总积分:622
  • 注册:2008年9月08日
发表于:2004-03-08 11:27:00
29楼
支持

songgmengda

  • 精华:0帖
  • 求助:1帖
  • 帖子:1帖 | 45回
  • 年度积分:0
  • 历史总积分:447
  • 注册:2004年4月03日
发表于:2004-04-05 11:59:00
30楼
真的很好!支持!这才是真正的应用呢

刘鹏鹏

  • 精华:0帖
  • 求助:0帖
  • 帖子:6帖 | 25回
  • 年度积分:0
  • 历史总积分:93
  • 注册:2004年4月10日
发表于:2004-04-11 18:12:00
31楼
我一共有五路要控制的量,而且各个量的PID参数都不一样,偏差限也不同,我应该怎么编这个程序? 我用的是VB,希望哪位高的手能教教我,如果编程序不方便,可以只把大体的思路说一说,感激不尽。

bawanghao

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 1回
  • 年度积分:0
  • 历史总积分:27
  • 注册:2002年10月12日
发表于:2004-05-31 10:54:00
32楼
大家好,我想用汇编做个电流的PID调节程序,是用单片机控制可控硅的,用增量式还是用位置式呢?有程序请发一篇参考,万分感谢!! 邮箱:bawanghao@163.com

gongkongedit

  • 精华:1099帖
  • 求助:0帖
  • 帖子:14392帖 | 54470回
  • 年度积分:0
  • 历史总积分:622
  • 注册:2008年9月08日
发表于:2004-05-31 11:06:00
33楼
真的都是高手阿!!

沙漠的风雨

  • 精华:0帖
  • 求助:0帖
  • 帖子:24帖 | 461回
  • 年度积分:0
  • 历史总积分:1069
  • 注册:2003年10月23日
发表于:2004-05-31 22:35:00
34楼
学习

wyq

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 3回
  • 年度积分:0
  • 历史总积分:53
  • 注册:2003年2月25日
发表于:2004-06-02 08:56:00
35楼
我也想用汇编做个电流的PID调节程序,也是用单片机控制可控硅的,哪位高手有例程 email:arwa-1@163.com 谢谢!!!!

stone2008

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 1回
  • 年度积分:0
  • 历史总积分:7
  • 注册:2004年6月13日
发表于:2004-06-24 17:39:00
36楼
我想用汇编语言编制一个PID控制算法,哪位大哥有例程啊,请发一下啊,万分感谢,我的邮箱:x01331225@163.com

暧昧

  • 精华:1帖
  • 求助:0帖
  • 帖子:11帖 | 66回
  • 年度积分:0
  • 历史总积分:91
  • 注册:2005年4月13日
发表于:2005-08-19 23:41:00
37楼
有用PLC作的吗?

weixiao

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 20回
  • 年度积分:0
  • 历史总积分:84
  • 注册:2003年3月31日
发表于:2006-01-04 11:46:00
38楼
pid_setinteg(&warm,30.0);
pid_bumpless(&warm);
这两句源程序就是这样的么?
这样能防止启动时的积分饱和和作无扰切换么?

小白杨

  • 精华:0帖
  • 求助:0帖
  • 帖子:19帖 | 82回
  • 年度积分:0
  • 历史总积分:241
  • 注册:2003年10月08日
发表于:2006-01-04 20:25:00
39楼
支持一下

拉拉拉

  • 精华:0帖
  • 求助:0帖
  • 帖子:15帖 | 75回
  • 年度积分:0
  • 历史总积分:189
  • 注册:2001年8月12日
发表于:2006-01-14 11:39:00
40楼
好东西

热门招聘
相关主题

官方公众号

智造工程师