[文档] PID控制算法

[复制链接]
974|1
 楼主| alvpeg 发表于 2024-9-16 17:39 | 显示全部楼层 |阅读模式



  1. #define DEAD_BAND 50//死区控制值   
  2. #define PID_OUT_MAX 200 //PID输出上限
  3. #define PID_OUT_MAX 200 //PID输出上限

  4. #include "math.h"           
  5. //PID结构体
  6. typedef struct
  7. {
  8.    volatile float    Proportion;             // 比例常数 Proportional Const
  9.    volatile float    Integral;               // 积分常数 Integral Const
  10.    volatile float    Derivative;             // 微分常数 Derivative Const
  11.    volatile int      Error1;                 // Error[n-1]
  12.    volatile int      Error2;                 // Error[n-2]
  13.    volatile int      iError;                 // Error[n]
  14.    volatile  int     Error_sum;
  15. } PID

  16. /****************************************************************************************/                                                        //                位置式PID
  17. //                    //pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]  
  18. /****************************************************************************************/
  19. float PID_Postion (float set_point,,float now_point,PID* sptr)
  20. {
  21.   float  iIncpid=0;
  22.   sptr->iError=now_point-set_point; // 计算当前误差
  23.   //死区控制算法                                    
  24.   if(fabs(sptr->iError)>DEAD_BAND)
  25.   {
  26.   sptr->Error_sum+=sptr->iError;//积分项      
  27.   iIncpid=sptr->Proportion * sptr->iError                  // P
  28.          +sptr->Integral * sptr->Error_sum                // I
  29.          +sptr->Derivative * (sptr->iError-sptr->Error1); // D
  30.   sptr->Error1=sptr->iError ;          // 存储误差,用于下次计算

  31.   }  
  32.   else
  33.   {
  34.     iIncpid=0;
  35.     //sptr->Error_sum+=sptr->iError;//积分项   
  36.     sptr->Error1=sptr->iError;  // 存储误差,用于下次计算
  37.   }  
  38.   
  39.     return(iIncpid);          // 返回计算值                  
  40. }

  41. /****************************************************************************************/                                    //增量式PID                                            
  42. //        pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]                                      //
  43. /****************************************************************************************/
  44. float PID_increase(int iError,PID* sptr)
  45. {
  46.   
  47.   float  iIncpid=0;
  48.   sptr->iError=iError;//直接检测当前偏差
  49.   if(fabs(sptr->iError)>DEAD_BAND)
  50.   {
  51.   iIncpid=sptr->Proportion * (sptr->iError-sptr->Error1)                  // P
  52.          +sptr->Integral * sptr->iError                                   // I
  53.          +sptr->Derivative * (sptr->iError-2*sptr->Error1+sptr->Error2);  // D            
  54.   sptr->Error2=sptr->Error1;                          // 存储误差,用于下次计算
  55.   sptr->Error1=sptr->iError;

  56. }
  57. else
  58. {
  59.   iIncpid=0;//输出增量值为0
  60.   sptr->Error2=sptr->Error1; // 存储误差,用于下次计算                       
  61.     sptr->Error1=sptr->iError;
  62. }
  63.   return(iIncpid);   // 返回增量值  
  64. }


yangjiaxu 发表于 2024-9-24 16:18 | 显示全部楼层
感觉做PID就数学一定要好一些,而且PID应用确实很广泛,电机和调节的时候确实用PID就很不错
您需要登录后才可以回帖 登录 | 注册

本版积分规则

45

主题

1816

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部