使用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);  //微分D

	err->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);    //微分D

	err->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++;
		}
		else
			cnt =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);    //微分D

	err->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);    //微分D

	err->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++;
		}
		else
			cnt = 0;
	}
}


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[Algorithm][滑动窗口][长度最小的子数组] + 滑动窗口原理

目录 0.滑动窗口原理讲解1.长度最小的子数组1.题目链接2.算法原理讲解3.代码实现 0.滑动窗口原理讲解 滑动窗口&#xff1a;“同向双指针”滑动窗口可处理「⼀段连续的区间」问题如何使用&#xff1f; left 0, right 0进窗口判断 是否出窗口 更新结果 -> 视情况而定 可能…

使用Canal同步MySQL 8到ES中小白配置教程

&#x1f680; 使用Canal同步MySQL 8到ES中小白配置教程 &#x1f680; 文章目录 &#x1f680; 使用Canal同步MySQL 8到ES中小白配置教程 &#x1f680;**摘要****引言****正文**&#x1f4d8; 第1章&#xff1a;初识Canal1.1 Canal概述1.2 工作原理解析 &#x1f4d8; 第2章&…

数据赋能(60)——要求:数据服务部门能力

“要求&#xff1a;数据服务部门实施数据赋能影响因素”是作为标准的参考内容编写的。 在实施数据赋能中&#xff0c;数据服务部门的能力体现在多个方面&#xff0c;关键能力如下图所示。 在实施数据赋能的过程中&#xff0c;数据服务部门应具备的关键能力如下。 业务理解和沟…

C++:文件内容完全读入

在上一篇文章中我留下了一点小坑&#xff1a;使用>> 运算符&#xff0c;这个运算符默认将空格作为分隔符&#xff0c;所以在文件内容读取的时候发现在读到空格时就会停止读取&#xff0c;导致读取内容不完整&#xff0c;这显然不符合日常的使用用能&#xff0c;那么今天就…

Djanog的中间件

1 中间件的五个方法 process_request(self,request)process_response(self, request, response)process_view(self, request, view_func, view_args, view_kwargs)process_exception(self, request, exception)process_template_response(self,request,response) 中间件处理函…

详解运算符重载,赋值运算符重载,++运算符重载

目录 前言 运算符重载 概念 目的 写法 调用 注意事项 详解注意事项 运算符重载成全局性的弊端 类中隐含的this指针 赋值运算符重载 赋值运算符重载格式 注意点 明晰赋值运算符重载函数的调用 连续赋值 传引用与传值返回 默认赋值运算符重载 前置和后置重载 前…

Scikit-Learn

机器学习中的重要角色 Scikit-Leran&#xff08;官网&#xff1a;https://scikit-learn.org/stable/&#xff09;&#xff0c;它是一个基于 Python 语言的机器学习算法库。Scikit-Learn 主要用 Python 语言开发&#xff0c;建立在 NumPy、Scipy 与 Matplotlib 之上&#xff0c;…

嵌入式中strstr函数详解

一、strstr函数是什么? strstr函数是 C 语言中的一个标准库函数(使用时要引入头文件string.h),用于在一个字符串中查找另一个字符串首次出现的位置。如果找到子串,则返回子串在主串中首次出现的位置的指针;如果未找到,则返回 NULL。 二、使用场景 1.用来找出字符串1在字…

学习了解大模型的四大缺陷

由中国人工智能学会主办的第十三届吴文俊人工智能科学技术奖颁奖典礼暨2023中国人工智能产业年会于2024年4月14日闭幕。 会上&#xff0c;中国工程院院士、同济大学校长郑庆华认为&#xff0c;大模型已经成为当前人工智能的巅峰&#xff0c;大模型之所以强&#xff0c;是依托了…

GPT国内怎么用

2022年11月&#xff0c;OpenAI发布了ChatGPT&#xff0c;这标志着大型语言模型在自然语言处理领域迈出了巨大的一步。ChatGPT不仅在生成文本方面表现出了惊人的流畅度和连贯性&#xff0c;更为人工智能应用开启了全新的可能性。 ChatGPT的推出促进了人工智能技术在多个领域的广…

网工交换技术基础——VLAN原理

