基于TI板MSP430 玩转PID

编程入门 行业动态 更新时间:2024-10-10 14:30:14

基于TI板MSP430 <a href=https://www.elefans.com/category/jswz/34/1768105.html style=玩转PID"/>

基于TI板MSP430 玩转PID

文章目录

  • 前言
  • 一、整体框架
  • 二、PID算法
    • 1. 位置式PID
    • 2. 增量式PID
    • 3. 比例外置式PID
    • 4. 积分限幅、输出限幅和PID参数整定
    • 5. 位置式PID和增量式PID的区别及抉择
  • 三、初值获取
    • 1. 定时器输入捕获
    • 2. 外部中断
    • 3. ADC采样


前言

具体啥是PID,我这里不做介绍,网上有大把的资料可查,以下我推荐几篇优秀文章以供大家参考:

  • 史上最详细的PID教程——理解PID原理及优化算法 ---------- 【狂刀西瓜】
  • 位置式PID与增量式PID区别浅析 ---------- 【Z小旋】
  • 深入浅出PID控制算法 ---------- 【万般滋味皆生活】

一、整体框架

该篇以电机控速为例展开分析,假如你手上有一个编码器电机,其余配件若干,请你运用PID算法相关知识设计出一套完整的反馈路线。

相信大家最常用的设计路线是用定时器,那么这里我就以定时器来构思反馈路线。

  1. 编码器电机的变化源于所在ABZ三相的变化(一般编码器电机只有A相和B相,这里也以该俩相为例),所以先对该两项进行设计,可知定时器有输入捕获功能刚好可以用于捕获AB相的变化 【定时器一】。
  2. 每隔一定时间对电机速度进行一次检测,以及时响应未知变化 【定时器二】。
  3. 需对电机进行速度控制,也就是PWM设计 【定时器三】。
  4. 你需给定电机一个初速度,那么该怎么给呢,我的方法是你可以根据你检测电机的时间,也就是定时器二的时间所捕获到的AB相脉冲数做为初速度,PWM周期可根据实际脉冲数而设定。

简易框图如下:

二、PID算法

1. 位置式PID


位置式Pid就是位置闭环控制,位置闭环控制就是根据编码器的脉冲累加,测量电机的位置信息,并与目标值进行比较得到一个控制偏差,然后我们对偏差进行比例积分、微分的控制,使偏差趋近于0的一个过程。

  • 优点:
    位置式PID是一种非递推式算法,可直接控制执行机构(如平衡小车),u(k)的值和执行机构的实际位置(如小车当前角度)是一一对应的,因此在执行机构不带积分部件的对象中可以很好应用
  • 缺点:
    每次输出均与过去的状态有关,计算时要对e(k)进行累加,运算工作量大。
PID_VAR_TYPE Position_PID_Cal(PID * s_PID,PID_VAR_TYPE now_point)
{s_PID->LastResult = s_PID->Result;                 // 简单赋值运算//误差计算s_PID->Error = s_PID->SetPoint - now_point;s_PID->SumError += s_PID->Error;                            //积分误差累加//积分限幅PID_VAR_TYPE IOutValue = s_PID->SumError * s_PID->Integral;if(IOutValue > s_PID->IntegralMax)IOutValue = s_PID->IntegralMax;else if(IOutValue < s_PID->IntegralMin)IOutValue = s_PID->IntegralMin;//PID计算s_PID->Result =  s_PID->Proportion  *  s_PID->Error                          // 比例项+ IOutValue                                                     // 积分项+ s_PID->Derivative  * (s_PID->Error - s_PID->LastError);     // 微分项s_PID->PrevError = s_PID->LastError;                               // 简单赋值运算s_PID->LastError = s_PID->Error;                       // 简单赋值运算//输出限幅if(s_PID->Result > s_PID->OutMax)s_PID->Result = s_PID->OutMax;else if(s_PID->Result < s_PID->OutMin)s_PID->Result = s_PID->OutMin;return s_PID->Result;
}

2. 增量式PID


