#include "pid.h"
#define Kp 3.0
#define Ki 0.3
#define Kd 200.0
#define Ts 20 //采样周期为2S,采样频率为100ms一次
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
uchar sampl_cnt = 0; //采样数变量,100ms加一次
bit flag_100ms = 0;
typedef struct _PID_
{
uint SetPoint; //设定目标Desired Value
long SumError; //误差累计
uint Proportion; //比例常数Proportional Const
uint Integral; //积分常数Integral Const
uint Derivative; //微分常数Derivative Const
int LastError; //Error[-1]
//int PrevError; //Error[-2]
}PID_TYPE;
static PID_TYPE ContlHeatPID;
static PID_TYPE *pPID = &ContlHeatPID;
/******************************
函数名称:
函数功能:
函数参数:
函数返回值:
******************************/
void PIDInit(void)
{
pPID->SetPoint = 0;
pPID->Proportion = Kp;
pPID->Integral = Ki;
pPID->Derivative = Kd;
pPID->LastError = 0;
pPID->SumError = 0;
}
/******************************
函数名称:
函数功能:积分项每100ms累加一次误差值,20次后清零,但是PID也每100ms更新一次
函数参数:
函数返回值:
******************************/
void CalPID1(int nexPoint)
{
int iError,dError;
uint pOut;
iError = pPID->SetPoint - nexPoint;
if(flag_100ms)
{
flag_100ms = 0;
if(sampl_cnt < 20)
{
sampl_cnt++;
pPID->SumError += iError;
}
if(sampl_cnt == 20)
{
pPID->SumError = 0;
pPID->SumError += iError;
}
}
dError= iError - pPID->LastError;
pPID->LastError = iError;
pOut = pPID->Proportion*iError + pPID->Integral*pPID->Integral
+ pPID->Derivative*dError;
}
/******************************
函数名称:
函数功能: 每经过20采样数,也就是每间隔2S输出一个调节PID数据
函数参数:
函数返回值:
******************************/
void CalPID2(int nexPoint)
{
int iError,dError;
uint pOut;
iError = pPID->SetPoint - nexPoint;
if(flag_100ms)
{
flag_100ms = 0;
sampl_cnt++;
if(sampl_cnt < 20) //如果采样数据小于20个,积累积分项
{
pPID->SumError += iError;
dError= iError - pPID->LastError;
pPID->LastError = iError;
}
else if(sampl_cnt == 20)//如果采样数据为20个,输出PID调节数据,清0 SunError为下次准备
{
sampl_cnt = 0;
pPID->SumError += iError;
dError= iError - pPID->LastError;
pPID->LastError = iError;
pOut = pPID->Proportion*iError + pPID->Integral*pPID->Integral
+ pPID->Derivative*dError;
pPID->SumError = 0;
}
}
}
|