使用CCS软件查看PID曲线

  在刚开始学习PID的时候,都需要借助PID的曲线来理解比例,积分,微分这三个参数的具体作用。但是这些曲线生成一般都需要借助上位机软件或者在网页上才能实现。如果是在单片机上调试程序的话,想要看曲线,一般就是通过串口将数据发送出去,然后使用串口波形显示软化将曲线打印出来。
如果使用的是CCS软件来开发的话,那么就可以直接使用CCS软件自带的图形显示工具来打印曲线。
  比如要测试的代码如下:

typedef struct
{float P;float I;float D;float limit;
}PID;typedef struct
{float Current_Error;			//当前误差float Last_Error;				//上一次误差float Previous_Error;			//上上次误差
}ERROR;
// 位置式PID
float PID_Realize(ERROR *err, PID *pid, float feedback, float reference)
{float iError, Realize;    						// 当前误差 实际输出iError = reference - feedback;					// 计算当前误差  期望值-当前值err->Current_Error += pid->I * iError;    		// 误差积分err->Current_Error = err->Current_Error > pid->limit ? pid->limit : err->Current_Error;	//积分限幅err->Current_Error = err->Current_Error < -pid->limit ? -pid->limit : err->Current_Error;Realize = pid->P * iError       				//比例P+ err->Current_Error    						//积分I+ pid->D * (iError - err->Last_Error);  //微分Derr->Last_Error = iError;		  				// 更新上次误差return Realize;    								// 返回实际值
}// 增量式PID
float PID_Increase(ERROR *err, PID *pid, float feedback, float reference)
{float iError, Increase;    						// 当前误差  最后得出的实际增量iError = reference - feedback;    				// 计算当前误差Increase = pid->P * (iError - err->Last_Error)  //比例P+ pid->I * iError      							//积分I+ pid->D * (iError - 2 * err->Last_Error + err->Previous_Error);    //微分Derr->Previous_Error = err->Last_Error;    		// 更新前次误差err->Last_Error = iError;		  				// 更新上次误差return Increase;								// 返回增量
}

  这是两种很典型的PID算法,一个位置式,一个增量式。下面就在CCS软件中测试这两个函数,这里使用的是dsp28335芯片。首先定义PID和ERROR结构体变量。

PID pid = { 0.1, 0.01, 0.001, 100.0 };
ERROR err = { 0.0, 0.0, 0.0 };

  接下来就可以直接在main函数中调用上面两种pid的算法了。

float ref = 100;		//参考值
float sample1=0,sample2=0;	//采样值
void main()
{InitSysCtrl();InitPieCtrl();IER = 0x0000;IFR = 0x0000;InitPieVectTable();LED_Init();while(1){sample1 += PID_Realize(&err,&pid,sample1,ref);sample2 += PID_Increase(&err,&pid,sample2,ref);}
}

  将需要设定的参考值ref设置为100,然后两个采样值sample1sample2都设置为0,将PID计算出来的结果作为第二次的输入,然后在调用PID计算,这样一直循环。

  代码编写完成之后,直接debug开始调试。

进入调试界面之后,在变量sample1上单击鼠标右键,选择添加到观察窗口
在这里插入图片描述
弹出的窗口上点OK
在这里插入图片描述
此时窗口右边就会出现一个变量显示区域
在这里插入图片描述
同样在变量sample2上也单击右键,添加到观察窗口。
在这里插入图片描述
  添加完成之后,将黄色箭头的图标选中,这个是实时刷新功能,这样在代码全速运行的时候,就可实时看到变量值在变化。接下来全速运行代码。
在这里插入图片描述
  此时可以看到这两个变量值都停在在100作用不变化了,没有看到变换的过程。下面将这两个值添加到图形显示中。在观测窗口变量值上单击鼠标右键,选择Graph。

在这里插入图片描述
此时就会新增一个图形显示窗口
在这里插入图片描述
在另一个变量上右键,选择Graph。
在这里插入图片描述
  此时又增加了一个显示窗口,但是这两个窗口重叠在了一起,看起来不方便,在窗口标题处按住鼠标左键,拖动窗口,将两个图形显示调节到合适的位置。
在这里插入图片描述

  然后再这两个图形显示窗口上,将实时刷新的按钮选中。
在这里插入图片描述
接下里全速运行程序。
在这里插入图片描述
  这时候PID调节的曲线就显示出来了,但是这个曲线和PID调节的曲线看起来不太一样,难道是程序有问题吗?当然不是程序的问题,是这个图形显示的刷新率太低了,而我们的程序执行的太快了。下面在代码中添加延时。

while(1){sample1 += PID_Realize(&err,&pid,sample1,ref);sample2 += PID_Increase(&err,&pid,sample2,ref);DELAY_US(1000*200);}

  重新编译运行代码
在这里插入图片描述
在这里插入图片描述
这时候就可看到右侧的变量和曲线都在缓慢的变化,可以看到PID的调节过程了。
在这里插入图片描述
  为了方便修改PID的参数,将结构体变量pid也添加到观察窗口中。在代码中选中pid然后右键添加到观察窗口。