增量式pid就是速度闭环控制,速度闭环控制是根据单位时间获取的脉冲数,测量电机的速度信息,并于目标值进行比较,得到了偏差。然后同样通过对偏差的比例、积分、微分进行控制,使偏差趋近于0的一个过程。

  • 优点:
    ①误动作时影响小,必要时可用逻辑判断的方法去掉出错数据。
    ②手动/自动切换时冲击小,便于实现无扰动切换。当计算机故障时,仍能保持原值。
    ③算式中不需要累加。控制增量Δu(k)的确定仅与最近3次的采样值有关。
  • 缺点:
    ①积分截断效应大,有稳态误差;
    ②溢出的影响大。有的被控对象用增量式则不太好;
PID_VAR_TYPE Increment_PID_Cal(PID * s_PID,PID_VAR_TYPE now_point)
{s_PID->LastResult = s_PID->Result;                         // 简单赋值运算//误差计算s_PID->Error = s_PID->SetPoint - now_point;//PID计算s_PID->Result = s_PID->LastResult+ s_PID->Proportion  * (s_PID->Error - s_PID->LastError)                          // 比例项+ s_PID->Integral    *  s_PID->Error                                         // 积分项+ s_PID->Derivative  * (s_PID->Error - 2*(s_PID->LastError) + s_PID->PrevError);  // 微分项s_PID->PrevError = s_PID->LastError;                       // 简单赋值运算s_PID->LastError = s_PID->Error;                       // 简单赋值运算//输出限幅if(s_PID->Result > s_PID->OutMax)s_PID->Result = s_PID->OutMax;else if(s_PID->Result < s_PID->OutMin)s_PID->Result = s_PID->OutMin;return s_PID->Result;
}

3. 比例外置式PID

此类运用相对较少,请自行查阅

PID_VAR_TYPE PID_Cal(PID * s_PID,PID_VAR_TYPE now_point)
{s_PID->LastResult = s_PID->Result;                 // 简单赋值运算//误差计算s_PID->Error = s_PID->SetPoint - now_point;s_PID->SumError += s_PID->Error;                            //积分误差累加//积分限幅PID_VAR_TYPE IOutValue = s_PID->SumError * s_PID->Integral;if(IOutValue > s_PID->IntegralMax)IOutValue = s_PID->IntegralMax;else if(IOutValue < s_PID->IntegralMin)IOutValue = s_PID->IntegralMin;//PID计算s_PID->Result = s_PID->Proportion *(s_PID->Error + IOutValue + s_PID->Derivative * (s_PID->Error - s_PID->LastError) );s_PID->PrevError = s_PID->LastError;                               // 简单赋值运算s_PID->LastError = s_PID->Error;                       // 简单赋值运算//输出限幅if(s_PID->Result > s_PID->OutMax)s_PID->Result = s_PID->OutMax;else if(s_PID->Result < s_PID->OutMin)s_PID->Result = s_PID->OutMin;return s_PID->Result;
}

4. 积分限幅、输出限幅和PID参数整定

//设置PID输出范围
void  PID_SetOutRange  (PID * s_PID, PID_VAR_TYPE outMax,PID_VAR_TYPE outMin)
{s_PID->OutMax = outMax;s_PID->OutMin = outMin;
}
//设置PID积分范围
void  PID_SetIntegralOutRange(PID * s_PID, PID_VAR_TYPE outMax,PID_VAR_TYPE outMin)
{s_PID->IntegralMax = outMax;s_PID->IntegralMin = outMin;
}
				参数整定找最佳, 从小到大顺序查。先是比例后积分, 最后再把微分加。曲线振荡很频繁, 比例度盘要放大。曲线漂浮绕大弯, 比例度盘往小扳。曲线偏离回复慢, 积分时间往下降。曲线波动周期长, 积分时间再加长。曲线振荡频率快, 先把微分降下来。动差大来波动慢, 微分时间应加长。理想曲线两个波, 前高后低四比一。一看二调多分析, 调节质量不会低。

