PID控制器中,各环节的作用及优缺点,PID算法的程序实现

PID调节器:
在过程控制中,按偏差的比例(P)、积分(I)和微分(D)进行控制的PID控制器(亦称PID调节器)是应用最为广泛的一种自动控制器。它具有原理简单,易于实现,适用面广,控制参数相互独立,参数的选定比较简单等优点;而且在理论上可以证明,对于过程控制的典型对象──“一阶滞后+纯滞后”与“二阶滞后+纯滞后”的控制对象,PID控制器是一种最优控制。(摘自百度)

1 比例调节作用:
是按比例反应系统的偏差,系统一旦出现了偏差,比例调节立即产生调节作用用以减少偏差。比例作用大,可以加快调节,减少误差,但是过大的比例,使系统的稳定性下降,甚至造成系统的不稳定。

2 积分调节作用:
是使系统消除稳态误差,提高无差度。因为有误差,积分调节就进行,直至无差,积分调节停止,积分调节输出一常值。积分作用的强弱取决与积分时间常数Ti,Ti越小,积分作用就越强。反之Ti大则积分作用弱,加入积分调节可使系统稳定性下降,动态响应变慢。积分作用常与另两种调节规律结合,组成PI调节器或PID调节器。

3 微分调节作用:
微分作用反映系统偏差信号的变化率,具有预见性,能预见偏差变化的趋势,因此能产生超前的控制作用,在偏差还没有形成之前,已被微分调节作用消除。所以可以改善系统的动态性能。在微分时间选择合适情况下,可以减少超调,减少调节时间。微分作用对噪声干扰有放大作用,因此过强的加微分调节,对系统抗干扰不利。此外,微分反应的是变化率,而当输入没有变化时,微分作用输出为零。微分作用不能单独使用,需要与另外两种调节规律相结合,组成PD或PID控制器。

PID简化框图如下:
在这里插入图片描述
PID表达式:
在这里插入图片描述
MCU能处理的信号是数字信号,且我们使用增量式PID算法,经过PID算法处理后将其偏差转化为相应的PWM从而去控制电机,温度等,最终实现温度的恒定或电机转速恒定等(闭环控制系统)。

增量式PID算法:
在这里插入图片描述
在这里插入图片描述
(摘自我的毕业论文)
程序实现:
PID.C文件

#include "pid.h"
#include "relay.h"

PID pid;
/*
函数功能:初始化相应的PID参数
参数:    无
返回值:  无
注:此参数设置好后,通过24c02断电保存,此处直接初始化使用
*/
void Set_PID_Init(void)
{
	pid.Kp=200;//比例系数  200
	pid.SV=0;//用户设定目标温度:0度
	pid.T=1000;//500ms采样一次 PID计算周期--多久采样一次      1000
	pid.Td=20;//微分常数 20
	pid.Ti=1200;//积分常数 1200
	pid.OUT0=0;//默认初始值0	
	pid.Ek=0;  //本次偏差=用户设定值-传感器返回值
	pid.Eklast=0;//上一次偏差
	pid.Eklastlast=0;//上上一次偏差
	pid.SEK=0;//历史偏差
	pid.Calc_Time=0;//计算周期比较值

}
/*
函数功能:PID计算
参数:    无
返回值:  无
注:      增量式PID
输出的是增量(将增量加至PWM),公式如下:
delOUT=Kp*(Ek-Eklast)+Kp*T/Ti*Ek+Kp*Td/T*(Ek-2*Eklast+Eklastlast)
*/
void PID_Calc_Handler_Incremental(void)
{
	float delEk;//本次的偏差-上次偏差
	float Ki;//Kp*T/Ti
	float Kd;//Kp*Td/T
	float Iout;//积分输出
	float Pout;//比例输出
	float Dout;//微分输出
	if(pid.Calc_Time<pid.T)//计算周期未到
	{
		return ;
	}
	pid.Ek=pid.SV-pid.Pv;//当前偏差值 设定值-传感器返回值
	delEk=pid.Ek-pid.Eklast;//本次偏差	
	Ki=pid.Kp*pid.T/pid.Ti;//积分系数
	Kd=pid.Kp*pid.Td/pid.T;//微分系数
	Iout=Ki*pid.Ek;//积分输出
	Dout=Kd*(pid.Ek-2*pid.Eklast+pid.Eklastlast);//微分输出
	Pout=pid.Kp*delEk;//比例输出
	pid.OUT=Pout+Iout+Dout+pid.OUT0;//本次的计算结果,即输出的PWM脉宽
	//pid输出规避,设置的PWM周期为500 2khz 
	if(pid.OUT>999)
	{
		SET_Duty_Cycle_Fan(100);
		SET_Duty_Cycle_Heat(999);
	}
	else if(pid.OUT>0&&pid.OUT<999)
	{
		SET_Duty_Cycle_Fan(1000-pid.OUT);
		SET_Duty_Cycle_Heat(999);
	}
	else if((pid.OUT>=-999)&&(pid.OUT<0))
	{
		SET_Duty_Cycle_Fan(999);
		SET_Duty_Cycle_Heat(1000+pid.OUT);
	}
	else if(pid.OUT<-999)
	{
		SET_Duty_Cycle_Fan(999);
		SET_Duty_Cycle_Heat(100);
	}
	else
	{
		SET_Duty_Cycle_Fan(999);
		SET_Duty_Cycle_Heat(999);
	}
	//更新偏差
	pid.Eklastlast=pid.Eklast;
	pid.Eklast=pid.Ek;	
	pid.Calc_Time=0;	
}

PID.H文件

#ifndef __PID_H
#define __PID_H
#include "sys.h"
#include "delay.h"
#include "relay.h"
#define PIDMode 1//0:位置式pid 1:增量式pid
typedef struct
{
    float SV;//用户设定值
	float Pv;//当前传感器传回的值
	
	float Kp;//比例系数
	float T;//PID计算周期--多久采样一次
	float Ti;//积分常数
	float Td;//微分常数
	
	float Ek; //本次偏差
	float Eklast;//上一次偏差
	float Eklastlast;//上上一次偏差
	
	float SEK;//历史偏差之和
	float OUT0;//初值
	
	float OUT;//本次应该输出的值
	
	u16 Calc_Time;//经历的时间
}PID;
extern PID pid;
void Set_PID_Init(void);
#if (PIDMode)
void PID_Calc_Handler_Incremental(void);
#else
void PID_Calc_Handler_Positional(void);
#endif
#endif

猜你喜欢

转载自blog.csdn.net/liuxianfei0810/article/details/106325390
今日推荐