搜索
bottom↓
回复: 17

分享一个基于STM32定时器的PID温度控制程序

  [复制链接]

出0入0汤圆

发表于 2014-1-8 11:13:53 | 显示全部楼层 |阅读模式
感谢大家对先前硬件的改进帮助,http://www.amobbs.com/thread-5564443-1-1.html
收益匪浅,最终方案还是将软件PID部分进行了修改,使用定时器开启8S周期的PWM波,最低每2S一个开关
周期。

该方案可满足±1.5度的精度要求。如果将PID参数进一步调整,应该效果会更好。

  PID_Parameters.P_gain_Cold= (float)(1.0f);
  PID_Parameters.I_gain_Cold= (float)(0.1f);
  PID_Parameters.D_gain_Cold= (float)(0.1f);
  PID_Parameters.Deadband_Cold= 0.2f;
  PID_Parameters.Integral_Cold= 5.0f;

void Temperature_Pwm_Configuration(void)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCInitStructure;

        GPIO_InitTypeDef GPIO_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
        
   
        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8|GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        
        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6|GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);

        /* -----------------------------------------------------------------------
          TIM4 Configuration: generate 4 PWM signals with 4 different duty cycles:
          TIM4CLK = 72 MHz, Prescaler = 35999, TIM3 counter clock = 2 KHz
          TIM4 ARR Register = 15999 => TIM4 Frequency = TIM4 counter clock/(ARR + 1)
          TIM4 Frequency = 0.125Hz.
          4000为基本单位保证开关频率大于2秒
         
        ----------------------------------------------------------------------- */
        
        /* Time base configuration */
        TIM_TimeBaseStructure.TIM_Period = Tim4_Arr;
        TIM_TimeBaseStructure.TIM_Prescaler = 35999;
        TIM_TimeBaseStructure.TIM_ClockDivision = 0;
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
        
        /* PWM4 Mode configuration: Channel1
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_Pulse = Tim4_Arr;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        TIM_OC1Init(TIM4, &TIM_OCInitStructure);
        TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);*/
        
        /* PWM4 Mode configuration: Channel2
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_Pulse = Tim4_Arr;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        TIM_OC2Init(TIM4, &TIM_OCInitStructure);
        TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);*/
        
        /* PWM4 Mode configuration: Channel3 */
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_Pulse = Tim4_Arr;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        TIM_OC3Init(TIM4, &TIM_OCInitStructure);
        TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
        
        /* PWM4 Mode configuration: Channel4 */
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_Pulse = Tim4_Arr;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        TIM_OC4Init(TIM4, &TIM_OCInitStructure);
        TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
        
        TIM_ARRPreloadConfig(TIM4, ENABLE);

        
    TIM_ClearFlag(TIM4, TIM_FLAG_Update);
    TIM_ITConfig(TIM4,TIM_IT_Update, ENABLE);
        
        /* TIM4 enable counter */
        TIM_Cmd(TIM4, ENABLE);
        TIM_CtrlPWMOutputs(TIM4,ENABLE);

        Fans_Stop;
}


