[程序源码] 适用于单片机的简单易懂的 PID 计算函数与 C 代码

[复制链接]
1592|6
 楼主| panxiaoyi 发表于 2022-10-2 11:04 | 显示全部楼层 |阅读模式

  1. #include "stdio.h"

  2. int dat;
  3. int goal=180;                                                //设定值
  4. int now;                                                     //现在值
  5. int gap[3];                                                  //缓存,最少3个成员

  6. int Pid(unsigned char P, unsigned char I, unsigned char D, int goal, int now, int *gap) //P/I/D系数,目标值,现在值,缓存
  7. {
  8.         gap[2]=gap[1];
  9.         gap[1]=gap[0];
  10.         gap[0]=goal-now;                                                                    //负反馈式PID
  11.         //gap[0]=now-goal;                                                                  //正反馈式PID。这2条语句请2选1

  12.         return (P*(gap[0]-gap[1])+I*gap[0]+D*(gap[0]-gap[1]-gap[1]+gap[2]));                //PID计算公式
  13. }

  14. int main()                                                   //以下的是测试代码
  15. {
  16.         while(1)                                                 //使用PID计算,请注意要定时定点的采集测量数据才有效
  17.         {
  18.                 printf("请输入当前温度\n");                          //提示字符
  19.                 scanf("%3d[0-9]",&now);                              //从键盘获取最多3个0-9的字符,然后转化为十进制,再赋值给变量
  20.                 scanf("%*[^\n]%*c");                                 //清空输入缓存,等同于非标准的fflush(stdin)
  21.                 dat=Pid(9,8,7,goal,now,gap);                         //PID计算
  22.                 printf("当前的温度=%d,PID计算结果=%d,",now,dat);   //输出原始值
  23.                 if(dat<0) dat=0; if(dat>255) dat=255;                //计算结果限幅
  24.                 printf("PWM占空比=%d/255\n\n",dat);                  //输出PWM调整参数
  25.         }
  26. }

  27. /*
  28. 调试结果:

  29. 请输入当前温度
  30. 150
  31. 当前的温度=150,PID计算结果=720,PWM占空比=255/255

  32. 请输入当前温度
  33. 175
  34. 当前的温度=175,PID计算结果=-570,PWM占空比=0/255

  35. 请输入当前温度
  36. 176
  37. 当前的温度=176,PID计算结果=191,PWM占空比=191/255

  38. 请输入当前温度
  39. ADCD
  40. 当前的温度=176,PID计算结果=39,PWM占空比=39/255

  41. 请输入当前温度
  42. 18234
  43. 当前的温度=182,PID计算结果=-112,PWM占空比=0/255
  44. */


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
LcwSwust 发表于 2022-10-2 11:14 | 显示全部楼层
你这增量式的公式,怎么是位置式的用法。
 楼主| panxiaoyi 发表于 2022-10-2 16:20 | 显示全部楼层
LcwSwust 发表于 2022-10-2 11:14
你这增量式的公式,怎么是位置式的用法。

你的意思是下面的做法才是合适的,是吗?有空我测试看看
  1. dat=Pid(9,8,7,goal,now,gap);
  2. 修改成
  3. dat+=Pid(9,8,7,goal,now,gap);


LcwSwust 发表于 2022-10-2 18:12 | 显示全部楼层
panxiaoyi 发表于 2022-10-2 16:20
你的意思是下面的做法才是合适的,是吗?有空我测试看看

是的,假如设定值与目标值一直是固定的误差,原来的用法输出值是一直不变的,修改后才是正确的,输出会逐渐变化。
uant 发表于 2022-10-4 09:35 | 显示全部楼层
感谢分享,不过计算过程还是不太懂
 楼主| panxiaoyi 发表于 2022-10-4 10:32 | 显示全部楼层
uant 发表于 2022-10-4 09:35
感谢分享,不过计算过程还是不太懂
  1. 本次差距 = 目标值 - 测量值   //适合输出结果越大,输出功率越大
  2. 本次差距 = 测量值 - 目标值   //适合输出结果越大,输出功率越小

  3. 输出值 = 上次输出值 + P x (本次差距 - 上次差距) + I x 本次差距 + D x ((本次差距 - 上次差距) - (上次差距 - 上上次差距))


 楼主| panxiaoyi 发表于 2022-10-4 10:39 | 显示全部楼层
  1. scanf("%*[^\n]%*c");  //清空输入缓存,清空电脑接受键盘的缓存,与PID计算没有任何关系


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

本版积分规则

53

主题

417

帖子

2

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