打印

请教单片机PWM控制加热器用增量式PID,三个参数的选择

[复制链接]
4454|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
discussant|  楼主 | 2013-12-5 13:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 discussant 于 2013-12-5 13:44 编辑

我用PWM信号控制加热器,采用增量式PWM控制方法。增量式的公式是δu(k)=A*E(K)-B*E(K-1)+C*E(K-2),请问这三个参数如何选择?我的机器是用传感器测量水温的,通常测量到的水温要滞后一些,因为传感器离加热器有一定距离。现在想用单片机输出PWM来让水温稳定在设定温度。

相关帖子

沙发
金融小数| | 2013-12-5 14:48 | 只看该作者
好像有个建议选值方法的,网上有

使用特权

评论回复
板凳
gx_huang| | 2013-12-5 16:13 | 只看该作者
LZ上面的公式是懒汉公式,最好把PID的3个分开,可以独立调整PID参数,更灵活。

使用特权

评论回复
地板
discussant|  楼主 | 2013-12-5 18:37 | 只看该作者
谢谢各位,有没有不计算,用增减PWM来做的PI控制的简单的程序?

使用特权

评论回复
5
gx_huang| | 2013-12-6 15:16 | 只看该作者
不计算,叫算法吗?
不编程,叫程序吗?
其实,你只要肯付出,一切都会有的,要么付出精力,要么付出金钱。

使用特权

评论回复
6
hopewise| | 2013-12-6 17:54 | 只看该作者
/************************************************
                                PID温度控制做动函数
*************************************************/
void   compare_temper()
{          
           if(f_start==1)                                                                                  //按下启动键,则还要判断
           {

                  if(set_temp>r_temperature)
              {
                                if(set_temp-r_temperature>5)                //如果控制目标温度温与实时温度差大于5度
                    {
                               PWM0_set(255);                       //PWM 输出低电平占空比最大。即全速加温
                                }
                                else  
                                {
                                       rin=r_temperature;                   //PID输入实时温度采样值
                           rout = PIDCalc ( &spid,rin );        // PID增量输出
                                               if(rout>=240)rout=240;                    //保障PWM输入值10-240 防止pwm出现失调。stc单片机特性。
                               if(rout<=20)rout=20;
                               PWM0_set(255-rout);
                                }
             }
                 else if(set_temp<=r_temperature)    PWM0_set(0);  //目标温度<=实时温度,pwm输出高电平占空比最小,关闭加热
                                                     
           }
           else if(f_start==0)  PWM0_set(0);                                       //没按下启动键,则关闭加热

}

使用特权

评论回复
7
hopewise| | 2013-12-6 17:54 | 只看该作者

/************************************************
                                PID函数初始化
*************************************************/
void PIDBEGIN()
{
      PIDInit(&spid);                              // Initialize Structure
      spid.Proportion = 10;                        // Set PID Coefficients
      spid.Integral = 5;
      spid.Derivative =4;
}

使用特权

评论回复
8
hopewise| | 2013-12-6 17:55 | 只看该作者

/************************************************
              PID初始化
*************************************************/
void PIDInit (struct PID *pp)
{
      memset ( pp,0,sizeof(struct PID));
}


/************************************************
              增量控制PID函数体
51单片机最不擅长浮点数计算,转换成int型计算
//增量法计算公式:Pdt=Kp*[E(t)-E(t-1)]+Ki*E(t)+Kd*[E(t)-2*E(t-1)+E(t-2)]
*************************************************/
uint PIDCalc( struct PID *pp, double r_temperature )
{
       uint dError,Error,pError;
       Error = (set_temp - r_temperature);             //偏差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);         
                                       //比例                                //积分项                                 // 微分项
}

//************PWM初始化******************
//***************************************
void PWM_init (void)
{         
          CMOD=0x02;      //设置PCA定时器
          CL=0x00;
          CH=0x00;
          CCAPM0=0x42;    //PWM0设置PCA工作方式为PWM方式(0100 0010)
          CCAP0L=0x00;    //设置PWM0初始值与CCAP0H相同,PWM0初始时为0(注:CL≥CCAPnL时,PWMn接口输出高电平,反之,输出低电平)
             CCAP0H=0x00;    // PWM0初始时为0

          CCAPM1=0x42;    //PWM1设置PCA工作方式为PWM方式(使用时删除//)
          CCAP1L=0x00;    //设置PWM1初始值与CCAP0H相同
          CCAP1H=0x00;    // PWM1初始时为0

          CR=1;           //启动PCA定时器          
}


/*********************************************************************************************
函数名:PWM0占空比设置函数
调  用:PWM0_set();
参  数:0x00~0xFF(亦可用0~255)
返回值:无
结  果:设置PWM模式占空比,为0时全部高电平,为1时全部低电平
备  注:如果需要PWM1的设置函数,只要把CCAP0L和CCAP0H中的0改为1即可
/**********************************************************************************************/
void PWM0_set (uchar a)
{
           CCAP0L= a;    //设置值直接写入CCAP0L
              CCAP0H= a;    //设置值直接写入CCAP0H
}

使用特权

评论回复
9
hopewise| | 2013-12-6 17:59 | 只看该作者
网上找的,我把它做了修改(用NTC等),精度+-1度,我是用12VDC/2A发热提来测试

使用特权

评论回复
10
hopewise| | 2013-12-6 18:00 | 只看该作者
/************************************************
PID函数
*************************************************/
/*************PID**********************************/
struct PID
{
      double Proportion;    // 比例常数 Proportional Const
      double Integral;      // 积分常数 Integral Const
      double Derivative;    // 微分常数 Derivative Const
      double LastError;     // Error[-1]
      double PrevError;     // Error[-2]
};

xdata struct PID spid;    // PID Control Structure

uint rout;                // PID Response (Output)
uint rin;                 // PID Feedback (Input)

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

68

主题

249

帖子

1

粉丝