在这里插入图片描述
  此时右边的观察窗口中就多了一个pid的结构体变量,将PID前面的加号点开,这时候就可以看到结构体中每个成员的值了。
在这里插入图片描述
  这时候在变量窗口中就可以直接修改这些参数的值了。鼠标双击要修改的值,选中值之后,直接输入要改的值,然后按回车键。
在这里插入图片描述
这里将P的值修改为0.2在这里插入图片描述
修改完成之后,底下的曲线没有发生变化。要想重新看pid的调节过程,这里将两个采样值都改为0 。
在这里插入图片描述
这时候PID函数就会从0开始重新计算,底下的曲线也会重新绘制。
在这里插入图片描述
  这样只需要在变量观察窗口直接修改PID的参数,就能实时看到PID曲线的效果了。不用在程序里面修改一次参数然后又重新仿真运行。

  还有一种方法,不需要加延时也能实时查看波形。下面就介绍一下这个方法。
定义两个数组来存放采样值,然后增加一个变量来记录数组的下标。在主函数中将采样的两个值分别存放到数组中,当数组个数超过200个之后,将下标清零。此时代码中将延时函数去掉了。没有延时,相当于代码按照正常的计算速度运行。

int cnt=0;
float value1[200];
float value2[200];while(1){sample1 += PID_Realize(&err,&pid,sample1,ref);sample2 += PID_Increase(&err,&pid,sample2,ref);//DELAY_US(1000*200);if(cnt<200){value1[cnt] = sample1;value2[cnt] = sample2;cnt++;}elsecnt =0;}

仿真运行代码,进入仿真界面后再工具栏选择 Tools—Grapg—Single Time
在这里插入图片描述
这时候会弹出一个对话框,在对话框中填入需要观测的数组信息。
在这里插入图片描述
将数组相关信息填写进去,然后点OK按钮,此时就会新增一个图形显示窗口
在这里插入图片描述
按照同样的方法,在工具栏选择 Tools—Grapg—Single Time,将value2数组也添加到图形显示中,然后选中实时刷新按钮。
在这里插入图片描述
然后在 cnt=0这一行打个断点,用来观察一次计算完成之后的波形。全速运行代码。
在这里插入图片描述
  程序在断点处停止后,左边两个图形显示的是正常的PID调节曲线,右边两个是阶跃信号。这是因为取消延时后,图形显示的刷新率太低,不能实时捕获到每个数据,所以直接显示变量的曲线就看不出来细节了,而数组显示比较完整,是因为代码中将过程中的所有数据都先存储到了数组中,然后根据数组中的数据来绘制曲线。
  继续全速运行,这时候曲线就会变成一条直线,这是因为PID调节完成之后,数组中的值被更新了。
在这里插入图片描述

如果还想继续观察调节过程,在程序中断之后,将sample1sample2的值改为0,修改完之后,这时变量的曲线值也会从100变为0.
在这里插入图片描述
  全速运行代码
在这里插入图片描述
这时候左边两个数组的曲线就会被重新绘制出来。

  如果要修改PI参数的话,每次程序在断点处停止之后,修改PI参数,然后将sample1sample2的值改为0,接着全速运行,就可观测到新的PI参数生成的曲线了。
在这里插入图片描述
  这样在学习PID的时候就不用借助上位机软件,使用CCS本身的图形显示工具,就能看到不同参数下PID调节的差别了。
在这里插入图片描述
完整代码如下

#include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h"   // DSP2833x Examples Include File
#include "leds.h"
typedef struct
{float P;float I;float D;float limit;
} PID;typedef struct
{float Current_Error;			//当前误差float Last_Error;				//上一次误差float Previous_Error;			//上上次误差
} ERROR;// 位置式PID控制
float PID_Realize(ERROR *err, PID *pid, float feedback, float reference)
{float iError, Realize;    						// 当前误差 实际输出iError = reference - feedback;					// 计算当前误差  期望值-当前值err->Current_Error += pid->I * iError;    		// 误差积分err->Current_Error = err->Current_Error > pid->limit ? pid->limit : err->Current_Error;    //积分限幅err->Current_Error = err->Current_Error < -pid->limit ? -pid->limit : err->Current_Error;Realize = pid->P * iError       				//比例P+ err->Current_Error    						//积分I+ pid->D * (iError - err->Last_Error);    //微分Derr->Last_Error = iError;		  				// 更新上次误差return Realize;    								// 返回实际值
}// 增量式PID
float PID_Increase(ERROR *err, PID *pid, float feedback, float reference)
{float iError, Increase;    						// 当前误差  最后得出的实际增量iError = reference - feedback;    				// 计算当前误差Increase = pid->P * (iError - err->Last_Error)    //比例P+ pid->I * iError      							//积分I+ pid->D * (iError - 2 * err->Last_Error + err->Previous_Error);    //微分Derr->Previous_Error = err->Last_Error;    		// 更新前次误差err->Last_Error = iError;		  				// 更新上次误差return Increase;								// 返回增量
}PID pid = { 0.1, 0.01, 0.001, 100.0 };
ERROR err = { 0.0, 0.0, 0.0 };float ref = 100;		//参考值
float sample1 = 0, sample2 = 0;    //采样值int cnt = 0;
float value1[200];
float value2[200];
void main()
{InitSysCtrl();InitPieCtrl();IER = 0x0000;IFR = 0x0000;InitPieVectTable();while (1){sample1 += PID_Realize(&err, &pid, sample1, ref);sample2 += PID_Increase(&err, &pid, sample2, ref);//DELAY_US(1000*200);if (cnt < 200){value1[cnt] = sample1;value2[cnt] = sample2;cnt++;}elsecnt = 0;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第二届 Oceanbase 开发者大会 实录

第二届 Oceanbase 开发者大会 实录 今天很有幸参加了Oceanbase 开发者大会&#xff0c;我是真的我一开始还不知道什么是Oceanbase &#xff0c;直到我开了会才知道。看来真的需要多参加一些这样活动。 会议议程 我们科普一下什么是Oceanbase OceanBase 是阿里巴巴集团推出…

openai whisper 语音转文字尝鲜

最近大模型很火&#xff0c;也试试搭一下&#xff0c;这个是openai 开源的whisper&#xff0c;用来语音转文字。 安装 按照此文档安装&#xff0c;个人习惯先使用第一个pip命令安装&#xff0c;然后再用第二个安装剩下的依赖&#xff08;主要是tiktoken&#xff09; https:/…

云知识库怎么搭建才适合中小企业?用这几个工具很轻松

当我们想到知识库时&#xff0c;可能会联想到庞大的公司和复杂的系统&#xff0c;但实际上&#xff0c;随着技术的发展&#xff0c;中小企业也可以利用各种工具来建立自己的云知识库。这样不仅能够提升企业的知识管理效率&#xff0c;还能优化客户服务流程。这篇文章会介绍三款…

数据线接口类型名称

USB TYPE-A 这个接口其实就是我们当下连接手机充电器的那个端口&#xff0c;该标准一般适用于个人电脑PC和手机适配器中&#xff0c;是应用于最广泛的接口标准。 USB TYPE-B TYPE-B接口想必很多人都没太接触过&#xff0c;因为这类线材一般用于打印机、显示器等连接传输。 US…

两个字的商标现在还可以申请下来不!

前几天有个申请主体给普推知产老杨发来多个两个字的商标名称&#xff0c;说要申请商标&#xff0c;而且还是日常用词组合&#xff0c;这样的就是想出来几十个大概率有相同或高近的&#xff0c;两个常用词及组合名称的商标名称基本都有注册的&#xff0c;但是也有捡漏的。 以前…

pycharm 更换Eclipse 的按键模式 keymap

流程 整体来说比较简单&#xff0c;其实只要下载一个eclipse keymap插件就可以完成 首先 ctrl alt s 打开设置页面&#xff0c;找到 plugin 安装完成后还是在 settings 下切换到 keymap即可以看到eclipse 的按键设置出现了&#xff0c;应用后ok 即可完成 再去试试&#x…

【java】(软考)面向对象---责任链解析

目录 责任链的意义 手写笔记 ​编辑 责任链的意义 当您把请求给出时&#xff0c;如果某对象不能实现您的操作&#xff0c;责任链会自动把您的请求传给它的下一级 从而避免请求的发送者和接受者之间的耦合关系 这里以2007年下半年试题七进行说明 题目描述 某企业的采购审批…

【声呐仿真】学习记录1-配置dave、uuv_simulator

【声呐仿真】学习记录1-配置dave、uuv_simulator 1.介绍2.配置3.一些场景 1.介绍 家|DAVE项目 — Home | Project DAVE 2.配置 参考官方教程安装|DAVE项目 — Installation | Project DAVE mkdir -p ~/uuv_ws/src cd ~/uuv_ws/src git clone https://github.com/Field-Robot…

第7章 Kafka-Kraft模式【Kafka】

第7章 Kafka-Kraft模式【Kafka】 前言推荐第7章 Kafka-Kraft模式7.1 Kafka-Kraft架构7.2 Kafka-Kraft集群部署7.3 Kafka-Kraft集群启动停止脚本 最后 前言 2024-3-27 22:46:07 本文是根据尚硅谷学习所做笔记 仅供学习交流使用&#xff0c;转载注明出处 推荐 【尚硅谷】Kaf…

【漏洞复现】WordPress_Wholesale_Market admin-ajax.php 任意文件读取漏洞

0x01 产品简介 WordPress Wholesale Market是一个WordPress主题,专门设计用于创建批发市场和在线商城网站。该主题提供了许多功能和设计元素,使您能够轻松地构建一个功能强大的批发市场平台,以满足批发商和零售商的需求。 0x02 漏洞概述 WordPress Wholesale Market存在任…

vue快速入门(三十五)组件通信-父传子

注释很详细&#xff0c;直接上代码 上一篇 新增内容 父组件传值子组件接收父组件传来的数据 源码 App.vue <template><div id"app"><!-- :item"item"为将item的值传递给MyTest组件 --><MyTest v-for"item in roles" :key&q…

【LAMMPS学习】八、基础知识(3.6)计算热导率

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…