5. 位置式PID和增量式PID的区别及抉择

  • (1)区别
  1. 增量式算法不需要做累加,控制量增量的确定仅与最近几次偏差采样值有关,计算误差对控制 量计算的影响较小。而位置式算法要用到过去偏差的累加值,容易产生较大的累加误差。

  2. 增量式算法得出的是控制量的增量,例如在阀门控制中,只输出阀门开度的变化部分,误动作 影响小,必要时还可通过逻辑判断限制或禁止本次输出,不会严重影响系统的工作。 而位置式的输出直接对应对象的输出,因此对系统影响较大。

  3. 增量式PID控制输出的是控制量增量,并无积分作用,因此该方法适用于执行机构带积分部件的对象,如步进电机等,而位置式PID适用于执行机构不带积分部件的对象,如电液伺服阀。

  4. 在进行PID控制时,位置式PID需要有积分限幅和输出限幅,而增量式PID只需输出限幅

  • (2)抉择
  1. 位置式PID控制的输出与整个过去的状态有关,用到了误差的累加值;而增量式PID的输出只与当前拍和前两拍的误差有关,因此位置式PID控制的累积误差相对更大;
  2. 增量式PID控制输出的是控制量增量,并无积分作用,因此该方法适用于执行机构带积分部件的对象,如步进电机等,而位置式PID适用于执行机构不带积分部件的对象,如电液伺服阀。
  3. 由于增量式PID输出的是控制量增量,如果计算机出现故障,误动作影响较小,而执行机构本身有记忆功能,可仍保持原位,不会严重影响系统的工作,而位置式的输出直接对应对象的输出,因此对系统影响较大。

三、初值获取

关于初值的设定可以根据以下3种方法获取。

1. 定时器输入捕获

定时器A0和A1开捕获模式(双边沿),分别接俩个电机的A/B相,每发生一个脉冲变化进一次捕获中断,中断里做计数操作。

void TIME()//配置编码电机接口
{TA0CCTL1 = CM_3 | CCIS_0 | SCS | CAP | CCIE; // 捕获比较器1:双边沿捕获模式,捕获 TA0CLK 信号,启用捕获中断TA0CTL = TASSEL_2 | ID_0 | MC_2 | TACLR; // P1OUT=BIT2;时钟源选择 SMCLK,分频系数为 1,计数器模式为连续计数,启用计数器清零P1DIR &=~ BIT2;               //初始化捕获IO口P1SEL |=  BIT2;// 启用 Timer_A 中断和总中断TA0CTL |= TAIE; // 启用 Timer_A 中断__enable_interrupt(); // 启用总中断
}#pragma vector=TIMER0_A1_VECTOR //定时器A中断处理
__interrupt void timer_A0(void)
{switch(TA0IV) //向量查询,读取的话无需手动清零标志位{case 2:             //捕获中断count0++;break;case 10:            //溢出中断break;default:break;}
}

2. 外部中断

将A/B相接外部中断引脚,设置触发模式,每发生一次跳变便进一次中断,中断内做计数操作。

void init_encoders()
{P1DIR &= ~BIT4;          //设置P1.4口为输入P1IN |= BIT4;P1REN |= BIT4;P1OUT |= BIT4;          //配置P1.4上拉电阻P1IE |= BIT4;           //P1.4中断使能P1IES |= BIT4;          //P1.4下降沿触发中断P1IFG &= ~BIT4;        //清除中断标志位_EINT();
}#pragma vector = PORT1_VECTOR
__interrupt void P1_ISR(void)
{_DINT();  //关总中断if (P1IFG & BIT4){count0++;}P1IFG &= ~ BIT4 ;_EINT();  //开总中断
}

3. ADC采样

对电机的输出电压进行采样,可知 电机输出电压范围是 0~12V,所以是不能直接采集的,这时你需串联一个电阻进行分压,然后再将采集到的模拟信号转换为数字信号再根据PWM进行再次转化,最后将处理后的值当作初值运算。


void ADC_Init(void)
{P6SEL |= BIT6;ADC12CTL0 = ADC12ON + ADC12SHT0_8 + ADC12MSC;ADC12CTL1 = ADC12SHP + ADC12CONSEQ_2;ADC12MCTL0 = ADC12SREF_0 + ADC12INCH_6;ADC12CTL0 |= ADC12ENC;ADC12CTL0 |= ADC12SC;_EINT();
}//采样数据转换
float ADC_date()
{float date;date = ADC12MEM0*3.3/4065;return date;
}//采样中断服务函数
#pragma vector = ADC12_VECTOR
__interrupt void ADC12ISR(void)
{......
}

更多推荐

基于TI板MSP430 玩转PID

本文发布于:2024-03-13 17:09:10,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1734438.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:玩转   TI   PID

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!