#include<intrins.h>
#include<math.h>
#include<string.h>
struct PID
{
unsigned int SetPoint ;
// 設定目標 Desired Value
unsigned int Proportion ;
// 比例常數(shù) Proportional Const
unsigned int Integral ;
// 積分常數(shù) Integral Const
unsigned int Derivative ;
// 微分常數(shù) Derivative Const
unsigned int LastError ;
// Error[-1]
unsigned int PrevError ;
// Error[-2]
unsigned int SumError ;
// Sums of Errors
}
;
struct PID spid ;
// PID Control Structure
unsigned int rout ;
// PID Response (Output)
unsigned int rin ;
// PID Feedback (Input)
unsigned int set_temper,temper,s ;
sbit output=P3^4;
unsigned char high_time,low_time,count=0 ;
//占空比調(diào)節(jié)參數(shù)
void PIDInit(struct PID*pp)
{
memset(pp,0,sizeof(struct PID)); //PID參數(shù)初始化全部設置為0
}
unsigned int PIDCalc(struct PID*pp,unsigned int NextPoint)
{
unsigned int dError,Error ;
Error=pp->SetPoint-NextPoint ;
// 偏差
pp->SumError+=Error ;
// 積分
dError=pp->LastError-pp->PrevError ;
// 當前微分
pp->PrevError=pp->LastError ;
pp->LastError=Error ;
//比例
//積分項
return(pp->Proportion*Error+pp->Integral*pp->SumError+pp->Derivative*dError);
// 微分項
}
/***********************************************************
溫度比較處理子程序
***********************************************************/
void compare_temper(unsigned int set_temper,unsigned int temper)
{
unsigned char i ;
//EA=0;
if(set_temper>temper)
{
if(set_temper-temper>10)
{
high_time=100 ; //大于1°不進行PID運算
low_time=0 ;
}
else
{ //在1°范圍內(nèi)進行PID運算
for(i=0;i<10;i++)
{
//get_temper();
rin=temper;
// Read Input
rout=PIDCalc(&spid,rin); //執(zhí)行PID運算
// Perform PID Interation
}
if(high_time<=100) //限制最大值
high_time=(unsigned char)(rout/800);
else
high_time=100;
low_time=(100-high_time);
}
}
/****************************************/
else if(set_temper<=temper) //當實際溫度大于設置溫度時
{
if(temper-set_temper>0)//如果實際溫度大于設定溫度
{
high_time=0 ;
low_time=100 ;
}
else
{
for(i=0;i<10;i++)
{
//get_temper();
rin=temper;
// Read Input
rout=PIDCalc(&spid,rin);
// Perform PID Interation
}
if(high_time<100) //此變量是無符號字符型
high_time=(unsigned char)(rout/10000);
else
high_time=0 ;//限制不輸出負值
low_time=(100-high_time);
//EA=1;
}
}
}
/*****************************************************
T1中斷服務子程序,用于控制電平的翻轉(zhuǎn) ,40us*100=4ms周期
******************************************************/
void serve_T1()interrupt 3 using 1
{
if(++count<=(high_time))
output=0 ;
else if(count<=100)
{
output=1 ;
}
else
count=0 ;
TH1=0x2f ;
TL1=0xe0 ;
}
void PIDBEGIN()
{
TH1=0x2f ;
TL1=0x40 ;
ET1=1 ;
TR1=1 ;
high_time=50 ;
low_time=50 ;
PIDInit(&spid);
// Initialize Structure
spid.Proportion=10 ;
// Set PID Coefficients
spid.Integral=8 ;
spid.Derivative=6 ;
spid.SetPoint=100 ;
// Set PID Setpoint
}
#endif
main
{
while(1){
PIDBEGIN();
if(hengwen==0)
{
compare_temper(temp4,temp5);
}
}
}
temp4是設定溫度和temp5時實際溫度,求高人指點,急急急
|