float PID_Cold(void)
{
        static float err=0,ferror=0;
        static float Temprature_Setting_Old=0.0f,Temprature_Setting=0.0f;
    static u8 Setting_Refresh_Flag=0;
        
        Temprature_Setting = PID_Parameters.Control_Temprature_Set;
        if(Temprature_Setting_Old!=Temprature_Setting)
                {
                  Temprature_Setting_Old = Temprature_Setting;
                  Setting_Refresh_Flag =1 ;
            }
        //计算偏差
        err=(PID_Parameters.Control_Temprature_Set)-(PID_Parameters.Control_Temprature_Measure);
                        
        if(abs(err)>PID_Parameters.Deadband_Heat)
          {
                        ferror=(float)err; //数据类型转换
                        //计算比例项
                        PID_Parameters.proportion_Cold = PID_Parameters.P_gain_Cold* ferror;
                        //计算积分项
                        if(PID_Parameters.proportion_Cold<-5.0f || PID_Parameters.proportion_Cold>5.0f)
                                {
                                        PID_Parameters.Integral_Cold= 5.0f;
                            }
                        else
                                {
                                        if(Setting_Refresh_Flag)
                                                {
                                                 Setting_Refresh_Flag = 0 ;
                                                 PID_Parameters.Integral_Cold = 5.0f;
                                            }
                                        else
                                                {
                                                 PID_Parameters.Integral_Cold += PID_Parameters.I_gain_Cold* ferror;
                                            }
                                       
                                        if(PID_Parameters.Integral_Cold>5.0f)
                                          {
                                                PID_Parameters.Integral_Cold= 5.0f;
                                                Hot_Cold_Flag = 0 ;
                                          }
                                        else if(PID_Parameters.Integral_Cold<0.0f)
                                          {
                                                PID_Parameters.Integral_Cold=0.0f;
                                          }
                                }
                        //输出结果
                        PID_Parameters.Result_Cold = PID_Parameters.proportion_Cold + PID_Parameters.Integral_Cold;
          }
        else
          {
                         PID_Parameters.Result_Cold = PID_Parameters.Integral_Cold;
          }

               
                if(PID_Parameters.Result_Cold>5.0f)
                  {
                        PID_Parameters.Result_Cold= 5.0f;
                        Hot_Cold_Flag = 0 ;
                  }
                else if(PID_Parameters.Result_Cold<0.0)
                  {
                        PID_Parameters.Result_Cold=0.0;
                  }

                if(PID_Parameters.Result_Cold <=1.0f)
                        PID_Parameters.Result_Cold_PWM= 0.0f;
                else if(PID_Parameters.Result_Cold <=2.0f)
                        PID_Parameters.Result_Cold_PWM = 4000.0f;
                else if(PID_Parameters.Result_Cold <=3.0f)
                        PID_Parameters.Result_Cold_PWM = 8000.0f;
                else if(PID_Parameters.Result_Cold <=4.0f)
                        PID_Parameters.Result_Cold_PWM = 12000.0f;
                else
                        PID_Parameters.Result_Cold_PWM = 15999.0f;

           return  PID_Parameters.Result_Cold_PWM;

}

出0入0汤圆

发表于 2014-1-8 11:26:53 | 显示全部楼层
在学习PID的知识,谢谢分享

出0入0汤圆

发表于 2014-1-8 12:13:15 | 显示全部楼层
顶一下,路过

出0入0汤圆

发表于 2014-1-8 12:39:25 来自手机 | 显示全部楼层
手机标记,谢谢分享。

出0入0汤圆

发表于 2014-1-8 19:54:42 | 显示全部楼层
谢谢分享!!!

出0入0汤圆

发表于 2014-1-10 12:00:36 | 显示全部楼层
mark, study

出0入0汤圆

发表于 2014-5-15 17:24:31 | 显示全部楼层
十分感谢

出0入0汤圆

发表于 2014-5-18 21:23:54 | 显示全部楼层
标记一下

出0入0汤圆

发表于 2015-5-20 19:21:55 | 显示全部楼层
手机标记,谢谢分享。     

出0入0汤圆

发表于 2015-7-1 12:02:00 | 显示全部楼层
帮定了哈

出0入0汤圆

发表于 2015-12-10 15:42:02 | 显示全部楼层
谢谢分享哈,收藏啦

出0入0汤圆

发表于 2017-6-25 07:50:32 | 显示全部楼层
学习中.....谢谢

出0入0汤圆

发表于 2017-6-25 21:40:36 | 显示全部楼层
收藏啦,谢谢分享哈

出0入0汤圆

发表于 2017-10-18 08:21:43 | 显示全部楼层
mark 温度控制 pid

出0入4汤圆

发表于 2017-10-19 11:31:19 | 显示全部楼层
正在学习PID的,好好看看

出0入0汤圆

发表于 2017-10-19 15:54:26 | 显示全部楼层
谢谢楼主分享!

出0入0汤圆

发表于 2019-7-26 22:18:01 | 显示全部楼层
正在学习PID控制温度,感谢分享。

出0入0汤圆

发表于 2020-1-6 11:46:35 | 显示全部楼层
非常感谢楼主的分享,PID温度控制,多多学习!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-20 14:39

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表