0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于CW32的PID温度控制案例分享

CW32生态社区 来源:CW32生态社区 2023-08-14 18:21 次阅读

1.PID温控系统是一种常用的控制系统,用于实现对温度变量的精确控制。PID算法根据当前的温度误差以及误差的变化率,计算一个控制信号,用于调节加热器的输出。以下是PID算法的三个主要组成部分:

①比例(Proportional)控制:比例控制是根据当前的温度误差来计算控制信号。具体而言,通过将设定温度与实际温度之间的差异称为误差,然后将误差乘以一个比例增益参数,得到一个修正值。这个修正值与控制设备的输出信号相加,以调整温度控制。

②积分(Integral)控制:积分控制用于处理长期的温度误差。它通过对温度误差进行积分来计算一个积分误差。积分误差乘以积分增益参数,并且在一段时间内进行积累,得到一个修正值。积分控制可以帮助消除持续的稳态误差,使系统更快地达到设定温度。

③微分(Derivative)控制:微分控制用于处理温度变化的速率。它通过计算温度误差的变化率,即误差的导数,得到一个微分值。微分值乘以一个微分增益参数,用于调整修正值。微分控制可以帮助系统更快地响应温度变化,以防止过冲。

通过结合比例、积分和微分部分的修正值,PID控制算法可以计算出最终的控制信号。这个控制信号会被传递给加热器,以控制温度的变化。

2.本实验用到了CW32-48大学计划开发板OK、温控实验模块及Keil5开发环境。


CW32-48大学计划开发板OK

温控实验模块
e0ec5ca4-3a89-11ee-9e74-dac502259ad0.png
e0fbcc7a-3a89-11ee-9e74-dac502259ad0.png
温控模块电路原理


4.核心代码

mian.c:


#include "config.h"


unsigned char face = 0;       //界面变量
unsigned char face_brush = 0; //界面刷新频率控制


void InitSystem(void)  
{
  RCC_Configuration();        //时钟配置
  ADC_Configuration();        //ADC采集通道配置,采集NTC热敏电阻电压
  PID_Configuration();        //PID参数配置
  GPIO_KEYS_Configuration(); //按键GPIO配置
  PWM_Init();                  //两路PWM输出初始化
  Lcd_Init();                 //TFT屏幕初始化
  BTIM_Init();                //定时器初始化
}


void Interface(void)  //人机交互界面
{
  if ( face_brush > 200 )  //200ms刷新一次
  {
    face_brush = 0;
    switch(face)
    {
      case 0://显示PV和SV,该界面下,可以设定SV
        TFTSHOW_STRING_HEADLINE(0,0,"  PID  Control  ");
        TFTSHOW_STRING(2,0,"REAL_Temper(℃):");
        TFTSHOW_STRING(4,0,"   P V:       ");
        TFTSHOW_FLOAT_NUMBER(4,8,pid.Pv);
        TFTSHOW_STRING(6,0,"SET_Temper(℃):");
        TFTSHOW_STRING(8,0,"   S V:       ");
        TFTSHOW_FLOAT_NUMBER(8,8,pid.set_Sv);
        break;
      case 1://该界面下,可以设定P参数
        TFTSHOW_STRING_HEADLINE(0,0,"  PID  Control  ");
        TFTSHOW_STRING(2,0,"SET PID Control:");
        TFTSHOW_STRING(4,0,"    P :       ");
        TFTSHOW_INT_NUMBER(4,8,pid.set_Kp);
        break;
      case 2://该界面下,可以设定I参数
        TFTSHOW_STRING_HEADLINE(0,0,"  PID  Control  ");
        TFTSHOW_STRING(2,0,"SET PID Control:");
        TFTSHOW_STRING(4,0,"    I :       ");
        TFTSHOW_FLOAT_NUMBER(4,8,pid.set_Ki);
        break;
      case 3://该界面下,可以设定D参数
        TFTSHOW_STRING_HEADLINE(0,0,"  PID  Control  ");
        TFTSHOW_STRING(2,0,"SET PID Control:");
        TFTSHOW_STRING(4,0,"    D :       ");
        TFTSHOW_INT_NUMBER(4,8,pid.set_Kd);
        break;
      case 4://该界面下,可以设定Out0,即修正值
        TFTSHOW_STRING_HEADLINE(0,0,"  PID  Control  ");
        TFTSHOW_STRING(2,0,"SET PID Control:");
        TFTSHOW_STRING(4,0,"   OUT0 :      ");
        TFTSHOW_INT_NUMBER(4,10,pid.set_Out0);
        break;
    }
  }
}


