flagship567 发表于 2010-8-27 14:36:45

各位高手,本人这个程序调了一天了,他的占空比好像一直不变化!求助!!!用PID做的一个测温程

各位高手,本人这个程序调了一天了,他的占空比好像一直不变化!求助!!!
#ifndef pid
#define pid
uchar set;                     //温度初始值
uint rout;                     // PID Response (Output)
uchar high_time,low_time,count=0;         //占空比调节参数

struct PID {
unsigned int SetPoint; // 设定目标 Desired Value
unsigned int Proportion; // 比例常数 Proportional Const
unsigned int Integral; // 积分常数 Integral Const
unsigned int Derivative; // 微分常数 Derivative Const
unsigned int LastError; // Error[-1]
unsigned int PrevError; // Error[-2]
unsigned int SumError; // Sums of Errors
};                                              
struct PID spid;                // PID Control Structure

/****************pid初始化*********************/
void init_pid()
{
        high_time=50;
    spid.LastError = 20;
    spid.PrevError = 20;
    spid.SumError= 20;
        spid.Proportion = 20;       // Set PID Coefficients
        spid.Integral = 8;
        spid.Derivative =6;
        spid.SetPoint = set;      // Set PID Setpoint
}
/***************************PID算法**************************/
unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint )
{
        unsigned int dError=0,Error=0;
        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);
}
/********************PID控制占空比*************************/
//high_time表示高电平数
void duty_cycle(uint t)                               // 占空比
{
   /* uchar s;

        s=set;
        if(s>t)
        {
                if(s-t>2)   
                        high_time=100;                  
                else
                {       
                  rout = PIDCalc ( &spid,t );   // Perform PID Interation                                                        
                        if(high_time<=100)
                          high_time=(uchar)(rout/600);
                else
                      high_time=100;                               
          }
   }
       else
       {
                  high_time=0;
        }

*/
uchar i;
   if(set>t)
   {
   if(set-t>3)
      {
      high_time=100;
      low_time=0;
      
       }
   else
   {
       for(i=0;i<10;i++)
         {
         rout=PIDCalc(&spid,t);
         
          }
      if(high_time<=100)
          high_time=(uchar)(rout/800);
      else
         { high_time=100;
          low_time=(100-high_time);
         }
      }
   }
else if(set<=t)
{
    if(t-set>0)
    {
   high_time=0;
   low_time=100;
   }
    else
    {
       for(i=0;i<10;i++)
         {
         rout=PIDCalc(&spid,t);
         
          }
      if(high_time<=100)
          high_time=(uchar)(rout/10000);
      else
          high_time=100;
          low_time=(100-high_time);

      }
}

}       
#endif

void main ()
{
    uint t;
   
TMOD=0x01;       
TH0 =0x10;
TL0 =0x10;
EA= 1;
ET0 = 1;
TR0 = 1;   
set=70;
init_pid();
view();
while(1)
{

t=gettemp;
   duty_cycle(t);
}

}





/*void t0_int(void) interrupt 1                //PWM波输出
{
        if(++count<=(high_time))
   SWH=0;
   else if(count<=100)
   SWH=1;
   else
      count=0;
   TH0=0x10;//定时器初始化
   TL0=0x10;
} */
void t0() interrupt 1
{
TF0=0;
TR0=0;
if(++count<=(high_time))
SWH=0;
else if((high_time)<count<=100)
{
SWH=1;
}
else
//SWH=0;
count=0;
TH0=0x10;
TL0=0x10;
TR0=1;
}

okyinglong 发表于 2012-4-19 12:46:30

请问你调试成功了吗 可以说说是什么问题吗?

mayiqing888 发表于 2012-4-19 16:44:42

楼主可以试试增量式PID,我感觉效果还不错,目前还在调呢

okyinglong 发表于 2012-4-19 23:03:10

本帖最后由 okyinglong 于 2012-4-19 23:08 编辑

请教楼上的 我的是采用增量式 PID我用89c51单片 如何将PID值利用一个定时器来控制IO口状态 (也就是温度控制中,用PID算法得到的是一个数值,这个数值如何转换为占空比?)我的思路是下面的 但是我知道不行

void compare_temper()                 //PID温度控制输出函数
{   
   unsigned char i;      
   if(set_temper>temper)   
    {   
          if(set_temper-temper>50)//如果控制目标温度温与实时温度差大于5度,(放大10倍)是50   
            {         
                   pwms = 256;          //PWM 输出高电平占空比最大。即全速加温                
            }        
          else   
             {   
                  for(i=0;i<10;i++) //5度范围内PID增量控制,10次周期 即PID积分式中T=10   
                         {      
                        rin=ReadTemperature();//PID输入实时温度采样值      
                        rout = PIDCalc ( &spid,rin ); // PID增量输出   
                        }        //PID增量输出范围(0-255)配合pwm取值范围                 
                  if(rout>=240)rout=240;        //保障PWM输入值10-240 防止pwm出现失调。stc单片机特性。        
                  if(rout<=20)rout=20;                  
                     pwms=255-rout;             
            }   
      }   
       else if(set_temper<=temper) //目标温度小于实时温度pwm输出低电平最高占空比,关闭加热。
      {                                                                                           
         pwms = 250;   
       }
}


/***************************************************************
*                        占空比处理函数 *                       
***************************************************************/
void init_t0()
{        
TMOD=0X02;                //定时器0,工作模式2(0000,0010),8位定时模式       
TH0=0x06;   //写入预置初值6到定时器0,使250微秒溢出一次(12MHz)       
TL0=0x06;   //写入预置值       
TR0=1;    //启动定时器       
ET0=1;    //允许定时器0中断       
EA=1;   //允许总中断
}
void timer0() interrupt 1    //定时器0中断服务程序
{                  
staticunsigned int   tt ;   //tt用来保存当前时间在一秒中的比例位置             
tt++;    //每250微秒增加1   
if(tt>=240)        
tt = 0;        
if(tt<=pwms)   //2.5毫秒的时钟周期                  
{                        
tt=0;//使tt=0,开始新的PWM周期                                      
P2_0=1;                   
}       
else                
{                        
//if(scale==tt)//按照当前占空比切换输出为高电平                       
P2_0=0;                        
}   
}
页: [1]
查看完整版本: 各位高手,本人这个程序调了一天了,他的占空比好像一直不变化!求助!!!用PID做的一个测温程