1、VLAN的概念&#xff1a; VLAN(Virtual LAN)&#xff0c;翻译成中文是“虚拟局域网”。LAN可以是由少数几台家用计算机构成的网络&#xff0c;也可以是数以百计的计算机构成的企业网络。VLAN所指的LAN特指使用路由器分割的网络——也就是广播域。 2、VLAN的主要作用&#xf…

stm32f103c8t6学习笔记(学习B站up江科大自化协)-SPI

SPI通信 SPI&#xff0c;&#xff08;serial peripheral interface&#xff09;&#xff0c;字面翻译是串行外设接口&#xff0c;是一种通用的数据总线&#xff0c;适用于主控和外挂芯片之间的通信&#xff0c;与IIC应用领域非常相似。 IIC无论是在硬件电路还是在软件时序设计…

JUC知识点三

执行TestFrames这个类的时候发生了什么呢&#xff1f; 执行TestFrames这个类的时候发生了什么呢&#xff1f; 1、首先执行一个类加载&#xff0c;把TestFrames这个类的二进制字节码加载到java虚拟机中的方法区内存中&#xff08;其实是二进制的字节码&#xff0c;只是为了好理…

linux运行ant 报错 Unable to locate tools.jar【已解决】

linux安装 ant 运行时报错 Unable to locate tools.jar. Expected to find it in /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.402.b06-1.el7_9.x86_64/lib/tools.jar 原因 已安装的jdk只有运行环境&#xff0c;没有tool.jar&#xff0c;而ant运行需要java开发环境&#xff0c;因…

如何进行数据库的迁移与同步——【DBA 从入门到实践】第四期

在日常的数据库运维工作中&#xff0c;我们时常会面临数据库替换、机房搬迁、业务测试以及数据库升级等任务&#xff0c;这些任务都需要对数据进行迁移和同步操作。【DBA 从入门到实践】第4期&#xff0c;将引导大家深入了解数据库迁移的流程&#xff0c;并探讨在迁移过程中可用…

Zynq学习笔记--AXI 总线仿真(AXI VIP)

目录 1. 概述 2. Simulation with AXI VIP 2.1 axi_vip_pkg 2.2 design_1_axi_vip_0_0_pkg 2.3 参数指定 3. 实例化注意事项 3.1 名称对应关系 3.2 寄存器地址 3.3 block design 1. 概述 AXI Verification IP&#xff08;AXI VIP&#xff09;是一种用于验证AXI总线协议的…

无需公网IP,安全稳定实现U8C异地访问

无需公网IP&#xff0c;安全稳定实现U8C异地访问 用友是全球领先的企业云服务与软件提供商&#xff0c; 在财务、人力、供应链、采购、制造、营销、研发、项目、资产、协同等领域为客户提供数字化、智能化、社会化的企业云服务产品与解决方案。 U8C是用友针对成长型、创新型…

ElasticSearch中使用向量和关键词联合检索

注&#xff1a;案例测试数据及其索引构建详见&#xff1a;ElasticSearch中使用bge-large-zh-v1.5进行向量检索&#xff08;一&#xff09;-CSDN博客 中的第三部分。 假设任务场景为&#xff1a;用“新疆”向量检索相关的数据&#xff0c;同时需要匹配关键词“巴州”。 首先获取…

最新免费 ChatGPT、GPTs、AI换脸(Suno-AI音乐生成大模型)

&#x1f525;博客主页&#xff1a;只恨天高 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ ChatGPT3.5、GPT4.0、GPTs、AI绘画相信对大家应该不感到陌生吧&#xff1f;简单来说&#xff0c;GPT-4技术比之前的GPT-3.5相对来说更加智能&#xff0c;会根据用户的要求生成多种内容…

基于快照行情的股票/基金 1分钟 K 线合成指南

1. 概述 由于不同交易所不同资产的交易规则是有差异的&#xff0c;导致不同交易所基于快照行情或逐笔成交合成不同资产1分钟 K 线的计算方法是不同的。 本教程旨在提高 DolphinDB 在具体业务场景下的落地效率&#xff0c;降低 DolphinDB 在实际业务使用中的开发难度。 本教程…