避免过冲的PID算法 控制对象是温度 C语言代码

[复制链接]
查看1 | 回复0 | 2021-4-17 01:55:50 | 显示全部楼层 |阅读模式
  1. #include "pid.h"
  2. PID pid; //存放PID算法所需要的数据

  3. void PID_Calc()  //pid计算
  4. {
  5. float DelEk;
  6.         float ti,ki;
  7. //        float Iout;
  8. //        float Pout;
  9. //        float Dout;
  10.         float td;
  11.         float kd;
  12.         float out;
  13. if(pid.C10ms<(pid.T))  //计算周期未到
  14. {
  15.     return ;
  16. }

  17. pid.Ek=pid.Sv-pid.Pv;   //得到当前的偏差值
  18. pid.Pout=pid.Kp*pid.Ek;      //比例输出

  19. pid.SEk+=pid.Ek;        //历史偏差总和

  20. DelEk=pid.Ek-pid.Ek_1;  //最近两次偏差之差

  21. ti=pid.T/pid.Ti;
  22. ki=ti*pid.Kp;

  23.   pid.Iout=ki*pid.SEk*pid.Kp;  //积分输出

  24. td=pid.Td/pid.T;

  25. kd=pid.Kp*td;

  26.   pid.Dout=kd*DelEk;    //微分输出

  27. out= pid.Pout+ pid.Iout+ pid.Dout;

  28. //////////////////////////////////////////////////////////

  29. if(out>pid.pwmcycle)
  30. {
  31.   pid.OUT=pid.pwmcycle;
  32. }
  33. else if(out<0)
  34. {
  35.   pid.OUT=pid.OUT0;
  36. }
  37. else
  38. {
  39.   pid.OUT=out;
  40. }
  41. //pid.OUT+=; //本次的计算结果
  42. pid.Ek_1=pid.Ek;  //更新偏差

  43. pid.C10ms=0;
  44. }


  45. void PID_Calc_overshoot()  //pid计算-过冲处理?
  46. {
  47. float DelEk;
  48.         float ti,ki;
  49. //        float Iout;
  50. //        float Pout;
  51. //        float Dout;
  52.         float td;
  53.         float kd;
  54.         float out;
  55.   float SvSave;
  56. if(pid.C10ms<(pid.T))  //计算周期未到
  57. {
  58.     return ;
  59. }


  60. //判断Sv
  61.   SvSave=pid.Sv;

  62. if(pid.Pv<(SvSave*0.55))//温度达到计数开始 66度
  63. {
  64.     pid.times=0;
  65. }

  66.   if(pid.times<=60)//3分钟 72度  100s
  67. {
  68.   pid.Sv=SvSave*0.6;
  69. }

  70. if((pid.times>60)&&(pid.times<=100))//3分钟 96度  100s
  71. {
  72.   pid.Sv=SvSave*0.8;
  73. }

  74. if((pid.times>100)&&(pid.times<=200))//2分钟 102度 100s
  75. {
  76.   pid.Sv=SvSave*0.85;
  77. }

  78. if((pid.times>200)&&(pid.times<=300))//2分钟 108度 100s
  79. {
  80.   pid.Sv=SvSave*0.9;
  81. }

  82.   if((pid.times>300)&&(pid.times<=400))//2分钟 114度 100s
  83. {
  84.   pid.Sv=SvSave*0.95;
  85. }

  86. if(pid.times>400)
  87. {
  88.   pid.Sv=SvSave;
  89. }
  90. //////////////////////////////////


  91. pid.Ek=pid.Sv-pid.Pv;   //得到当前的偏差值
  92. pid.Pout=pid.Kp*pid.Ek;      //比例输出

  93. pid.SEk+=pid.Ek;        //历史偏差总和

  94. DelEk=pid.Ek-pid.Ek_1;  //最近两次偏差之差

  95. ti=pid.T/pid.Ti;
  96. ki=ti*pid.Kp;

  97.   pid.Iout=ki*pid.SEk*pid.Kp;  //积分输出

  98. td=pid.Td/pid.T;

  99. kd=pid.Kp*td;

  100.   pid.Dout=kd*DelEk;    //微分输出

  101. out= pid.Pout+ pid.Iout+ pid.Dout;

  102. //////////////////////////////////////////////////////////

  103. if(out>pid.pwmcycle)
  104. {
  105.   pid.OUT=pid.pwmcycle;
  106. }
  107. else if(out<0)
  108. {
  109.   pid.OUT=pid.OUT0;
  110. }
  111. else
  112. {
  113.   pid.OUT=out;
  114. }
  115. //pid.OUT+=; //本次的计算结果
  116. pid.Ek_1=pid.Ek;  //更新偏差

  117. pid.C10ms=0;
  118. pid.Sv=SvSave;
  119. }
复制代码

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则