📄 pidcalc._c
字号:
/*****************************************************************
* 文件名: PID.c
* 版本号:
* 创作日期: 2005.7.12
* 作者: Wangzq
* 功能说明: PID增量式算法
* 其它说明:
*****************************************************************/
/*****************************************************************
* 修改日期:
* 修改人:
* 修改原因:
*******************************************************************/
#include "PIDCALC.h"
//****************************************************************
//增量式PID算法
//
//***************************************************************
void PIDInit (struct PID *pp )
{
memset( pp, 0, sizeof(struct PID ) );
}
byte PIDCalc(struct PID *pp, word Fact_Value )
{
byte K; // PID实际输出值
sword perror,derror;
sdword result,pidtemp;
if (pp->SetValue < 300 ) //低速的PID值
{
pp->P = KPL; //低速的p值
pp->I = KIL;
pp->D = KDL;
}
else
{
if (pp->SetValue > 2500) //高速的PID值
{
pp->P = KPH; //告诉的p值
pp->I = KIH;
pp->D = KDH;
}
else //中速的PID值,p,i,d按一定的斜率计算
{
//*********************计算PID插值常数***************************
perror = (2500-pp->SetValue); //计算PID插值常数
pidtemp = (KPL-KPH);
pidtemp *= perror
pidtemp /= PIM;
pidtemp += KPH;
pp->P = pidtemp;
pidtemp = (KIL-KIH);
pidtemp *= perror;
pidtemp /= PIM;
pidtemp += KIH;
pp->I = pidtemp;
// pidtemp = (KDL-KDH);
// pidtemp *= perror;
// pidtemp /= PIM;
// pidtemp += KDH;
// pp->D = pidtemp;
//*********************计算PID插值常数***************************
}
}
//result = 0;// 清零
if (Fact_Value > 7000) //转速上限值设定
{
Fact_Value = 7000;
}
pp->Error = pp->SetValue - Fact_Value; // 取当前偏差
perror = pp->Error - pp->LastError; //计算比例偏差
//*****************************************************************
// derror = pp->LastError; //计算微分偏差
// derror += pp->LastError;
// derror = pp->Error - derror;
// derror += pp->PrevError;
//****************************************************************
pp->PrevError = pp->LastError; // 当前误差Error[-1]赋给上次误差Error[-2]
pp->LastError = pp->Error; // 取当前误差
pidtemp = perror;
pidtemp *= (pp->P);
result = pidtemp; // 比例项
pidtemp = pp->Error;
pidtemp *= (pp->I);
result += pidtemp; // 积分项
// pidtemp = derror;
// pidtemp *= (pp->D);
// result += pidtemp; // 微分项
SumDu += result;
if (SumDu <= 0)
{
K = 0;
}
else
{
result = SumDu;
result /= 3000;
if (result > 1000)
result = 1000;
result *= 0xff;
result /=1000;
K = result;
K = PIDBound(K, Fact_Value); //计算控制值上限
}
return K;
}
byte PIDBound(byte K, word Fact_Value)
{
//if (K >0x7f )
//{
// K = 0x7f;
//}
return K;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -