|
做了一个数控电源,用PID来控制,PID程序如下:
/************************************************
PIDº¯Êý
*************************************************/
void PIDInit (struct PID *pp)
{
memset ( pp,0,sizeof(struct PID));
}
/************************************************
ÔöÁ¿¿ØÖÆPIDº¯ÊýÌå
51µ¥Æ¬»ú×î²»É󤸡µãÊý¼ÆË㣬ת»»³ÉintÐͼÆËã PVsetΪÉ趨ֵ,NextPointΪÏÖÔÚÖµ
*************************************************/
unsigned int PIDCalc( struct PID *pp,unsigned int PVset,unsigned int NextPoint )
{
unsigned 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 = PVset - NextPoint; // Æ«²î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->Proportion * pError //±ÈÀý
+ pp->Integral *Error //»ý·ÖÏî
+ pp->Derivative * dError // ΢·ÖÏî
);
}
/************************************************
PIDº¯Êý³õʼ»¯
*************************************************/
void PIDBEGIN()
{
PIDInit(&spid); // Initialize Structure
spid.Proportion = 10; // Set PID Coefficients
spid.Integral = 5;
spid.Derivative =4;
}
/***********************************************************
PIDµçѹ¿ØÖÆ×ö¶¯º¯Êý
***********************************************************/
void compare_voltage(uint Vset) //PIDµçѹ¿ØÖÆÊä³öº¯Êý
{
unsigned char i;
uint x;
if(Vset>Vout)
{
if((Vset-Vout)>50) //Èç¹û¿ØÖÆÄ¿±êµçѹÓëʵʱµçѹ²î´óÓÚ50mv
{
dacshu=dacshu+5;
if(dacshu>=2000){dacshu=2000;}
DAC0out(dacshu);
delay(5000);
}
else
{
for(i=0;i<10;i++) //50mV·¶Î§ÄÚPIDÔöÁ¿¿ØÖÆ£¬10´ÎÖÜÆÚ ¼´PID»ý·ÖʽÖÐT=10
{
measurement2 = ad_start(3);
Vout = (measurement2*6097)/10000;
rin=Vout; //PIDÊäÈëʵʱµçѹ²ÉÑùÖµ
rout = PIDCalc ( &spid,Vset,rin ); // PIDÔöÁ¿Êä³ö
if(rout>2000){rout=0;}
} //PIDÔöÁ¿Êä³ö·¶Î§£¨0-2000£©ÅäºÏDACÈ¡Öµ·¶Î§
// mVshuADC(); //¶ÁÈ¡µçѹ¡¢µçÁ÷,ÅжÏÉ趨ÊÇ·ñµÈÓÚÊä³ö
if(Vset==Vout){rout=0;}
dacshu=dacshu+rout;
if(dacshu>2000){dacshu=2000;}
DAC0out(dacshu);
x=rout;
}
}
else if(Vset<Vout) //Ä¿±êµçѹСÓÚʵʱÊä³öµçѹ
{
if((Vout-Vset)>50) //Èç¹û¿ØÖÆʵʱµçѹÓëÄ¿±êµçѹ²î´óÓÚ50mv
{
if(dacshu<=5){dacshu=5;}
dacshu=dacshu-5;
DAC0out(dacshu);
delay(5000);
}
else
{
for(i=0;i<10;i++) //50mV·¶Î§ÄÚPIDÔöÁ¿¿ØÖÆ£¬10´ÎÖÜÆÚ ¼´PID»ý·ÖʽÖÐT=10
{
measurement2 = ad_start(3);
Vout = (measurement2*6097)/10000;
rin=Vout; //PIDÊäÈëʵʱµçѹ²ÉÑùÖµ
rout = PIDCalc ( &spid,Vset,rin ); // PIDÔöÁ¿Êä³ö
if(rout<63535){rout=65535;} //PIDÒç³öÏÞÖÆ
} //PIDÔöÁ¿Êä³ö·¶Î§£¨0-2000£©ÅäºÏDACÈ¡Öµ·¶Î§
if(Vset==Vout){rout=65535;}
dacshu=dacshu-(65535-rout);
if(dacshu>63535){dacshu=0;}
DAC0out(dacshu);
x=65535-rout;
}
}
ax1=x/1000;
ax2=(x-ax1*1000)/100;
ax3=(x-ax1*1000-ax2*100)/10;
ax4=(x-ax1*1000-ax2*100-ax3*10);
}
/***********************************************************
现在的问题是每次设定=输出时,PID的输出值(rout)不是零,而是1024,或是2048 ,或是512不知道是什么原因? |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|