加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

经典控制算法PID程序

(2012-06-04 19:53:32)
标签:

pid

程序

杂谈

分类: 旧博客旧文

经典控制算法PID程序

PID代码

//定义变量
float Kp; //PI调节的比例常数
float Ti; //PI调节的积分常数
float T; //采样周期
float Ki;
float ek; //偏差e[k]
float ek1; //偏差e[k-1]
float ek2; //偏差e[k-2]
float uk; //u[k]
signed int uk1; //对u[k]四舍五入取整
signed int adjust; //调节器输出调整量

//变量初始化
Kp=4;
Ti=0。005;
T=0.001;
// Ki=KpT/Ti=0.8,微分系数Kd=KpTd/T=0.8,Td=0.0002,根据实验调得的结果确定这些参数
ek=0;
ek1=0;
ek2=0;
uk=0;
uk1=0;
adjust=0;

int piadjust(float ek) //PI调节算法
{
if( gabs(ek)<0.1 )
{
adjust=0;
}
else
{
uk=Kp*(ek-ek1)+Ki*ek; //计算控制增量
ek1=ek;

uk1=(signed int)uk;
if(uk>0)
{
if(uk-uk1>=0.5)
{
uk1=uk1+1;
}
}
if(uk<0)
{
if(uk1-uk>=0.5)
{
uk1=uk1-1;
}
}
adjust=uk1;
}


return adjust;
}

下面是在AD中断程序中调用的代码。

。。。。。。。。。。。
else //退出软启动后,PID调节,20ms调节一次
{
EvaRegs.CMPR3=EvaRegs.CMPR3+piadjust(ek);//误差较小PID调节稳住
if(EvaRegs.CMPR3>=890)
{
EvaRegs.CMPR3=890; //限制PWM占空比
}
}
。。。。。。。。。。。。。。。。

4PID调节经验总结

PID控制器参数选择的方法很多,例如试凑法、临界比例度法、扩充临界比例度法等。但是,对于PID控制而言,参数的选择始终是一件非常烦杂的工作,需要经过不断的调整才能得到较为满意的控制效果。依据经验,一般PID参数确定的步骤如下[42]:
(1) 确定比例系数Kp
确定比例系数Kp时,首先去掉PID的积分项和微分项,可以令Ti=0、Td=0,使之成为
纯比例调节。输入设定为系统允许输出最大值的60%~70%,比例系数Kp由0开始逐渐增大,直至系统出现振荡;再反过来,从此时的比例系数Kp逐渐减小,直至系统振荡消失。记录此时的比例系数Kp,设定PID的比例系数Kp为当前值的60%~70%。
(2) 确定积分时间常数Ti
比例系数Kp确定之后,设定一个较大的积分时间常数Ti,然后逐渐减小Ti,直至系统出现振荡,然后再反过来,逐渐增大Ti,直至系统振荡消失。记录此时的Ti,设定PID的积分时间常数Ti为当前值的150%~180%。
(3) 确定微分时间常数Td
微分时间常数Td一般不用设定,为0即可,此时PID调节转换为PI调节。如果需要设定,则与确定Kp的方法相同,取不振荡时其值的30%。
(4) 系统空载、带载联调
对PID参数进行微调,直到满足性能要求。

上面的实际是PI调节的代码,现附上PID的。

1. //声明变量

2.

3. //定义变量

4. float Kp; //PID调节的比例常数

5. float Ti; //PID调节的积分常数

6. float T; //采样周期

7. float Td; //PID调节的微分时间常数

8. float a0;

9. float a1;

10. float a2;

11.

12. float ek; //偏差e[k]

13. float ek1; //偏差e[k-1]

14. float ek2; //偏差e[k-2]

15. float uk; //u[k]

16. int uk1; //对uk四舍五入求整

17. int adjust; //最终输出的调整量

18.

19. //变量初始化,根据实际情况初始化

20. Kp=;

21. Ti=;

22. T=;

23. Td=;

24.

25. a0=Kp*(1+T/Ti+Td/T);

26. a1=-Kp*(1+2*Td/T);

27. a2=Kp*Td/T;

28. // Ki=KpT/Ti=0.8,微分系数Kd=KpTd/T=0.8,Td=0.0002,根据实验调得的结果确定这些参数

29. ek=0;

30. ek1=0;

31. ek2=0;

32. uk=0;

33. uk1=0;

34. adjust=0;

35.

36.

37. int pid(float ek)

38. {

39. if(gabs(ek)<ee) //ee 为误差的阀值,小于这个数值的时候,不做PID调整,避免误差较小时频繁调节引起震荡。ee的值可自己设

40. {

41. adjust=0;

42. }

43. else

44. {

45. uk=a0*ek+a1*ek1+a2*ek2;

46. ek2=ek1;

47. ek1=ek;

48. uk1=(int)uk;

49.

50. if(uk>0)

51. {

52. if(uk-uk1>=0.5)

53. {

54. uk1=uk1+1;

55. }

56. }

57. if(uk<0)

58. {

59. if(uk1-uk>=0.5)

60. {

61. uk1=uk1-1;

62. }

63. }

64.

65. adjust=uk1;

66. }

67. return adjust;

68.

69. }

70.

71. float gabs(float ek)

72. {

73. if(ek<0)

74. {

75. ek=0-ek;

76. }

77. return ek;

78. }

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有