用整型变量来完成PID算法,由所以用整型数来做的,所以也不是很准确,可是关于许多的运用场合,这个精度也够了,关于系数和采样电压全部是扩大10倍处理的.所以精度不是很高. 可是也不是那么低,大部分的场合都够了. 真实觉得精度不行, 能够再扩大10倍或许100倍处理,可是要注意不超出整个数据类型的规模就能够了.本程序包含PID核算和输出两部分.当误差>10度全速加热,误差在10度以内为PID核算输出.
//================================================================
// pid.H
// Operation about PID algorithm procedure
// C51编译器 Keil 7.08
//================================================================
// 作者:zhoufeng
// Date :2007-08-06
// All rights reserved.
//================================================================
#include
#include
typedef
typedef
typedef
//
void
void
//================================================================
typedef struct PIDValue
{
uint32
uint8
uint8
uint8
uint8
uint16
uint16
uint16
}PIDValueStr;
PIDValueStr PID;
uint8
uint8
//================================================================
PID = Uk + KP*[E(k)-E(k-1)]+KI*E(k)+KD*[E(k)-2E(k-1)+E(k-2)];(增量型PID算式)
函数进口: RK(设定值),CK(实践值),KP,KI,KD
函数出口: U(K)
//PID运算函数
//================================================================
void
{
uint32
uint32
uint32
Temp[0] = 0;
Temp[1] = 0;
Temp[2] = 0;
PostSum = 0;
NegSum = 0;
if( PID.RK_Uint16 > PID.CK_Uint16 )
{
if( PID.RK_Uint16 – PID.CK_Uint16 >10 )
{
else
{
//================================================================
Temp[0]=PID.Ek_Uint32[0] – PID.Ek_Uint32[1];
{
Temp[0]=PID.Ek_Uint32[0] – PID.Ek_Uint32[1];
//================================================================
if( (PID.Ek_Uint32[0]+ PID.Ek_Uint32[2])>Temp[2] )
Temp[2]=(PID.Ek_Uint32[0]+ PID.Ek_Uint32[2])-Temp[2];
{
Temp[2]=Temp[2]-(PID.Ek_Uint32[0]+ PID.Ek_Uint32[2]); //E(k-2)+E(k)<2E(k-1)
//================================================================
//以下部分代码是讲一切的正数项叠加,负数项叠加
//KP*[E(k)-E(k-1)]
if(PID.EkFlag_Uint8[0]==0)
PostSum += Temp[0];
else
NegSum += Temp[0];
// KI*E(k)
if(PID.EkFlag_Uint8[1]==0)
PostSum += Temp[1];
else
//KD*[E(k-2)+E(k)-2E(k-1)]
if(PID.EkFlag_Uint8[2]==0)
PostSum += Temp[2];
else
NegSum += Temp[2];
//U(K)
PostSum += (uint32)PID.Uk_Uint16;
if(PostSum > NegSum )
{ Temp[0] = PostSum – NegSum;
if( Temp[0] < 100 )
PID.Uk_Uint16 = (uint16)Temp[0];
else
PID.Uk_Uint16 = 100;
}
else
}
}
else
{ PID.Uk_Uint16 = 0; }
}
//================================================================
函数进口: U(K)
函数出口: out(加热输出)
//PID运算植输出函数
//================================================================
void
{
static int i;
i=PID.Uk_Uint16;
if(i==0)
out=1;
else out=0;
if((count++)==5)//如守时中止为40MS,40MS*5=0.2S(输出时刻单位),加热周期20S(100等份)
{
count=0;
i–;
}
}