找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2838|回复: 2
收起左侧

飞思卡尔控制电机PID算法代码解析

[复制链接]
ID:257741 发表于 2017-12-9 22:11 | 显示全部楼层 |阅读模式
PID实指“比例proportional”、“积分integral”、“微分derivative” , 这三项构成PID基本要素。每一项完成不同任务对系统功能产生不同的影响。 搞软件的往往对硬件不屑 ,却忘了软件再牛B也是为硬件服务的 , PID的数字化算法就完全是为硬件而生的 , 这是控制电机算法的一个难点 , 没有一定的对软硬件的理解 , 就连调试装定PID参数都会很为难 ! 飞思卡尔智能车项目里面就会用到PID算法 , 比如车爬坡和平地连续拐弯时 , 代码里面没有PID算法 , 控制和驱动起来就会很拙急 , 对不对 ? 不过 ,搞清楚问题还是有个前提的 , 那就是懂点微积分 , 不会微积分嘛 , 下面的内容无需关注

实际上 , PID算法的应用基础始于对PCB板上的运放的PID参数进行调校 , P对应于运放增益  ; I 就是运放输入和输出端之间接一个电容引入反馈 , 就是控制器的输出与输入误差会积累起来影响输出 ;  D 就是运放输入端串接一个电容 ,起的微分作用是阻止输出与输入误差的变化 .  结合示波器来观察控制电机的PID参数设定的话 , 网上有一首诗 , 它就代表我的心声了 :

参数整定找最佳,从小到大顺序查
先是比例后积分,最后再把微分加
曲线振荡很频繁,比例度盘要放大
曲线漂浮绕大湾,比例度盘往小扳
曲线偏离回复慢,积分时间往下降
曲线波动周期长,积分时间再加长
曲线振荡频率快,先把微分降下来
动差大来波动慢,微分时间应加长
理想曲线两个波,前高后低四比一
一看二调多分析,调节质量不会低 !


下面贴段代码 (真的是仅供参考):
  1.     #include <mc9s12dg128.h> /* derivative information */
  2.     /*******************************************************************
  3.     * 宏定义
  4.     **********************************************************************************/
  5.     #define STABMAX 50
  6.     #define SENSORNUM 8
  7.     #define SAMPLETIMES 5
  8.     /********************************************************************
  9.     FUNCTION PROTOTYPES
  10.     ********************************************************************/
  11.     int CalculateP(void);
  12.     float CalculatePID(void);
  13.     /********************************** PID控制程序 *******************/
  14.     struct CARSTATE
  15.     {
  16.     int E0;
  17.     int E1;
  18.     int E2;
  19.     int E3;
  20.     float Integral;
  21.     }CarState;
  22.     /*
  23.     ********************************************************************
  24.     * 初始化PID参数
  25.     ********************************************************************/
  26.     void Init_PID()
  27.     {
  28.     CarState.E0 = 0;
  29.     CarState.E1 = 0;
  30.     CarState.E2 = 0;
  31.     CarState.E3 = 0;
  32.     CarState.Integral = 0;
  33.     }
  34.     /*
  35.     ********************************************************************
  36.     * 信号处理函数
  37.     * 程序描述: 对传感器采集过来的数据进行处理,得到一些基本的计算参数

  38.     ********************************************************************/
  39.     int SignalProcess( unsigned int signal )
  40.     {
  41.     const int BitValue[8] = {43,26,12,6,-6,-12,-26,-43}; //MAX:28
  42.     int i,CurrPoint=0,LastPoint=0,BitNum=0;
  43.     unsigned char SignalBit[8];
  44.     for(i=0;i<8;i++)
  45.     {
  46.     SignalBit = signal & 0x0001;
  47.     BitNum += SignalBit;
  48.     signal >>= 1;
  49.     }
  50.     switch(BitNum)
  51.     {
  52.     case 1:
  53.     for(i=0;i<8;i++)
  54.     if(SignalBit != 0)
  55.     CurrPoint += BitValue;
  56.     CarState.E0 = CurrPoint;
  57.     break;
  58.     case 2:
  59.     for(i=0;i<8;i++)
  60.     if(SignalBit != 0)
  61.     CurrPoint += BitValue;
  62.     CurrPoint >>= 1;
  63.     CarState.E0 = CurrPoint;
  64.     break;
  65.     default:
  66.     CarState.E0 = CarState.E1;
  67.     break;
  68.     }
  69.     return CalculateP()*100;
  70.     }
  71.     /*******************************************************************
  72.     * PID计算函数

  73.     * 程序描述: 计算P参数

  74.     ********************************************************************/
  75.     int CalculateP(void)
  76.     {
  77.     CarState.E1 = CarState.E0;
  78.     return((int)CarState.E0);
  79.     }

  80.     /*
  81.     ***********************************************************************************
  82.     * PID计算函数
  83.     *
  84.     * 程序描述: 对传感器采集过来的数据进行处理,得到一些基本的计算参数
  85.     *
  86.     ******************************************************************* ***************/
  87.     float CalculatePID(void)
  88.     {
  89.     float P, I = 0, D;
  90.     /* parameter const */
  91.     float Kp = 1.0, Ki = -0.0002, Kd = -0.0002;
  92.     /* P parameter */
  93.     P = CarState.E0 * Kp;
  94.     /* I parameter */
  95.     if(P+I<2)
  96.     {
  97.     CarState.Integral += Ki * CarState.E0;
  98.     I = CarState.Integral;
  99.     }
  100.     /* D parameter */
  101.     D = Kd * ( CarState.E0 + 3*CarState.E1 - 3*CarState.E2 - CarState.E3 )/6.0;
  102.     CarState.E3 = CarState.E2;
  103.     CarState.E2 = CarState.E1;
  104.     CarState.E1 = CarState.E0;
  105.     return (P+I+D);
  106.     }
复制代码



回复

使用道具 举报

ID:242544 发表于 2018-1-8 16:16 | 显示全部楼层
不错。很实用
回复

使用道具 举报

ID:242544 发表于 2018-1-8 16:17 | 显示全部楼层
不错,很实用
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表