1.PID溫控系統(tǒng)是一種常用的控制系統(tǒng),用于實(shí)現(xiàn)對(duì)溫度變量的精確控制。PID算法根據(jù)當(dāng)前的溫度誤差以及誤差的變化率,計(jì)算一個(gè)控制信號(hào),用于調(diào)節(jié)加熱器的輸出。以下是PID算法的三個(gè)主要組成部分:
①比例(Proportional)控制:比例控制是根據(jù)當(dāng)前的溫度誤差來(lái)計(jì)算控制信號(hào)。具體而言,通過(guò)將設(shè)定溫度與實(shí)際溫度之間的差異稱為誤差,然后將誤差乘以一個(gè)比例增益參數(shù),得到一個(gè)修正值。這個(gè)修正值與控制設(shè)備的輸出信號(hào)相加,以調(diào)整溫度控制。
②積分(Integral)控制:積分控制用于處理長(zhǎng)期的溫度誤差。它通過(guò)對(duì)溫度誤差進(jìn)行積分來(lái)計(jì)算一個(gè)積分誤差。積分誤差乘以積分增益參數(shù),并且在一段時(shí)間內(nèi)進(jìn)行積累,得到一個(gè)修正值。積分控制可以幫助消除持續(xù)的穩(wěn)態(tài)誤差,使系統(tǒng)更快地達(dá)到設(shè)定溫度。
③微分(Derivative)控制:微分控制用于處理溫度變化的速率。它通過(guò)計(jì)算溫度誤差的變化率,即誤差的導(dǎo)數(shù),得到一個(gè)微分值。微分值乘以一個(gè)微分增益參數(shù),用于調(diào)整修正值。微分控制可以幫助系統(tǒng)更快地響應(yīng)溫度變化,以防止過(guò)沖。
通過(guò)結(jié)合比例、積分和微分部分的修正值,PID控制算法可以計(jì)算出最終的控制信號(hào)。這個(gè)控制信號(hào)會(huì)被傳遞給加熱器,以控制溫度的變化。
2.本實(shí)驗(yàn)用到了CW32-48大學(xué)計(jì)劃開(kāi)發(fā)板OK、溫控實(shí)驗(yàn)?zāi)K及Keil5開(kāi)發(fā)環(huán)境。
CW32-48大學(xué)計(jì)劃開(kāi)發(fā)板OK |
溫控實(shí)驗(yàn)?zāi)K |
![]() ![]() 溫控模塊電路原理圖 |
4.核心代碼
mian.c: #include "config.h" unsigned char face = 0; //界面變量 unsigned char face_brush = 0; //界面刷新頻率控制 void InitSystem(void) { RCC_Configuration(); //時(shí)鐘配置 ADC_Configuration(); //ADC采集通道配置,采集NTC熱敏電阻電壓 PID_Configuration(); //PID參數(shù)配置 GPIO_KEYS_Configuration(); //按鍵GPIO配置 PWM_Init(); //兩路PWM輸出初始化 Lcd_Init(); //TFT屏幕初始化 BTIM_Init(); //定時(shí)器初始化 } void Interface(void) //人機(jī)交互界面 { 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運(yùn)算 Interface(); //人機(jī)交互界面 Keys_Function(); //按鍵控制 } } pwm.c: #include "pwm.h" void PWM_Init(void) { RCC_APBPeriphClk_Enable1(RCC_APB1_PERIPH_GTIM2,ENABLE); //使能GTIM2時(shí)鐘 __RCC_GPIOA_CLK_ENABLE(); //使能GPIOA時(shí)鐘 PA01_AFx_GTIM2CH2(); //打開(kāi)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; //通用定時(shí)器 GTIM_Initstructure.Mode=GTIM_MODE_TIME; //計(jì)數(shù)模式 GTIM_Initstructure.OneShotMode=GTIM_COUNT_CONTINUE; //連續(xù)計(jì)數(shù) GTIM_Initstructure.Prescaler=GTIM_PRESCALER_DIV64; //預(yù)分頻 GTIM_Initstructure.ReloadValue=2000-1; //ARR,計(jì)數(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計(jì)算周期 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意為當(dāng)前測(cè)量值,即當(dāng)前溫度 { return Get_Temperture(); } void PID_Calc(void) //PID算法 { float Pout,Iout,Dout; float out; if ( pid.cnt > pid.T ) //控制計(jì)算周期 { pid.cnt = 0; pid.Pv = Get_Pv(); pid.Ek = pid.Sv - pid.Pv; //計(jì)算偏差 pid.SumEk += pid.Ek; //偏差累積 Pout = pid.Kp * pid.Ek; //比例控制 Dout = pid.Kd * (pid.Ek - pid.Ek_1); //微分控制 if(pid.Pv>(pid.Sv-1)) //當(dāng)測(cè)量值非常接近目標(biāo)值的時(shí)候加入積分控制 { Iout = pid.Ki * pid.SumEk; //積分控制 out = Pout + Iout + Dout + pid.Out0; } else out = Pout + Dout + pid.Out0; //測(cè)量值距離目標(biāo)值較遠(yuǎn)時(shí)只使用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; //進(jìn)行下一次PID運(yùn)算之前,將本次偏差變?yōu)樯洗纹? } }
審核編輯:劉清
-
處理器
+關(guān)注
關(guān)注
68文章
19748瀏覽量
232963 -
熱敏電阻
+關(guān)注
關(guān)注
14文章
1188瀏覽量
102400 -
加熱器
+關(guān)注
關(guān)注
3文章
226瀏覽量
22250 -
TFT屏
+關(guān)注
關(guān)注
0文章
17瀏覽量
5986 -
PID溫度控制
+關(guān)注
關(guān)注
0文章
3瀏覽量
996
原文標(biāo)題:【CW32】基于CW32的PID溫度控制
文章出處:【微信號(hào):CW32生態(tài)社區(qū),微信公眾號(hào):CW32生態(tài)社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
基于CW32的門(mén)禁綜合系統(tǒng)


cw32和stm32的區(qū)別
cw32和gd32的區(qū)別
應(yīng)用筆記-CW32 自舉程序中使用的 ISP 協(xié)議
CW32單片機(jī)在智能馬桶的應(yīng)用介紹

評(píng)論