STM32_PID通用算法增量式和位置式

STM32_PID通用算法增量式和位置式

前言:
此算法为入门级PID算法,调试好参数后可应用于温度控制、舵机控制、直流电机的转速控制和直流电机的角度控制等等,下面就以温度控制举例

pid.c

#include "pid.h"
#include "sensor.h"
#include "dev_control.h"
#include "usbd_cdc_if.h"

pidTypeDef_t  heatTemp_pid = {0};
pidPID_t tempPID = {0};

void pidInit(void)
{
	tempPID.KP = 15;						//比例常数
	tempPID.KI = 0;							//积分常数
	tempPID.KD = 0.1;						//微分常数
	heatTemp_pid.PidMode = 0;				//使用增量式PID
	heatTemp_pid.SetPoint = 0;       		//设定目标值
	heatTemp_pid.ActualValue = 0.0;  		//期望值输出
	heatTemp_pid.SumError = 0.0;     		//积分值
	heatTemp_pid.Error = 0.0;        		//当前偏差值
	heatTemp_pid.LastError = 0.0;    		//上次偏差值
	heatTemp_pid.PrevError = 0.0;    		//上上次偏差值
	heatTemp_pid.Proportion = tempPID.KP;  	//比例常数
	heatTemp_pid.Integral = tempPID.KI;    	//积分常数
	heatTemp_pid.Derivative = tempPID.KD;  	//微分常数
}

void pidTask(void)//根据系统来计算调用该函数的周期
{
	if(devTypedef.devHeatAir.devHeatAirEnable == STATE_ENABLE)
	{
		heatTemp_pid.SetPoint = (float)sensorData.ptcSensorData.ptcSensorData_target;
		heatTemp_pid.ActualValue = pidComputeCtrl(&heatTemp_pid, (float)sensorData.ptcSensorData.ptcSensorData_float);//¼ÆËã³öPIDÊä³öÖµ

		if(heatTemp_pid.ActualValue < 0) heatTemp_pid.ActualValue = 0;
		if(heatTemp_pid.ActualValue > 100) heatTemp_pid.ActualValue = 100;

		devTypedef.devHeatAir.devHeatAirDuty = heatTemp_pid.ActualValue;//作用到控制设备上
		
		//调试信息
		usb_printf("%0.2f,%0.2f,%0.2f\r\n",heatTemp_pid.SetPoint,(float)sensorData.ptcSensorData.ptcSensorData_float,heatTemp_pid.ActualValue);
	}
}

float pidComputeCtrl(pidTypeDef_t *PID, float feedbackValue)
{
	PID->Error = (float)(PID->SetPoint - feedbackValue);               												//计算偏差

	if(PID->PidMode == 1)                                            												//增量式PID
	{
		PID->ActualValue += (PID->Proportion * (PID->Error - PID->LastError))                      					//比例环节
										 + (PID->Integral * PID->Error)                                             //积分环节
										 + (PID->Derivative * (PID->Error - 2 * PID->LastError + PID->PrevError)); 	//微分环节

		PID->PrevError = PID->LastError;                                   											//更新历史偏差
		PID->LastError = PID->Error;
	}
	else                                                               												//位置式PID
	{
		PID->SumError += PID->Error;
		float pid_integral = 0;
		pid_integral = PID->Integral * PID->SumError;																//限积分算法
		if(pid_integral > 5) pid_integral = 5;
		
		PID->ActualValue = (PID->Proportion * PID->Error)                   										//比例环节
									 + pid_integral                    												//积分环节
									 + (PID->Derivative * (PID->Error - PID->LastError));							//微分环节
		PID->LastError = PID->Error;
	}
	return (PID->ActualValue);                               														//返回计算后的结果
}

pid.h

#ifndef __PID_H
#define __PID_H
#include "main.h"
#include "log.h"

#define PID_TASK_PERIOD 1 //

#define PID_LOG_EN 1
#if PID_LOG_EN
	#define PID_printf(format, ...) 		printf(RTT_CTRL_TEXT_WHITE format , ##__VA_ARGS__)//"\r\n"
	#define PID_info(format, ...)   		printf(RTT_CTRL_TEXT_GREEN"[pid]info:" format , ##__VA_ARGS__)
	#define PID_debug(format, ...)  		printf(RTT_CTRL_TEXT_WHITE"[pid]debug:" format , ##__VA_ARGS__)
	#define PID_warning(format, ...)  	printf(RTT_CTRL_TEXT_YELLOW"[pid]warning:" format , ##__VA_ARGS__)
	#define PID_error(format, ...)  		printf(RTT_CTRL_TEXT_RED"[pid]error:" format ,##__VA_ARGS__)
#else
	#define PID_printf(format, ...)
	#define PID_info(format, ...)
	#define PID_debug(format, ...)
	#define PID_warning(format, ...)
	#define PID_error(format, ...)
#endif


typedef struct
{
	float KP;
	float KI;
	float KD;
}	pidPID_t;

extern pidPID_t pressurePID;
extern pidPID_t tempPID;

//PID参数结构体
typedef struct
{
	float  SetPoint;            //设定目标值
	float  ActualValue;         //期望值输出
	float  SumError;            //积分值
	float  Proportion;          //比例常数
	float  Integral;            //积分常数
	float  Derivative;          //微分常数
	float  Error;               //当前偏差值
	float  LastError;           //上次偏差值
	float  PrevError;           //上上次偏差值
	unsigned int PidMode;		//使用PID模式
} pidTypeDef_t;

extern pidTypeDef_t  heatTemp_pid;     				//加热系统PID参数结构体

extern unsigned char pid_flag;


void pidInit(void);
void pidTask(void);	
float pidComputeCtrl(pidTypeDef_t *PID, float feedbackValue);

#endif


你可能感兴趣的:(STM32开发经验,算法,stm32,java)