|
|
針對電阻加熱爐溫控需求,本文設(shè)計了一套以AT89C51 單片機為核心的溫度閉環(huán)控制系統(tǒng)。系統(tǒng)采K型熱電偶搭配MAX6675轉(zhuǎn)換芯片完成高溫信號采集,依托芯片內(nèi)置 12 位 ADC、冷端補償及 SPI 通信功能,實現(xiàn)溫度信號的數(shù)字化轉(zhuǎn)換與穩(wěn)定傳輸;使用 8 位共陽數(shù)碼管實時展示溫度數(shù)據(jù)與系統(tǒng)狀態(tài),通過獨立按鍵完成目標溫度、報警閾值、PID 參數(shù)的在線整定與工作模式切換。系統(tǒng)以數(shù)字 PID 算法作為核心控制策略,結(jié)合軟件方式生成 PWM 波形,通過調(diào)節(jié)雙向晶閘管導通占空比改變加熱功率,進而實現(xiàn)電阻加熱爐的恒溫控制。同時電路增設(shè)聲光報警模塊,具備超溫、傳感器故障提示功能。經(jīng)整體調(diào)試,該系統(tǒng)結(jié)構(gòu)簡單、成本低廉、抗干擾能力強、操作便捷,控溫效果穩(wěn)定,能夠滿足中小型電阻加熱爐的溫度控制要求,具備較強的實際應用價值。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png (44.44 KB, 下載次數(shù): 0)
下載附件
2026-6-15 14:45 上傳
51hei.png (51.32 KB, 下載次數(shù): 0)
下載附件
2026-6-15 14:45 上傳
電路原理圖如下:
51hei.png (76.45 KB, 下載次數(shù): 0)
下載附件
2026-6-15 14:46 上傳
程序流程圖:
流程圖.jpg (42.76 KB, 下載次數(shù): 0)
下載附件
2026-6-15 14:44 上傳
單片機K型熱電偶電熱爐源程序如下:- #include "reg51.h"
- #include "max6675.h"
- #define uchar unsigned char
- #define uint unsigned int
- sbit smg1=P2^0;//數(shù)碼管
- sbit smg2=P2^1;
- sbit smg3=P2^2;
- sbit smg4=P2^3;
- sbit smg5=P2^4;
- sbit smg6=P2^5;
- sbit smg7=P2^6;
- sbit smg8=P2^7;
- sbit k1=P1^0;//按鈕
- sbit k2=P1^1;
- sbit k3=P1^2;
- sbit k4=P1^3;
- sbit k5=P1^4;
- sbit k6=P1^5;
- sbit k7=P1^6;
- sbit beep=P3^7;//蜂鳴器
- sbit out=P3^6;//輸出控制
- uchar time=0;//系統(tǒng)定時
- uint wendu=0;//溫度
- uchar pwm=0;//占空比
- uchar mode=0;//模式
- uint set=800;//設(shè)置溫度
- uint limit=1000;//報警溫度
- uchar ii=0;
- //數(shù)碼管編碼
- uchar code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- uchar P_dat=1,I_dat=1,D_dat=1;//PID參數(shù)
- uint pid_dat[]={0,0,0,0,0}; //臨時數(shù)據(jù)
- //PID計算,返回占空比
- uchar PID(uint mub,uint dat)//調(diào)整目標+測量數(shù)據(jù)
- {
- uchar i=0;
- uint j=0,sum=0,k=0;
- //存儲數(shù)據(jù)
- for(i=0;i<4;i++)
- pid_dat[i]=pid_dat[i+1];
- pid_dat[4]=dat;
- //P調(diào)節(jié)
- j=0;
- if(dat<mub)
- {
- j=j+(mub-dat)*P_dat;
- if(j>100)
- j=100;
- }
- else
- {
- k=(dat-mub)*P_dat;
- if(j>k)
- j=j-k;
- }
- //I調(diào)節(jié)
- sum=0;
- for(i=0;i<5;i++)
- sum+=pid_dat[i];
- sum=sum/5;
- if(sum>mub)//減小
- {
- k=(sum-mub)*I_dat;
- if(j>k)
- j=j-k;
- }
- else //增加
- {
- k=(mub-sum)*I_dat;
- j+=k;
- if(j>100)
- j=100;
- }
- //D調(diào)節(jié)
- if(dat>pid_dat[3])//減小
- {
- k=(dat-pid_dat[3])*D_dat;
- if(j>k)
- j=j-k;
- }
- else //增加
- {
- k=(pid_dat[3]-dat)*D_dat;
- j+=k;
- if(j>100)
- j=100;
- }
- return j;
- }
- //延時
- void delay(uint i)
- {
- while(i--)
- {
- if(ii<99)//占空比計時
- ii++;
- else
- ii=0;
- if(ii<pwm)//輸出控制
- out=0;
- else
- out=1;
- }
- }
- //主函數(shù)
- void main()
- {
- uchar k=0;
- TMOD|=0X01;//初始化定時器
- TH0=0X3C;
- TL0=0XB0;
- ET0=1;//打開定時器0中斷允許
- EA=1;//打開總中斷
- TR0=1;//打開定時器
- while(1)
- {
- if(P1==0xff)
- k=0;
- //設(shè)置
- if(!k1 &&(k!=1))//設(shè)置切換
- {
- k=1;
- if(mode<5)
- mode++;
- else
- mode=0;
- }
- //設(shè)置調(diào)整溫度
- if(mode==1)
- {
- if(!k2 &&(k!=2))//+1
- {
- k=2;
- if(set<9999)
- set++;
- }
- if(!k3 &&(k!=3))//-1
- {
- k=3;
- if(set>0)
- set--;
- }
- if(!k4 &&(k!=4))//+10
- {
- k=4;
- if(set<9999)
- set+=10;
- }
- if(!k5 &&(k!=5))//-10
- {
- k=5;
- if(set>10)
- set-=10;
- }
- if(!k6 &&(k!=6))//+100
- {
- k=6;
- if(set<9999)
- set+=100;
- }
- if(!k7 &&(k!=7))//-100
- {
- k=7;
- if(set>100)
- set-=100;
- }
- }
- //設(shè)置報警溫度
- if(mode==2)
- {
- if(!k2 &&(k!=2))//+1
- {
- k=2;
- if(limit<9999)
- limit++;
- }
- if(!k3 &&(k!=3))//-1
- {
- k=3;
- if(limit>0)
- limit--;
- }
- if(!k4 &&(k!=4))//+10
- {
- k=4;
- if(limit<9999)
- limit+=10;
- }
- if(!k5 &&(k!=5))//-10
- {
- k=5;
- if(limit>10)
- limit-=10;
- }
- if(!k6 &&(k!=6))//+100
- {
- k=6;
- if(limit<9999)
- limit+=100;
- }
- if(!k7 &&(k!=7))//-100
- {
- k=7;
- if(limit>100)
- limit-=100;
- }
- }
- //設(shè)置P參數(shù)
- if(mode==3)
- {
- if(!k2 &&(k!=2))//+1
- {
- k=2;
- if(P_dat<99)
- P_dat++;
- }
- if(!k3 &&(k!=3))//-1
- {
- k=3;
- if(P_dat>0)
- P_dat--;
- }
- }
- //設(shè)置I參數(shù)
- if(mode==4)
- {
- if(!k2 &&(k!=2))//+1
- {
- k=2;
- if(I_dat<99)
- I_dat++;
- }
- if(!k3 &&(k!=3))//-1
- {
- k=3;
- if(I_dat>0)
- I_dat--;
- }
- }
- //設(shè)置D參數(shù)
- if(mode==5)
- {
- if(!k2 &&(k!=2))//+1
- {
- k=2;
- if(D_dat<99)
- D_dat++;
- }
- if(!k3 &&(k!=3))//-1
- {
- k=3;
- if(D_dat>0)
- D_dat--;
- }
- }
- //報警
- if(wendu>limit)
- beep=0;
- else
- beep=1;
- //顯示
- if(mode==0)
- {
- P0=smgduan[wendu/1000]; smg5=0;delay(50);smg5=1;
- P0=smgduan[wendu%1000/100]; smg6=0;delay(50);smg6=1;
- P0=smgduan[wendu%100/10]; smg7=0;delay(50);smg7=1;
- P0=smgduan[wendu%10]; smg8=0;delay(50);smg8=1;
- }
- if(mode==1)
- {
- P0=smgduan[1]; smg1=0;delay(50);smg1=1;
- P0=smgduan[set/1000]; smg5=0;delay(50);smg5=1;
- P0=smgduan[set%1000/100]; smg6=0;delay(50);smg6=1;
- P0=smgduan[set%100/10]; smg7=0;delay(50);smg7=1;
- P0=smgduan[set%10]; smg8=0;delay(50);smg8=1;
- }
- if(mode==2)
- {
- P0=smgduan[2]; smg1=0;delay(50);smg1=1;
- P0=smgduan[limit/1000]; smg5=0;delay(50);smg5=1;
- P0=smgduan[limit%1000/100]; smg6=0;delay(50);smg6=1;
- P0=smgduan[limit%100/10]; smg7=0;delay(50);smg7=1;
- P0=smgduan[limit%10]; smg8=0;delay(50);smg8=1;
- }
- if(mode==3)
- {
- P0=smgduan[3]; smg1=0;delay(50);smg1=1;
- P0=smgduan[P_dat/10]; smg7=0;delay(50);smg7=1;
- P0=smgduan[P_dat%10]; smg8=0;delay(50);smg8=1;
- }
- if(mode==4)
- {
- P0=smgduan[4]; smg1=0;delay(50);smg1=1;
- P0=smgduan[I_dat/10]; smg7=0;delay(50);smg7=1;
- P0=smgduan[I_dat%10]; smg8=0;delay(50);smg8=1;
- }
- if(mode==5)
- {
- P0=smgduan[5]; smg1=0;delay(50);smg1=1;
- P0=smgduan[D_dat/10]; smg7=0;delay(50);smg7=1;
- P0=smgduan[D_dat%10]; smg8=0;delay(50);smg8=1;
- }
- }
- }
- //定時器0中斷
- void Timer0() interrupt 1
- {
- unsigned long j;
- if(time<10)//0.5s
- time++;
- else
- {
- time=0;
- wendu=max_read();//測溫
- j=wendu;
- j=j*100/138;
- wendu=j;
- pwm=PID(set,wendu);//PID計算
- }
- TH0=0X3C;
- TL0=0XB0;
- }
復制代碼
|
|