首页 上一页 1 2 3 下一页 尾页

标准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 } }



gongkongedit

  • 精华:1099帖
  • 求助:0帖
  • 帖子:14392帖 | 54470回
  • 年度积分:0
  • 历史总积分:622
  • 注册:2008年9月08日
发表于:2003-01-22 17:32:00
1楼
没人支持? 以后不发了~~

大拇指

  • 精华:1帖
  • 求助:0帖
  • 帖子:7帖 | 24回
  • 年度积分:0
  • 历史总积分:90
  • 注册:2003年2月18日
发表于:2003-02-20 00:10:00
2楼
很好! 谢谢哥们!

工控机王

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 45回
  • 年度积分:0
  • 历史总积分:45
  • 注册:2003年2月09日
发表于:2003-02-20 10:01:00
3楼
很好,支持

碧海游侠

  • 精华:0帖
  • 求助:0帖
  • 帖子:10帖 | 284回
  • 年度积分:0
  • 历史总积分:438
  • 注册:2002年11月27日
发表于:2003-02-27 12:47:00
4楼
谢谢! 有了这么多朋友你就不会孤单了. 祝工作顺利! 哈哈哈哈哈.....

anyway

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 1回
  • 年度积分:0
  • 历史总积分:54
  • 注册:2003年2月26日
发表于:2003-03-01 09:31:00
5楼
很好呀,我正要找这方面的资料,谢谢你

benson99

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 1回
  • 年度积分:0
  • 历史总积分:1
  • 注册:2002年12月28日
发表于:2003-03-02 21:59:00
6楼
谢谢朋友

controls7

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 5回
  • 年度积分:0
  • 历史总积分:138
  • 注册:2002年10月21日
发表于:2003-03-12 13:04:00
7楼
很好,以后多发

gzjim

  • 精华:1帖
  • 求助:0帖
  • 帖子:2帖 | 5回
  • 年度积分:0
  • 历史总积分:16
  • 注册:2003年3月15日
发表于:2003-03-15 22:04:00
8楼
太好了,多谢啊

金丝猴

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 10回
  • 年度积分:0
  • 历史总积分:25
  • 注册:2002年11月11日
发表于:2003-03-18 14:42:00
9楼
我想问一下sPID.Proportion = 0.5,sPID.Proportion = 0.5。的根据是什么?经验还是其它?sPID.SetPoint = 100.0和输入一样有什么意义??

wwwwwww

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 7回
  • 年度积分:0
  • 历史总积分:60
  • 注册:2003年3月23日
发表于:2003-03-23 14:43:00
10楼
是啊 我也想知道!

存异

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 3回
  • 年度积分:0
  • 历史总积分:3
  • 注册:2002年10月10日
发表于:2003-03-28 15:03:00
11楼
楼上的,PID的调节参数当然是根据具体的控制对象而来,可以说是经验和实验的结果 yhsu,请继续发扬风格,多发好东东,我支持你

gongkongedit

  • 精华:1099帖
  • 求助:0帖
  • 帖子:14392帖 | 54470回
  • 年度积分:0
  • 历史总积分:622
  • 注册:2008年9月08日
发表于:2003-04-04 15:27:00
12楼
经典算法 好文章 敬佩!

gongkongedit

  • 精华:1099帖
  • 求助:0帖
  • 帖子:14392帖 | 54470回
  • 年度积分:0
  • 历史总积分:622
  • 注册:2008年9月08日
发表于:2003-04-06 15:41:00
13楼
谢谢你,yhsu!我正在找这方面的资料,非常感谢! 希望你以后能多发些这样的资料,我们大家都会支持你的。

阿穆克鲁斯

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 1回
  • 年度积分:0
  • 历史总积分:1
  • 注册:2003年4月19日
发表于:2003-04-19 12:55:00
14楼
yhsu兄,谢谢你的大作!可我只是听说过PID,你可以发一份PID的概念和几个简单的例子给我?小弟不胜感激!!! jxl-jxc@163.net

MiniOS7

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 11回
  • 年度积分:0
  • 历史总积分:61
  • 注册:2003年1月09日
发表于:2003-04-21 10:02:00
15楼
yhsu:好样的! RS-485论坛鼓励这样的好文章!那些喜欢做广告的朋友就不要再来骚扰这个纯洁的论坛了!

林子

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 6回
  • 年度积分:0
  • 历史总积分:56
  • 注册:2003年4月08日
发表于:2003-04-28 09:26:00
16楼
哥们的大作很好,是我们的学习榜样

TellTruth

  • 精华:1帖
  • 求助:0帖
  • 帖子:10帖 | 451回
  • 年度积分:0
  • 历史总积分:1302
  • 注册:2003年10月29日
发表于:2003-11-24 09:53:00
17楼
问题: 1.PID初始化参数宜都设为零,对于不同的系统,这样的初始化参数可能完全会损坏设备。 2.PID作为系统参数与系统输入输出量不能放在一个数据结构内(我的建议)。 3.算法采用递推法速度应该更快些,还可以避免积分累加带来的误差。

gongkongedit

  • 精华:1099帖
  • 求助:0帖
  • 帖子:14392帖 | 54470回
  • 年度积分:0
  • 历史总积分:622
  • 注册:2008年9月08日
发表于:2003-12-23 15:41:00
18楼
楼主好人啊!!!

zhaoqm

  • 精华:1帖
  • 求助:0帖
  • 帖子:12帖 | 59回
  • 年度积分:0
  • 历史总积分:156
  • 注册:2002年11月17日
发表于:2003-12-26 13:14:00
19楼
这是我们实验室计算机控制实验台的一个简单例程(PID子程序,位置式PID算法),用TC3写的,其实很简单(位置控制的) Sample是当前采样值,Position是目标值 int PIDPro(float Sample, float Position) { int DAOut; ErrPres=Position-Sample; //E(k)=R(k)-S(k) PPro=Kp*ErrPres; //Pp(k)=Kp*E(k) PInt=Ki*ErrPres+PIntPrev; //Pi(k)=Ki*E(k)+Pi(k-1) PDif=Kd*(ErrPres-ErrPrev); //Pd(k)=Kd*[E(k)-E(k-1)] VolOut=PPro+PInt+PDif; //P(k)=Pp(k)+Pi(k)+Pd(k) ErrPrev=ErrPres; //P(k-1)=P(k) PIntPrev=PInt; //Pi(k-1)=Pi(k) DAOut=(int)VolOut; if(DAOut>UpperLimit) DAOut=UpperLimit; //Upper Limit if(DAOut<LowerLimit) DAOut=LowerLimit; //Low Limit return DAOut; } 返回值是12位D/A的转换器的输入量

lazio

  • 精华:0帖
  • 求助:0帖
  • 帖子:2帖 | 2回
  • 年度积分:0
  • 历史总积分:18
  • 注册:2003年12月29日
发表于:2003-12-29 11:11:00
20楼
有用51系列单片机的汇编语言写的么?

热门招聘
相关主题

官方公众号

智造工程师
    首页 上一页 1 2 3 下一页 尾页