自动整定PID参数

article/2025/8/30 4:37:42

1.自整定的过程大致分为以下步骤:

        ①稳定为先:先用一个无需非常完美的PID参数调整系统,使系统的被调量和输出都达到稳态,并且被调量近似达到设定值。
        ②强行震荡:再暂时禁用PID调节,使控制器将一个矩形波状的控制作用力作用于系统,当被调量低于设定值时,控制输出产生一个正的阶跃信号,迫使被调量向高处转变,当被调量高于设定值时,控制输出产生一个负的阶跃信号,迫使被调量向低处转变,由此强行使系统产生震荡。
        ③分析波形:分析以上过程产生的波形的特征,根据需要计算出相应的PID参数
投入使用:将自整定得到的参数投入PID调节器中,即可让系统实现较好的PID调节效果。

        完成波形分析后,仅需将得到的峰峰值和周期带到PID前辈们推导出的公式中,计算得到相应的PID参数,再将PID参数更新投入使用,PID自整定便大功告成!

2.部分代码

2.1 主函数main.c文件:

        由于main主函数里面会一直循环做别的控制,为了自整定的需要,需要在main的whlie循环里

#define    Auto_PID    1    //设置为1则进入自动整定状态(注意这时需要关闭另外的PID加热功能)if(Auto_PID){//用于PID自整定//测试AC_EN_Open;SetTextFloat(Page_13, 16, (Start == 124) ? (PT100_Temp1):(PT100_Temp2), 1, 1);//三目运算(显示当前通道温度)Handle_PID_AT((Start == 124) ? 1: 2);//三目运算(确定哪一路加热进行自整定)//判断自整定结束,结束则退出if(PID_AutoTune.State==STATE_End){Start=0;PID_AutoTune.State=0;switch (Auto_PID){case 1:PID1.kp=PID_AutoTune.Proportion;PID1.ki=PID_AutoTune.Integration;PID1.kd=PID_AutoTune.Differentiation;break;}}HAL_IWDG_Refresh(&hiwdg);//喂狗HAL_Delay(500);HAL_IWDG_Refresh(&hiwdg);//喂狗}

2.2 PID_Auto.h文件:

#ifndef __PID_AUTO_H
#define __PID_AUTO_H#include "hmi_driver.h"
#include "EEPROM.h"struct PID_Auto{uint16_t Timing;				//自整定计时器uint16_t TempSet;				//自整定设置温度uint16_t TempCheck[10];	//检测点	uint16_t TempPeakRecord[2][3];		//温度峰值记录[0]=时间,[1]=温度; 	uint8_t State;							//处于阶段uint8_t State_History;	//历史阶段uint8_t	Channel;						//测温通道uint8_t PWM_out;uint16_t Pu;uint16_t A; float Ku;float Proportion; 			// 比例常数Proportional Constfloat Integration; 			// 积分常数Integral Constfloat Differentiation;	// 微分常数Derivative Const
};#define STATE_Init			0	//初始化阶段
#define STATE_PreHeat		1	//预加热阶段
#define STATE_Inertia		2	//惯性升温阶段
#define STATE_PreShake	3	//预振荡阶段 	
#define STATE_Shake			4	//继电器振荡阶段
#define STATE_Analyse		5	//整定结束分析阶段
#define STATE_End				6	//整定结束#define PID_AT_PreStop	5		//温度预停止点
#define MAX_PWM_VALUE  	40	//PID运行最大输出值,代表最大功率#define _SCREEN_PidSet	13															//PID自整定页面
#define _TXTDISPLAY_PidSet_PID_AutoTune_Timing		45		//自整定计时
#define _TXTDISPLAY_PidSet_Pu				38		//周期
#define _TXTDISPLAY_PidSet_A				27		//差值#define		Set(A,B,C)			HAL_GPIO_WritePin(A,B,C)#define		AC220_1_Open		Set(AC220_1_GPIO_Port,AC220_1_Pin,RESET);	  //固态继电器1
#define		AC220_1_Stop		Set(AC220_1_GPIO_Port,AC220_1_Pin,SET);			//固态继电器1#define		AC220_2_Open		Set(AC220_2_GPIO_Port,AC220_2_Pin,RESET);	  //固态继电器2
#define		AC220_2_Stop		Set(AC220_2_GPIO_Port,AC220_2_Pin,SET);			//固态继电器2#define		AC220_3_Open		Set(AC220_3_GPIO_Port,AC220_3_Pin,RESET);	  //固态继电器3
#define		AC220_3_Stop		Set(AC220_3_GPIO_Port,AC220_3_Pin,SET);			//固态继电器3void Clear_PID_AT_HMI(void);
void Handle_PID_AT(uint8_t channel);#endif 

 2.3 PID_Auto.c文件:

