1.PID溫控系統(tǒng)是一種常用的控制系統(tǒng),用于實現(xiàn)對溫度變量的精確控制。PID算法根據(jù)當前的溫度誤差以及誤差的變化率,計算一個控制信號,用于調(diào)節(jié)加熱器的輸出。以下是PID算法的三個主要組成部分:
①比例(Proportional)控制:比例控制是根據(jù)當前的溫度誤差來計算控制信號。具體而言,通過將設(shè)定溫度與實際溫度之間的差異稱為誤差,然后將誤差乘以一個比例增益參數(shù),得到一個修正值。這個修正值與控制設(shè)備的輸出信號相加,以調(diào)整溫度控制。
②積分(Integral)控制:積分控制用于處理長期的溫度誤差。它通過對溫度誤差進行積分來計算一個積分誤差。積分誤差乘以積分增益參數(shù),并且在一段時間內(nèi)進行積累,得到一個修正值。積分控制可以幫助消除持續(xù)的穩(wěn)態(tài)誤差,使系統(tǒng)更快地達到設(shè)定溫度。
③微分(Derivative)控制:微分控制用于處理溫度變化的速率。它通過計算溫度誤差的變化率,即誤差的導數(shù),得到一個微分值。微分值乘以一個微分增益參數(shù),用于調(diào)整修正值。微分控制可以幫助系統(tǒng)更快地響應溫度變化,以防止過沖。
通過結(jié)合比例、積分和微分部分的修正值,PID控制算法可以計算出最終的控制信號。這個控制信號會被傳遞給加熱器,以控制溫度的變化。
2.本實驗用到了CW32-48大學計劃開發(fā)板OK、溫控實驗模塊及Keil5開發(fā)環(huán)境。
|
CW32-48大學計劃開發(fā)板OK |
溫控實驗模塊 |
![]() ![]() 溫控模塊電路原理圖 |
|
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參數(shù)配置
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,該界面下,可以設(shè)定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://該界面下,可以設(shè)定P參數(shù)
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://該界面下,可以設(shè)定I參數(shù)
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://該界面下,可以設(shè)定D參數(shù)
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://該界面下,可以設(shè)定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() //主函數(shù)
{
InitSystem(); //系統(tǒng)初始化
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; //計數(shù)模式
GTIM_Initstructure.OneShotMode=GTIM_COUNT_CONTINUE; //連續(xù)計數(shù)
GTIM_Initstructure.Prescaler=GTIM_PRESCALER_DIV64; //預分頻
GTIM_Initstructure.ReloadValue=2000-1; //ARR,計數(shù)重載周期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); //設(shè)置GTIM2通道3的CCR
}
void PWM2_Output(uint32_t value)
{
GTIM_SetCompare2(CW_GTIM2,value); //設(shè)置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結(jié)構(gòu)體變量pid
void PID_Configuration(void) //PID參數(shù)初始化配置
{
pid.Sv = 55;
pid.Kp = 350; //比例系數(shù)
pid.Ki = 10; //積分系數(shù)
pid.Kd = 38; //微分系數(shù)
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運算之前,將本次偏差變?yōu)樯洗纹? }
}
審核編輯:劉清
-
處理器
+關(guān)注
關(guān)注
68文章
20118瀏覽量
244914 -
熱敏電阻
+關(guān)注
關(guān)注
15文章
1220瀏覽量
103884 -
加熱器
+關(guān)注
關(guān)注
3文章
236瀏覽量
28140 -
TFT屏
+關(guān)注
關(guān)注
0文章
18瀏覽量
6182 -
PID溫度控制
+關(guān)注
關(guān)注
1文章
3瀏覽量
1073
原文標題:【CW32】基于CW32的PID溫度控制
文章出處:【微信號:CW32生態(tài)社區(qū),微信公眾號:CW32生態(tài)社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
基于CW32的門禁綜合系統(tǒng)

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


評論