基于TI板MSP430 玩转PID

news2024/10/2 20:37:25

文章目录

  • 前言
  • 一、整体框架
  • 二、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)
{
	......
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/484528.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringMVC(后)SSM整合

10、文件上传和下载 10.1、文件下载 ResponseEntity用于控制器方法的返回值类型&#xff0c;该控制器方法的返回值就是响应到浏览器的响应报文 使用ResponseEntity实现下载文件的功能 RequestMapping("/testDown") public ResponseEntity<byte[]> testResp…

【Hello Algorithm】复杂度 二分法

作者&#xff1a;小萌新 专栏&#xff1a;算法 作者简介&#xff1a;大二学生 希望能和大家一起进步 本篇博客简介&#xff1a;介绍算法的复杂度 对数器和二分法 复杂度 对数器 二分法 复杂度常数时间操作非常数时间操作时间复杂度空间复杂度 二分法有序数组中找一个值寻找有序…

树的存储和遍历

文章目录 6.5 树与森林6.5.1 树的存储结构1. 双亲表示法(顺序存储结构)2 孩子链表表示法3 孩子兄弟表示法(二叉树表示法) 6.5.2 森林与二叉树的转换1 树转换成二叉树2 二叉树转换成树3 森林转换成二叉树4 二叉树转换成森林 6.5.3 树和森林的遍历1. 树的遍历2. 森林的遍历 6.6 赫…

数据库篇:表设计、创建编辑以及导出导入数据

微信小程序云开发实战-答题积分赛小程序系列 数据库篇:表设计、添加编辑以及导出导入数据 原型: 最终实现界面截图:

Moqui REST API的两种实现方法

实现Restful API的方法 实现REST API有两种方法。第一种&#xff1a; The main tool for building a REST API based on internal services and entity operations is to define resource paths in a Service REST API XML file such as the moqui.rest.xml file in moqui-fr…

chatGPT国内可用镜像源地址

chatGPT国内可用镜像源地址 彷丶徨丶 关注 IP属地: 湖北 0.811 2023.03.15 16:02:16 字数 1,152 阅读 249,582 如果你正在尝试访问Chatgpt网站&#xff0c;但由于某些原因无法访问该网站&#xff0c;那么你可以尝试使用Chatgpt的国内镜像网站。以下是一些Chatgpt国内镜像网站的…

java基础知识——27.动态代理

这篇文章&#xff0c;我们来学一下java的动态代理 目录 1.动态代理的介绍 2.具体的代码实现 1.动态代理的介绍 动态代理&#xff1a;无侵入式的额外给代码增加功能 很不好理解&#xff0c;下面&#xff0c;我们通过两个例子来说明一下什么是动态代理&#xff1a; 例一&a…

shell编程 -- 基础

shell是一个命令行解释器&#xff0c;它接收应用程序/用户命令&#xff0c;然后调用操作系统内核。 linux笔记 链接&#xff1a;https://pan.baidu.com/s/16GZCPfUTRzUqIyGnYwPuUg?pwds5xt 提取码&#xff1a;s5xt 脚本执行 采用bash或者sh脚本的相对路径或绝对路径&#x…

TikTok跨境电商如何选品和营销?

鑫优尚电子商务&#xff1a;TikTok目前发展飞速&#xff0c;全球的MAU是5.6亿。现在作为全球炙手可热的短视频平台&#xff0c;全球流量相当庞大&#xff0c;覆盖75个语种、全球150个国家和地区。 对于从事跨境电商行业的人来说&#xff0c;又怎能错过一个流量这么好的平台呢&a…

ChatGPT注册详细步骤教程-ChatGPT申请教程

注册chatGPT账号的详细经验教程 注册ChatGPT账号是使用这一自然语言生成技术的关键步骤。下面是注册ChatGPT账号的详细经验教程&#xff1a; 访问OpenAI注册页面 在Web浏览器中打开OpenAI注册页面。 2.输入个人信息 在注册页面上&#xff0c;您需要提供以下个人信息&#…

树莓派 二维云台调零控制

目录 舵机的工作原理 案例程序 要求&#xff1a; 程序&#xff1a; 二维云台是通过IIC总线进行控制的&#xff0c;我们可以通过窗口命令输入&#xff1a;i2cdetect -y 1来检测IIC总线是否连接正常。 当有40显示的时候就说明IIC总线正常。 操控舵机我们需要一个PCA9685的模…

【移动端网页布局】流式布局案例 ④ ( Banner 栏制作 | 固定定位 | 标准流 | 百分比宽度设置 )

文章目录 一、Banner 栏样式及核心要点1、实现效果2、核心要点分析 二、完整代码示例1、HTML 标签结构2、CSS 样式3、展示效果 一、Banner 栏样式及核心要点 1、实现效果 在上一篇博客中 , 实现了 搜索栏 , 在本篇博客开始实现 搜索栏 下方的 Banner 栏 ; 2、核心要点分析 Bann…

OpenCV实战(21)——基于随机样本一致匹配图像

OpenCV实战&#xff08;21&#xff09;——基于随机样本一致匹配图像 0. 前言1. 基于随机样本一致匹配图像1.1 计算基本矩阵与匹配集1.2 随机样本一致算法 2. 算法优化2.1 优化基本矩阵2.2 优化匹配集 3. 完整代码小结系列链接 0. 前言 当两台摄像机拍摄同一场景时&#xff0c…

【Vue面试题】Vue2.x生命周期?

文章目录 1.有哪些生命周期&#xff08;系统自带&#xff09;?beforeCreate( 创建前 )created ( 创建后&#xff09;beforeMount (挂载前)mount (挂载后)beforeUpdate (更新前)updated (更新后)beforeDestroy&#xff08;销毁前&#xff09;destroy&#xff08;销毁后&#xf…

突发:深度学习之父Hinton为了警告AI的风险,不惜从谷歌离职!

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 今天&#xff0c;AI领域发生了一件标志性事件。那就是Hinton 为了能更自由的表达对AI失控的担忧&#xff0c;不惜从工作了10年的谷歌离职&#xff0c;可见他真的深切的感受到了危机。 不久前&#xff0c;纽约时报的一篇采访…

干货! ICLR:将语言模型绑定到符号语言中个人信息

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; ╱ 作者简介╱ 承洲骏 上海交通大学硕士生&#xff0c;研究方向为代码生成&#xff0c;目前在香港大学余涛老师的实验室担任研究助理。 个人主页&#xff1a;http://blankcheng.github.io 谢天宝 香港大学一年级…

武忠祥老师每日一题||不定积分基础训练(六)

解法一&#xff1a; 求出 f ( x ) , 进而对 f ( x ) 进行积分。 求出f(x),进而对f(x)进行积分。 求出f(x),进而对f(x)进行积分。 令 ln ⁡ x t , 原式 f ( t ) ln ⁡ ( 1 e t ) e t 令\ln xt,原式f(t)\frac{\ln (1e^t)}{e^t} 令lnxt,原式f(t)etln(1et)​ 则 ∫ f ( x ) d…

分布式配置中心Apollo教程

分布式配置中心Apollo教程 简介 Apollo配置中心课程是传智燕青老师针对微服务开发设计的系列课程之一&#xff0c;本课程讲解了Apollo分布式系统配置中心的使用方法和工作原理&#xff0c;并从实战出发讲解生产环境下的配置中心的构建方案&#xff0c;从Apollo的应用、原理、项…

transformer and DETR

RNN 很难并行化处理 Transformer 1、Input向量x1-x4分别乘上矩阵W得到embedding向量a1-a4。 2、向量a1-a4分别乘上Wq、Wk、Wv得到不同的qi、ki、vi&#xff08;i{1,2,3,4}&#xff09;。 3、使用q1对每个k&#xff08;ki&#xff09;做attention得到a1,i&#xff08;i{1,2,3,4…

STL容器类

STL 1. STL初识 1.1 迭代器 1.1.1 原生指针也是迭代器 #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; void test01() {int arr[5] { 1,2,3,4,5 };int* p arr;for (int i 0; i < 5; i) {cout << arr[i] << endl;cout &…