int main()           //主函数
{
  InitSystem();      //系统初始化
  while(1)
  {
    PID_Calc();      //PID运算
    Interface();     //人机交互界面
    Keys_Function(); //按键控制    
  }
}


pwm.c:


#include "pwm.h"


void PWM_Init(void)
{
  RCC_APBPeriphClk_Enable1(RCC_APB1_PERIPH_GTIM2,ENABLE); //使能GTIM2时钟


  __RCC_GPIOA_CLK_ENABLE();   //使能GPIOA时钟


  PA01_AFx_GTIM2CH2();        //打开PWM输出通道
  PA02_AFx_GTIM2CH3();


  GPIO_InitTypeDef GPIO_InitStruct;


  GPIO_InitStruct.IT = GPIO_IT_NONE; 
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  //推挽输出模式
  GPIO_InitStruct.Pins = GPIO_PIN_1|GPIO_PIN_2;
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  GPIO_Init(CW_GPIOA, &GPIO_InitStruct);


  GTIM_InitTypeDef GTIM_Initstructure;     //通用定时器
  GTIM_Initstructure.Mode=GTIM_MODE_TIME;  //计数模式
  GTIM_Initstructure.OneShotMode=GTIM_COUNT_CONTINUE; //连续计数
  GTIM_Initstructure.Prescaler=GTIM_PRESCALER_DIV64; //预分频
  GTIM_Initstructure.ReloadValue=2000-1; //ARR,计数重载周期2000
  GTIM_Initstructure.ToggleOutState=DISABLE;
  GTIM_TimeBaseInit(CW_GTIM2,>IM_Initstructure);


  GTIM_OCInit(CW_GTIM2,GTIM_CHANNEL3,GTIM_OC_OUTPUT_PWM_LOW); //GTIM2输出比较,CH3、CH2
  GTIM_OCInit(CW_GTIM2,GTIM_CHANNEL2,GTIM_OC_OUTPUT_PWM_LOW); //有效占空比为低电平
  GTIM_Cmd(CW_GTIM2,ENABLE); //使能GTIM2
}


void PWM1_Output(uint32_t value)
{
  GTIM_SetCompare3(CW_GTIM2,value);  //设置GTIM2通道3的CCR
}


void PWM2_Output(uint32_t value)
{
  GTIM_SetCompare2(CW_GTIM2,value);  //设置GTIM2通道2的CCR
}


void PWM_ALL_Output(uint32_t value)  //PWM1、2同步输出
{
  PWM1_Output(value);
  PWM2_Output(value);
}


pid.c:


#include "pid.h"


PID pid;    //定义PID结构体变量pid


void PID_Configuration(void)   //PID参数初始化配置 
{
  pid.Sv     = 55;


  pid.Kp     = 350;  //比例系数
  pid.Ki     = 10;   //积分系数
  pid.Kd     = 38;   //微分系数


  pid.Ek_1   = 0;    //上一次偏差
  pid.T      = 400;  //PID计算周期


  pid.cnt    = 0;    
  pid.cycle  = 2000; //PWM周期
  pid.Out0   = 500;  //PID修正值


  pid.set_Sv = pid.Sv;
  pid.set_Kp = pid.Kp;
  pid.set_Ki = pid.Ki;
  pid.set_Kd = pid.Kd;
  pid.set_Out0 = pid.Out0;
}


float Get_Pv(void)  //Pv意为当前测量值,即当前温度
{
  return Get_Temperture();
}


void PID_Calc(void)    //PID算法
{
  float Pout,Iout,Dout;
  float out;


  if ( pid.cnt > pid.T )   //控制计算周期
  {
    pid.cnt = 0;


    pid.Pv = Get_Pv();       
    pid.Ek = pid.Sv - pid.Pv; //计算偏差
    pid.SumEk += pid.Ek;  //偏差累积




    Pout = pid.Kp * pid.Ek;  //比例控制


    Dout = pid.Kd * (pid.Ek - pid.Ek_1);  //微分控制


    if(pid.Pv>(pid.Sv-1))   //当测量值非常接近目标值的时候加入积分控制
    {
      Iout = pid.Ki * pid.SumEk;           //积分控制
      out = Pout + Iout + Dout + pid.Out0; 
    }
    else   out  = Pout + Dout + pid.Out0;  //测量值距离目标值较远时只使用PD控制


    if ( out > pid.cycle ) pid.Out = pid.cycle; //限幅
    else if ( out < 0 )    pid.Out = 0;
    else                   pid.Out = out;
    PWM_ALL_Output(pid.Out);  //控制PWM输出
    pid.Ek_1 = pid.Ek;  //进行下一次PID运算之前,将本次偏差变为上次偏差
  }
}





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 处理器
    +关注

    关注

    68

    文章

    18298

    浏览量

    222304
  • 热敏电阻
    +关注

    关注

    13

    文章

    1002

    浏览量

    100907
  • 加热器
    +关注

    关注

    3

    文章

    205

    浏览量

    20141
  • TFT屏
    +关注

    关注

    0

    文章

    17

    浏览量

    5633
  • PID温度控制
    +关注

    关注

    0

    文章

    3

    浏览量

    912

