.c文件
#include "pid.h" extern int now_temperature; extern int set_temperature; /************************************************ 增量式PID公式1 51单片机最不擅长浮点数计算,转换成int型放大十倍计算 *************************************************/ int PIDCalc(struct PID *pp) { int dError,Error,pError; //增量法计算公式: //Pdt=Kp*[E(t)-E(t-1)]+Ki*E(t)+Kd*[E(t)-2*E(t-1)+E(t-2)] Error = set_temperature - now_temperature; // 偏差E(t) pError = Error - pp->lasterror; //E(t)-E(t-1) dError = Error - 2*pp->lasterror + pp->preverror; //E(t)-2*E(t-1)+E(t-2) pp->preverror = pp->lasterror; pp->lasterror = Error; return ( pp->kp * pError //比例 + pp->ki *Error //积分项 + pp->kd * dError // 微分项 ); } /********************************************** 位置式PID **********************************************/ /* int PIDCalc(struct PID *pp) { int derror,error; error = set_temperature - now_temperature; // 偏差E(t) pp->sumerrror += error; derror = pp->lasterror - pp->preverror; pp->preverror = pp->lasterror; pp->lasterror = error; return (pp->kp * error + pp->ki * pp->sumerrror +pp->kd * derror); } */ /* //位置式PID控制设计 unsigned int LocPIDCalc(int NextPoint) { register int iError,dError; iError = sptr->SetPoint - NextPoint; //偏差 sptr->SumError += iError; //积分 dError = iError - sptr->LastError; //微分 sptr->LastError = iError; return(sptr->Proportion * iError //比例项 + sptr->Integral * sptr->SumError //积分项 + sptr->Derivative * dError); //微分项 } */ /************************************************ 增量式PID公式2 *************************************************/ /* int IncPIDCalc(int NextPoint) { register int iError, iIncpid; //当前误差 iError = sptr->SetPoint - NextPoint; //增量计算 iIncpid = sptr->Proportion * iError //E[k]项 - sptr->Integral * sptr->LastError //E[k-1]项 + sptr->Derivative * sptr->PrevError; //E[k-2]项 //存储误差,用于下次计算 sptr->PrevError = sptr->LastError; sptr->LastError = iError; //返回增量值 return(iIncpid); } */ void init_pid(PID *pid) { pid->kp = 0; pid->ki = 0; pid->kd = 0; pid->lasterror = 0; pid->preverror = 0; pid->sumerrror = 0; } void set_pid(PID *pid) { init_pid(pid); pid->kp = 1; pid->ki = 0; pid->kd = 0; }
.H文件
#ifndef __PID_H #define __PID_H #define KEY_A 16 typedef struct PID { /*double*/ int kp; /*比例系数*/ /*double*/ int ki; /*积分系数*/ /*double*/ int kd; /*微分系数*/ /*double*/ int lasterror; /*上一次误差*/ /*double*/ int preverror; /*上上次误差*/ /*double*/ int sumerrror ; /*误差积累*/ } PID; //double PID_calc(struct PID *pid,double nowpoint); //unsigned int LocPIDCalc(int NextPoint) ; //unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint ) ; //int IncPIDCalc(int NextPoint) ; void init_pid(PID *pid); void set_pid(PID *pid) ; int PIDCalc(PID *pp); #endif