本水溫自動控制系統(tǒng)分為主控部分、顯示部分、接收部分、無線部分、上位機部分共五大部分,其中主控部分和上位機部分是本次設(shè)計的重點。 普通溫度傳感器只能在容器的外部對溫度進行采集,不能很準(zhǔn)確的反應(yīng)實時的變化量。由于加熱棒停止加熱一段時間內(nèi)仍然有加熱的功效,所以如果溫度到達時才停止加熱,溫度一定會超出目標(biāo)溫度很多,所以采用PID算法可以較為準(zhǔn)確的控制水溫的變化情況。因為水有惰性,如果不進行攪拌那么一個燒杯中的水上層和下層甚至可能會差十?dāng)z氏度,所以需要讓水運動起來。由于容器較小,使用電機攪拌空間不足,所以采用氣泵方式。 當(dāng)主控端上電后,系統(tǒng)對溫度采集模塊、加熱控制模塊、制冷控制模塊、LCD顯示模塊、按鍵控制模塊、無線傳輸模塊進行初始化。初始化完成后,讀取無線數(shù)據(jù)的接收緩沖區(qū),判斷是否接收到數(shù)據(jù),如果收到命令則判斷其命令類型并執(zhí)行。檢測按鍵是否被按下,如果被按下則處理相應(yīng)的按鍵事件。獲取當(dāng)前溫度,在LCD上顯示,并通過無線將溫度數(shù)據(jù)發(fā)送給接收端,把當(dāng)前溫度值傳入PID算法中進行運算,得出脈沖寬度,再通過脈沖控制加熱棒加熱或制冷器制冷。
批注 2020-06-30 141855.png (183.13 KB, 下載次數(shù): 63)
下載附件
電路圖
2020-6-30 14:22 上傳
PID算法:#include "STC12C5A60S2.h"
#include "DisplayLED.h"
#include "USART.h"
#include "DS18B20.h"
sbit JiaRe = P3^5;
sbit KEY0 = P3^0;
sbit KEY1 = P3^1;
sbit KEY2 = P3^2;
sbit KEY3 = P3^3;
sbit LED = P3^6;
unsigned int Time_count = 0;
unsigned int TIME_MY = 1;
unsigned char JiaReFlag = 0;
unsigned char TxVALUE[RXTX_WIDTH];
typedef struct
{
signed int dState; // 保存最后一次輸入
signed int iState; // 積分器狀態(tài)
signed int iMax, iMin; // 積分器上下限
signed int iGain, // 積分增益
pGain, // 比例增益
dGain; // 微分增益
} SPid;
void Time0Init(void)
{
TMOD |= 0x01; // 設(shè)置定時器模式
TH0 = (65536-5000)/256; // 裝初值
TL0 = (65536-5000)%256;
TR0 = 0; // 開定時器
ET0 = 1; // 定時器中斷
EA = 1; // 開總中斷
}
void TimeZero() interrupt 1
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256; // 重填TH0,TL0
Time_count ++;
if(Time_count >= 40)
Time_count = 0;
if(Time_count < TIME_MY)
{
LED = 0;
JiaRe = 0;
}
else
{
LED = 1;
JiaRe = 1;
}
}
void PWM_ChuLi(signed int re)
{
if(re < 0)
{
TIME_MY = 0;
JiaReFlag = 0;
}
else if(re > 40)
TIME_MY = 40;
else
TIME_MY = re;
}
signed int ControlPID(SPid * pid, signed int error, signed int position)
{
signed int pTerm,dTerm, iTerm;
// 計算的比例項
pTerm = pid->pGain * error;
// 對積分狀態(tài)的限制
pid->iState += error;
if (pid->iState > pid->iMax)
pid->iState = pid->iMax;
else if (pid->iState < pid->iMin)
pid->iState = pid->iMin;
iTerm = pid->iGain * pid->iState;
// 計算的微分項
dTerm = pid->dGain * (position - pid->dState);
pid->dState = position;
return pTerm + iTerm/10 - dTerm;
}
void main(void)
{
signed int CommandSet = 340;
signed int position;
signed int Term;
unsigned int mLoop;
unsigned char SetFlag = 0;
SPid MyPID = {0,0,40,-40,0,4,1};
P0M0 = 0xFF;
P2M0 = 0xFF;
P1M0 = 0xFF;
// UartInit();
Time0Init();
while(1)
{
if(SetFlag == 0)
{
TmpChange();
position = GetTemperature();
Term = ControlPID(&MyPID,(CommandSet/10 - position/10 - 1),position/10);
PWM_ChuLi(Term);
}
for(mLoop = 0;mLoop< 10000;mLoop++)
{
if(KEY0 == 0)
{
while(KEY0 == 0);
SetFlag = ~SetFlag;
while(KEY0 == 0);
DelayMS(20);
while(KEY0 == 0);
DelayMS(20);
}
if(SetFlag != 0)
{
JiaReFlag = 0;
JiaRe = 1;
DisplayLED(CommandSet);
if(KEY1 == 0)
{
CommandSet += 10;
if(CommandSet > 990)
CommandSet = 990;
while(KEY1 == 0);
DelayMS(20);
while(KEY1 == 0);
DelayMS(20);
}
if(KEY2 == 0)
{
while(KEY2 == 0);
CommandSet -= 10;
if(CommandSet < position/10*10 +20)
CommandSet = position/10*10 +20;
while(KEY2 == 0);
DelayMS(20);
while(KEY2 == 0);
DelayMS(20);
}
}
else
{
DisplayLED(position);
}
if(KEY3 == 0)
{
while(KEY3 == 0);
JiaReFlag = 1;
}
if(JiaReFlag !=0)
{
LED = 0;
TR0 = 1;
}
else
{
JiaRe = 1;
TR0 = 0;
LED = 1;
}
}
}
}
全部資料51hei下載地址:
基于51單片機PID算法的自動水溫控制系統(tǒng).rar
(869.98 KB, 下載次數(shù): 201)
2020-6-30 16:38 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|