#include "PID_Auto.h"
#include "PID.h"struct PID_Auto PID_AutoTune;	//定义自整定结构体
struct PID PID3;							//定义PID结构体#define PWM_OutH 40			//PWM高值
#define PWM_OutL 0			//PWM低值uint16_t Temp[3];							//缓存的温度数据
extern uint16_t number13_10;	//设置的自整定温度
extern float PT100_Temp1;			//采集的温度值1
extern float PT100_Temp2;			//采集的温度值2//页面上数据置0
void Clear_PID_AT_HMI(void){SetTextFloat(_SCREEN_PidSet, 16, 0, 1, 1);HAL_Delay(20);SetTextInt32(_SCREEN_PidSet, 31, 0, 0, 1);HAL_Delay(20);SetTextInt32(_SCREEN_PidSet, 45, 0, 0, 1);HAL_Delay(20);SetTextInt32(_SCREEN_PidSet, 22, 0, 0, 1);HAL_Delay(20);SetTextInt32(_SCREEN_PidSet, 18, 0, 0, 1);HAL_Delay(20);SetTextInt32(_SCREEN_PidSet, 25, 0, 0, 1);HAL_Delay(20);SetTextInt32(_SCREEN_PidSet, 19, 0, 0, 1);HAL_Delay(20);SetTextInt32(_SCREEN_PidSet, 30, 0, 0, 1);HAL_Delay(20);SetTextInt32(_SCREEN_PidSet, 28, 0, 0, 1);HAL_Delay(20);SetTextInt32(_SCREEN_PidSet, 38, 0, 0, 1);HAL_Delay(20);SetTextInt32(_SCREEN_PidSet, 27, 0, 0, 1);HAL_Delay(20);
}//自整定函数
void Handle_PID_AT(uint8_t channel){static uint16_t flag_n = 0;Temp[1]=(uint16_t)(PT100_Temp1*10);				//温度取一个小数Temp[2]=(uint16_t)(PT100_Temp2*10);				//温度取一个小数PID_AutoTune.TempSet=number13_10*10;			//设置的自整定温度取一个小数PID_AutoTune.Channel=channel;//选取整定通道(改)/缓存的10个近期温度数据(第0位最新的)/PID_AutoTune.TempCheck[9] = PID_AutoTune.TempCheck[8];	PID_AutoTune.TempCheck[8] = PID_AutoTune.TempCheck[7];PID_AutoTune.TempCheck[7] = PID_AutoTune.TempCheck[6];PID_AutoTune.TempCheck[6] = PID_AutoTune.TempCheck[5];PID_AutoTune.TempCheck[5] = PID_AutoTune.TempCheck[4];	PID_AutoTune.TempCheck[4] = PID_AutoTune.TempCheck[3];PID_AutoTune.TempCheck[3] = PID_AutoTune.TempCheck[2];PID_AutoTune.TempCheck[2] = PID_AutoTune.TempCheck[1];PID_AutoTune.TempCheck[1] = PID_AutoTune.TempCheck[0];PID_AutoTune.TempCheck[0] = Temp[PID_AutoTune.Channel];/   历史阶段 or 现在阶段不同时,31处显示自整定阶段  ///if(PID_AutoTune.State != PID_AutoTune.State_History){																SetTextInt32(_SCREEN_PidSet, 31, PID_AutoTune.State, 0, 1);//整定阶段显示PID_AutoTune.State_History = PID_AutoTune.State;}//判断State在哪个阶段switch(PID_AutoTune.State){//********************初始化阶段(关闭全部加热,数据清除)case STATE_Init:{AC220_1_Stop;//关闭加热AC220_2_Stop;//关闭加热PID_AutoTune.Timing = 0;  //自整定计时器清零PID_AutoTune.TempSet = 0;	//清零//清除温度检测数据for (uint8_t n=0; n<10; n++){PID_AutoTune.TempCheck[n]=0;}//清除峰值记录数据for (uint8_t n=0; n<3; n++){PID_AutoTune.TempPeakRecord[0][n] = 0;PID_AutoTune.TempPeakRecord[1][n] = 0;}PID_AutoTune.State = 0;					//清零PID_AutoTune.State_History = 0;	//清零PID_AutoTune.Ku = 0;	//清除PIDPID_AutoTune.Pu =	0;	//清除PIDPID_AutoTune.A 	= 0;	//清除PIDClear_PID_AT_HMI();		//清空右下角全部的数值PID_AutoTune.State = STATE_PreHeat;//进入下一个阶段}break;//********************预加热阶段1case STATE_PreHeat:{//到达预终止点前,一直加热	if((Temp[PID_AutoTune.Channel]+PID_AT_PreStop*10) < PID_AutoTune.TempSet){PID_Init(&PID3, 12, 1.1, 120, 25, 100);PID_AutoTune.PWM_out=PID_Calc(&PID3,PID_AutoTune.TempSet/10,Temp[PID_AutoTune.Channel]/10);SetControlVisiable(_SCREEN_PidSet,46,1);//显示加热图标}else{PID_AutoTune.PWM_out=0;SetControlVisiable(_SCREEN_PidSet,46,0);//隐藏加热图标PID_AutoTune.State = STATE_Inertia;//进入下一个阶段}}break;//**********************惯性升温2(惯性升温后,降温开始则跳入下一阶段)case STATE_Inertia:{//检测温度是否处于跌落状态    (惯性升温后,降温开始则跳入下一阶段)if(PID_AutoTune.TempCheck[0] < PID_AutoTune.TempCheck[9]){ //检测5秒flag_n  = 0;PID_AutoTune.State = STATE_PreShake;//进入下一个阶段}}break;	//**********************预振荡阶段3case STATE_PreShake:{if(Temp[PID_AutoTune.Channel] < PID_AutoTune.TempSet){//加热引脚打开,进行加热PID_AutoTune.PWM_out=PWM_OutH;SetControlVisiable(_SCREEN_PidSet,46,1);//显示加热图标//判断是否到波谷if(flag_n==1)	flag_n=2;}else{//加热引脚关闭,不加热PID_AutoTune.PWM_out=PWM_OutL;SetControlVisiable(_SCREEN_PidSet,46,0);//隐藏加热图标switch(flag_n){case 0:	flag_n = 1;	break;	//第一次到波峰case 2:	//经过一个预振荡周期,过设置温度,进入振荡阶段flag_n = 0;PID_AutoTune.Timing = 0;PID_AutoTune.State = STATE_Shake;//进入下一个阶段break;}}}break;//*************************振荡阶段4case STATE_Shake:{PID_AutoTune.Timing++;	//计时if(Temp[PID_AutoTune.Channel] < PID_AutoTune.TempSet){//加热引脚打开,进行加热PID_AutoTune.PWM_out=PWM_OutH;SetControlVisiable(_SCREEN_PidSet,46,1);//显示加热图标if(flag_n==0){//显示上个记录值SetTextInt32( _SCREEN_PidSet, 22, PID_AutoTune.TempPeakRecord[0][flag_n], 0, 1);SetTextFloat( _SCREEN_PidSet, 18, ((float)PID_AutoTune.TempPeakRecord[1][flag_n])/10, 1, 1);flag_n=1;PID_AutoTune.TempPeakRecord[0][flag_n] = PID_AutoTune.Timing;PID_AutoTune.TempPeakRecord[1][flag_n] = Temp[PID_AutoTune.Channel];}//检测波谷波形if(Temp[PID_AutoTune.Channel] < PID_AutoTune.TempPeakRecord[1][flag_n]){PID_AutoTune.TempPeakRecord[0][flag_n] = PID_AutoTune.Timing;PID_AutoTune.TempPeakRecord[1][flag_n] = Temp[PID_AutoTune.Channel];}}else{//加热引脚关闭,不加热PID_AutoTune.PWM_out=PWM_OutL;SetControlVisiable(_SCREEN_PidSet,46,0);//隐藏加热图标if(flag_n==1){//显示上个记录值SetTextInt32(_SCREEN_PidSet, 25, PID_AutoTune.TempPeakRecord[0][flag_n], 0, 1);SetTextFloat(_SCREEN_PidSet, 19, ((float)PID_AutoTune.TempPeakRecord[1][flag_n])/10, 1, 1);flag_n=2;PID_AutoTune.TempPeakRecord[0][flag_n] = PID_AutoTune.Timing;PID_AutoTune.TempPeakRecord[1][flag_n] = Temp[PID_AutoTune.Channel];}//检测波峰波形if(Temp[PID_AutoTune.Channel] > PID_AutoTune.TempPeakRecord[1][flag_n]){PID_AutoTune.TempPeakRecord[0][flag_n] = PID_AutoTune.Timing;PID_AutoTune.TempPeakRecord[1][flag_n] = Temp[PID_AutoTune.Channel];}//完成两个波峰和一个波谷的检测则退出振荡if(flag_n==2){//检测温度是否处于跌落状态    (升温后,降温开始则跳入下一阶段)if(PID_AutoTune.TempCheck[0] <  PID_AutoTune.TempCheck[9]){ //检测5秒//显示上个记录值SetTextInt32(_SCREEN_PidSet, 30, PID_AutoTune.TempPeakRecord[0][flag_n], 0, 1);SetTextFloat(_SCREEN_PidSet, 28, ((float)PID_AutoTune.TempPeakRecord[1][flag_n])/10, 1, 1);PID_AutoTune.State = STATE_Analyse;//进入下一个阶段}}}}break;//*********************************分析阶段5case STATE_Analyse:{。。。。。。PID_AutoTune.State = STATE_End;//进入下一个阶段	}break;	}//显示计时秒数SetTextInt32(_SCREEN_PidSet, _TXTDISPLAY_PidSet_PID_AutoTune_Timing, PID_AutoTune.Timing, 0, 1);}

3.完整代码

        下载链接:https://download.csdn.net/download/qq_26043945/87839384

4.参考网址

        参考链接:http://t.csdn.cn/Qp9Nd


http://chatgpt.dhexx.cn/article/7FRBYMQr.shtml

相关文章

PID参数整定具体方法-圆周倒立摆

0.前言 关于PID参数的整定&#xff0c;网上调节的口诀、原则、方法满天飞&#xff0c;但是并没有具体的到步的教程&#xff0c;作为初学者且非自动化相关专业学生有点看不懂、一脸懵逼&#xff0c;走了不少弯路&#xff0c;呕心沥血才调节好&#xff0c;之后才看得懂那些口诀、…

用电机进行简单的PID参数整定

最近一直在学习PID的相关知识&#xff0c;网上有很多心得和口诀&#xff0c;看完过后感觉自己好像是懂了一些&#xff0c;但让自己实践一下又感觉无从下手&#xff0c;举手无措。所以今天我决定&#xff0c;直接上手一个简单的电机速度PID试试。 准备阶段 一块主控板子 我这里…

PID参数整定一些总结

PID参数整定法总结 PID控制规律 2、PID传递函数 3、各环节的作用 比例环节作用&#xff1a; 系统一旦出现偏差&#xff0c;比例环节立即产生调节作用以减小系统偏差&#xff0c;比例作用大 ,可以加快调节,减少误差,但是过大的比例,使系统的稳定性下降,甚至遥成系统的不稳定…

PID参数快速整定

点击–查看原文 全套资料免费下载&#xff1a; 关注v-x-公-众-号&#xff1a;【嵌入式基地】 后-台-回-复&#xff1a;【电赛】 即可获资料 回复【编程】即可获取 包括有&#xff1a;C、C、C#、JAVA、Python、JavaScript、PHP、数据库、微信小程序、人工智能、嵌入式、Linux、…

PID参数整定方法

介绍一种临界比例度法调节PID参数&#xff0c;也称为Ziegler-Nichols工程整定法。 1.临界比例度法的定义 适用于已知对象传递函数场合。 在闭环的控制系统中&#xff0c;激励为阶跃信号&#xff0c;将调节器置于纯比例作用下&#xff0c;从小到大逐渐改变调节器比例度的大小&a…

PID整定方法

转自&#xff1a;https://www.zhihu.com/question/27478212/answer/136494252 知乎用户 17 人赞同了该回答 个人总结的&#xff0c;希望有所帮助&#xff0c;都是平时搜索到的&#xff0c;然后整理的干货 1.在不发生震荡时&#xff0c;增大比例系数&#xff0c;减小积分…

PID参数整定方法介绍

文章目录 完全经验法等幅振荡法衰减曲线法响应曲线法 完全经验法 这种方法没有任何定量规律可循&#xff0c;凭借的是工程技术人员对控制系统与控制对象的工作机理、工作环境的熟悉&#xff0c;是一种粗糙的调参方法&#xff0c;一些定性的调参准则如下&#xff1a; 参数整定…

PID控制算法与参数整定,用这几招轻松搞定!

关注、星标公众号&#xff0c;不错过精彩内容 直接来源&#xff1a;21ic电子网 之前给大家分享过PID基础理论的文章&#xff1a; 重温经典PID算法 PID原理和参数调试 今天进一步分享一些PID相关细节内容。 在过程控制中&#xff0c;按偏差的比例(P)、积分(I)和微分(D)进行控制的…

IBIS建模——第2部分:为何以及如何创建您自己的IBIS模型

IBIS建模——第2部分&#xff1a;为何以及如何创建您自己的IBIS模型 【导读】本文提供有关在创建IBIS模型时如何使用LTspice的说明指南&#xff0c;涵盖从IBIS预建模程序到IBIS模型验证的整个过程。本文还详细介绍如何在LTspice中为IBIS模型准确提取I-V、V-T、斜坡和C_comp数据…

这么说IBIS模型,你应该就懂了

读datasheet最高深的境界&#xff0c;不仅要看datasheet上的内容&#xff0c;凡是涉及到的算法&#xff0c;协议&#xff0c;配合器件&#xff0c;都要懂&#xff0c;要善于做延展辅助阅读&#xff0c;甚至看清楚芯片背后的设计哲学。听说要写个datasheet简单的三四个月&#x…

学习笔记二:IBIS模型编辑报错纠正

新建IBIS文件后&#xff0c;写好了相应的IBIS模型文件。 写好文件后&#xff0c;最好要检查下是否符合ibis语法。 注意&#xff1a; 第一点&#xff1a;IBIS头文件的[File name]&#xff0c;此处名称需要和文件名称相同&#xff0c;同时名称字符数需在12个字符之内。否则会报错…

Cadence Allegro 17.4 IBS文件处理(IBIS模型)

Cadence Allegro 17.4 IBS文件处理(IBIS模型) IBIS(Input/Output Buffer Informational Specifation)是用来描述IC器件的输入、输出和I/OBuffer行为特性的文件,并且用来模拟Buffer和板上电路系统的相互作用。在IBIS模型里核心的内容就是Buffer的模型,因为这些Buffer产生…

Candence PCB Si 仿真设计篇前导:IBIS模型与PKG介绍

最近在做项目时遇到了一个信号SI问题&#xff0c;想自己动手仿真一下&#xff0c;就自己研究了一下如何用Candece 下面的Allegro Sigrity SI进行PCB板级链路仿真&#xff1a;在仿真之前我们要做的第一个准备工作就是准备需要仿真的器件模型&#xff1a;IBIS模型以及PKG文件。 1…

数据传输完整性_基于IBIS模型的FPGA信号完整性仿真验证方法

人工智能与深度学习等领域的快速发展&#xff0c;使得FPGA等器件应用范围愈加广泛&#xff0c;同时也要求器件的开关速率加快、引脚数量增多。但陡峭的时钟边沿和增加的引脚数使得杂散、耦合、寄生电容电感会对器件产生诸多信号完整性(Signal Integrity&#xff0c;SI)问题。这…

Candence PCB Si 仿真设计篇1:为仿真文件添加ibis模型

软件版本&#xff1a;cadence 16.6 仿真拓扑如下&#xff1a; 本章节主要完成对上述目标仿真拓扑中的PLL时钟芯片和FPGA完成IBIS模型的配置&#xff1b; 1.打开cadence PCB SI GXL&#xff1b; 2.在PCB SI GXL中打开板级文件.brd文件 3.在PCB SI GXL菜单栏Analyze-》Signal …

Cir 和 IBIS模型的使用

Cir 和 IBIS模型的使用在Analog上&#xff0c;很多时候下载到的是 cir和ibs 文件&#xff0c;那么如何使用呢。Cadence 中的pspice套件中含有编辑模型的程序模块&#xff0c;可以使用它进行转换&#xff0c;得到Capture库文件&#xff08;olb格式&#xff09; 和 Pspice 库文件…

Vivado使用技巧(17):创建IBIS模型

IBIS模型概述 IBIS是一种器件模型标准&#xff0c;允许使用行为模型进行开发&#xff0c;这些行为模型描述了器件内部互联的信号。IBIS模型保留专用的电路信息&#xff0c;不像SPICE这种结构化模型&#xff0c;IBIS模型是基于测量或电路仿真得到的 V/I曲线数据。 每个IOB标准…

信号完整性分析学习--13--IBIS模型(2)

IBIS模型除了用于SI仿真&#xff0c;我们还可以从IBIS模型中得到一些有用的东西&#xff0c;如信号上升时间&#xff0c;输出阻抗以及封装延时等等。 从IBIS模型中可以获得信号上升时间信息 IBIS模型中的关键字[Ramp]定义了buffer输出的上升下降沿的斜率。如下为micron的DDR3芯…

初识IBIS模型

关注、星标公众号&#xff0c;精彩内容每日送达 来源&#xff1a;网络素材 半导体LSI的EDA模型之一是"IBIS模型"&#xff0c;完整称为Input/Output Buffer Information Specification&#xff0c;是一个描述数字IC输入端和输出端电气特性的文本文件&#xff0c;在电路…

Cadence PCB仿真 使用Allegro PCB SI为BRD文件创建通用型IBIS模型的方法图文教程

⏪《上一篇》   🏡《总目录》   ⏩《下一篇》 1,概述 本文简单介绍使用Allegro PCB SI软件为BRD PCB设计文件中的元器件创建IBIS模型的方法。 2,创建方法 第1步:确定打开PCB文件的软件是 Allegro PCB SI 如果不是Allegro PCB SI,可执行File→Change Editor…更换软…