原文标题:【CW32】基于CW32的PID温度控制

文章出处:【微信号:CW32生态社区,微信公众号:CW32生态社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    CW32移植Free-RTOS】CW32开发者扶持计划

    CW32配置Free-RTOS全过程,CW32开发者扶持计划
    的头像 发表于 04-18 09:38 5577次阅读
    【<b class='flag-5'>CW32</b>移植Free-RTOS】<b class='flag-5'>CW32</b>开发者扶持计划

    CW32快速开发入门

    CW32快速开发入门
    的头像 发表于 04-24 18:56 898次阅读
    <b class='flag-5'>CW32</b>快速开发入门

    CW32量产烧录工具

    本节主要介绍CW32控制器的烧录器CW-Writer,以及与之配合的软件CW-Programmer的使用方法。烧录器CW-Writer通过
    的头像 发表于 04-25 15:22 531次阅读
    <b class='flag-5'>CW32</b>量产烧录工具

    CW32开发者扶持计划#CW32 #芯片

    CW32
    CW32生态社区
    发布于 :2023年05月24日 16:56:14

    【应用笔记】CW32 自举程序中使用的 ISP 协议

    CW32 自举程序中使用的 ISP 协议CW32控制器片上 FLASH 存储器有一部分区域用于存储 BootLoader 启动程序,在芯片出厂时已编程,用户可利用 BootLoader 启动程序
    发表于 06-06 13:26

    CW32系列微控制器选型表分享

    CW32系列微控制器选型表
    发表于 09-15 07:30

    cw32和stm32的区别

    cw32和stm32的区别 CW32和STM32是两种常见的单片机,被广泛应用于各种电子设备中。在本文中,我们将深入探讨CW32和STM32之间的区别和优劣势。 1. 硬件性能 硬件性能是衡量单片机
    的头像 发表于 08-16 11:15 2264次阅读

    cw32和gd32的区别

    推出的一款32位微控制器,它是WCH唯一以ARM Cortex-M3内核为基础的产品系列,Cortex-M3内核是ARM公司的经典内核之一,性能稳定,功耗低。CW32系列的主频高达72MHz,内置
    的头像 发表于 08-16 11:15 1128次阅读

    基于CW32的无刷水泵方案

    基于CW32的无刷水泵方案
    的头像 发表于 11-03 17:28 449次阅读
    基于<b class='flag-5'>CW32</b>的无刷水泵方案

    基于CW32热敏电阻采集温度应用

    基于CW32热敏电阻采集温度应用
    的头像 发表于 10-25 16:45 250次阅读
    基于<b class='flag-5'>CW32</b>热敏电阻采集<b class='flag-5'>温度</b>应用

    CW32 PWM输出功能介绍

    CW32 PWM输出功能介绍
    的头像 发表于 09-27 16:12 415次阅读
    <b class='flag-5'>CW32</b> PWM输出功能介绍

    应用笔记-CW32 自举程序中使用的 ISP 协议

    CW32自举程序中使用的ISP协议CW32控制器片上FLASH存储器有一部分区域用于存储BootLoader启动程序,在芯片出厂时已编程,用户可利用BootLoader启动程序提供的ISP模式
    发表于 06-06 13:37 7次下载

    2023电赛A题国奖CW32 开源分享

    电赛A题开源分享,主控为CW32
    的头像 发表于 11-02 10:16 792次阅读
    2023电赛A题国奖<b class='flag-5'>CW32</b> 开源分享

    基于CW32的物联网应用

    CW32】基于CW32的物联网应用
    的头像 发表于 11-02 15:55 338次阅读
    基于<b class='flag-5'>CW32</b>的物联网应用

    CW32单片机在智能马桶的应用介绍

    和调节。本文将介绍CW32单片机在智能马桶的详细应用。图:CW32的智能马桶控制CW32单片机在智能马桶的应用介绍1.温度感应与
    的头像 发表于 12-20 10:09 261次阅读
    <b class='flag-5'>CW32</b>单片机在智能马桶的应用介绍