51系列单片机闭环温度控制实验报告材料.docx
《51系列单片机闭环温度控制实验报告材料.docx》由会员分享,可在线阅读,更多相关《51系列单片机闭环温度控制实验报告材料.docx(22页珍藏版)》请在冰豆网上搜索。
51系列单片机闭环温度控制实验报告材料
成绩:
综合实验报告
题目:
51系列单片机闭环温度控制
班级:
小组成员:
指导教师:
完成时间:
2015年11月
一、实验名称:
51系列单片机闭环温度控制实验
——基于Protuse仿真实验平台实现
根本情况:
1.实验项目组长:
2.小组成员:
序号
姓名
班级
学号
分工系数
1
2
3
工:
负责程序编写,主要负责查询资料与实验报告撰写。
4.实验要求:
设计硬件电路:
温度检测:
采用热电偶或热电阻
温度给定:
采用电位器进展模拟电压给定,0——5V
AD转采用12位转换
显示采用8位LED,或者LCD1602显示
键盘4X4,PID等参数通过键盘设置。
软件
控制算法:
数字PID,参数在线修改。
显示窗口:
显示温度的设置值SV、温度的实际值PV。
实际温度值,温度峰值、峰值时间等通过串口上传到上位机(选做)
二、实验内容
1、系统根本原理(实验原理介绍)
根据实验要求,温度闭环控制,即对加温速度、超调量、调节时间级误差参数,选择PID控制参数级算法,实现对温度的自动控制。
闭环温度控制系统原理图如下:
2、PID算法的数字实现
本次试验通过8031通过OVEN是模拟加热的装置,加一定的电压便开始不停的升温,直到电压要消失如此开始降温。
仿真时,U形加热器为红色时表示正在加热,发红时将直流电压放过来接,就会制冷,变绿。
T端输出的是电压,温度越高,电压就越高。
8031对温度的控制是通过可控硅调控实现的。
可控硅通过时间可以通过可控硅控制板上控制脉冲控制。
该触发脉冲想8031用软件在P1.3引脚上产生,受过零同步脉冲后经光偶管和驱动器输送到可控硅的控制级上。
偏差控制原理是要求对所需温度求出偏差值,然后对偏差值处理而获得控制信号去调节加热装置的温度。
PID控制方程式:
式中e是指测量值与给定值之间的偏差
TD微分时间
T积分时间
KP调节器的放大系数
将上式离散化得到数字PID位置式算法,式中在位置算法的根底之上得到数字PID
增量式算法:
3、温度控制软件设计
程序结构图如下:
4、硬件电路设计
在温度控制中,经常采用是硬件电路主要有两大局部组成:
模拟局部和数字局部,对这两局部调节仪表进展调节,但都存在着许多缺点,用单片机进展温度控制使构成的系统灵活,可靠性高,并可用软件对传感器信号进展抗干拢滤波和非线性补偿处理,可大大提高控制质量和自动化水平;总的来说本系统由四大模块组成,它们是输入模块、单片机系统模块、计算机显示与控制模块和输出控制模块。
输入模块主要完成对温度信号的采集和转换工作,由温度传感器与其与单片机的接口局部组成。
利用模拟加热的装置来控制温度。
该闭环温度控制系统采用AT89S51八位机作为微处理单元进展控制。
采用4X4键盘把设定温度的最高值和最低值存入单片机的数据存储器,还可以通过键盘完成温度检测功能的转换。
温度传感器把采集的信号与单片机里的数据相比拟来控制温度控制器。
5、电路原理图
1、仿真完整电路图
2、12位AD转换模块
3、OVEN模型与信号调理电路
4、单片机主电路
三、实验结果分析〔含程序、数据记录与分析和实验总结等,可附页〕:
1、51系列单片机闭环温度控制实验程序
#include"includes.h"
charmeasure_temperature[6]={'+','0','0','0','C','\0'};
charsetting_temperature[6]={'0','1','0','0','C','\0'};
charcode_table[16]={'7','8','9','T',
'4','5','6','P',
'1','2','3','I',
'+','0','-','D'};
charPv[6]={'P','0','9','0','','\0'};
charIv[6]={'I','0','0','0','','\0'};
charDv[6]={'D','0','0','5','','\0'};
intPWM_Period=100;
intPWM_Hight=1;
intPWM_Hights=50;
shortm_temperature=0;
shorts_temperature=100;
floatpc=090.0;
floatic=0.0;
floatdc=5.0;
floate1=0;
floate2=0;
charRX_Data[5]={0};
intmain()
{
timer_init();
lcd_init();
while
(1)
{
ADCRead();
keyscan();
Data_update();
LCD_Display(0x80+0x08,setting_temperature);
LCD_Display(0x80+0x40,Pv);
LCD_Display(0x80+0x45,Iv);
LCD_Display(0x80+0x4A,Dv);
}
return0;
#include"includes.h"
ucharT_update=0;
ucharP_update=0;
ucharI_update=0;
ucharD_update=0;
voidT0_time()interrupt1//PWM
{
PWM_Hights--;
if(PWM_Hights==0)
{
PWM_EN=0;
PWM_Hights=1;
}
PWM_Period--;
if(PWM_Period==0)
{
PWM_EN=1;
PWM_Period=100;
PWM_Hights=PWM_Hight;
}
}
voidpid()
{
staticlongsum=0;
e2=e1;
e1=s_temperature-m_temperature;
sum+=e1;
if(e1>20)
{
PWM_Hight=100;
}
elseif(e1<-20)
{
PWM_Hight=1;
}
else
{
PWM_Hight=PWM_Hight+pc*(e1+ic*sum+dc*(e1-e2));
}
if(PWM_Hight>100)
PWM_Hight=100;
elseif(PWM_Hight<1)
PWM_Hight=1;
}
voidInterrupt_T1()interrupt3
{
staticintcount=0;
TH1=0x3C;//定时50ms
TL1=0xB0;
count++;
if(count==20)
{
pid();
count=0;
}
}
voidupdate_Temp()
{
shortj=0;
shorttmp=0;
for(j=1;j<=3;j++)
{
tmp=tmp*10+(setting_temperature[j]-'0');
}
if(setting_temperature[0]=='-')
tmp=-tmp;
s_temperature=tmp;
}
voidupdate_Pv()
{
shortj=0;
shorttmp=0;
for(j=1;j<=3;j++)
{
tmp=tmp*10+(Pv[j]-'0');
}
pc=tmp;
}
voidupdate_Iv()
{
shortj=0;
shorttmp=0;
for(j=1;j<=3;j++)
{
tmp=tmp*10+(Iv[j]-'0');
}
ic=tmp;
}
voidupdate_Dv()
{
shortj=0;
shorttmp=0;
for(j=1;j<=3;j++)
{
tmp=tmp*10+(Dv[j]-'0');
}
dc=tmp;
}
voidData_update()//循环检查每一次T、PID值是否有修改
{
if(T_update==1)
{
update_Temp();
T_update=0;
}
elseif(P_update==1)
{
update_Pv();
P_update=0;
}
elseif(I_update==1)
{
update_Iv();
I_update=0;
}
elseif(D_update==1)
{
update_Dv();
D_update=0;
}
}
#include"includes.h"
voidtimer_init()
{
EA=0;//关闭总中断
ET0=1;//ET0用于PWM产生
ET1=1;//ET1测速计时
TMOD=0x12;//T0:
工作方式2T1:
工作方式1
TH0=0x9C;
TL0=0x9C;
TH1=0x3C;//定时50ms
TL1=0xB0;
TR0=1;//运行定时器0
TR1=1;//运行定时器1
PT0=1;//T0中断优先级高
EA=1;//打开总中断
}
#include"includes.h"
voiditoa(shortnum,charstr[])
{
inti=3;
num=(num/2047.0)*999.0;
for(i=3;i>0;i--)
{
str[i]=(num%10)+'0';
num=num/10;
}
str[5]='\0';
}
voidADCRead()
{
shortnum=0;//无符号16位
RC=0;//启动转换
RC=1;//启动读取
while(BUSY==0);
num=0;
BYTE=0;//读取高4位
num=(num|P1)<<8;
num=num&0x0F00;
BYTE=1;//读取低8位
num=num|P1;//12位数据完整取好
if((num&0x0800)==0x0800)
{
measure_temperature[0]='-';
num=num&0xF7FF;
num=(num^0x07FF)+1;
m_temperature=-((num/2047.0)*999.0);
}
else
{
measure_temperature[0]='+';
m_temperature=(num/2047.0)*999.0;
}
itoa(num,measure_temperature);
LCD_Display(0x80,measure_temperature);
RC=0;
}
#include"includes.h"
voiddelay_ms(intn)//1ms延时
{
uinti=0,j=0;
for(i=0;ifor(j=0;j<123;j++);
}
#include"includes.h"
voidlcd_w(uchar)//1602写命令函数单片机给1602写命令
{
rs=0;//选择指令存放器
rw=0;//选择写
P0=;//把命令字送入
delay_ms
(1);
en=1;//使能线电平变化,命令送入1602的8位数据口
delay_ms
(1);
en=0;
}
voidlcd_wdat(uchardat)//1602写数据函数
{
rs=1;//选择数据存放器
rw=0;//选择写
P0=dat;//把要显示的数据送入
delay_ms
(1);
en=1;//使能线电平变化,数据送入1602的8位数据口
delay_ms
(1);
en=0;
}
voidLCD_Display(uintlocation,ucharDisplay_Part[])
{
inti=0;
lcd_w(location);
for(i=0;Display_Part[i]!
=0;i++)
{
lcd_wdat(Display_Part[i]);
delay_ms
(1);
}
}
voidlcd_init()//1602初始化函数
{
lcd_w(0x38);//8位数据,双列,5*7字形
lcd_w(0x0c);//开启显示屏,关光标,光标不闪烁
lcd_w(0x06);//显示地址递增,即写一个数据后,显示位置右移一位
lcd_w(0x01);//清屏
LCD_Display(0x80+0x08,setting_temperature);
LCD_Display(0x80+0x40,Pv);
LCD_Display(0x80+0x45,Iv);
LCD_Display(0x80+0x4A,Dv);
}
#include"includes.h"
voidkeyscan()
{
uintkeyno=16;
uchartemp=0;
uchari=0;
staticcharupdate_flag=0;
staticintupdate_index=0;
charkey_code=0;
P3=0x0F;
if(P3!
=0x0F)
{
P3=0x0F;
//delay_ms
(1);
temp=P3;
i=temp^0x0F;
switch(i)
{
case1:
keyno=0;break;
case2:
keyno=1;break;
case4:
keyno=2;break;
case8:
keyno=3;break;
default:
keyno=16;//无键按下
}
P3=0xF0;
temp=P3;
//delay_ms
(1);
i=(temp>>4)^0x0F;
switch(i)
{
case1:
keyno+=0;break;
case2:
keyno+=4;break;
case4:
keyno+=8;break;
case8:
keyno+=12;break;
}
while(P3!
=0xF0);
}
if(keyno>=0&&keyno<=15)
{
if(update_flag==1)
{
key_code=code_table[keyno];
setting_temperature[update_index]=key_code;
update_index++;
if(update_index==4)
{
update_flag=0;
update_index=0;
T_update=1;
}
}
elseif(update_flag==2)
{
key_code=code_table[keyno];
Pv[1+update_index]=key_code;
update_index++;
if(update_index==3)
{
update_flag=0;
update_index=0;
P_update=1;
}
}
elseif(update_flag==3)
{
key_code=code_table[keyno];
Iv[1+update_index]=key_code;
update_index++;
if(update_index==3)
{
update_flag=0;
update_index=0;
I_update=1;
}
}
elseif(update_flag==4)
{
key_code=code_table[keyno];
Dv[1+update_index]=key_code;
update_index++;
if(update_index==3)
{
update_flag=0;
update_index=0;
D_update=1;
}
}
else
{
switch(keyno)
{
case3:
update_flag=1;break;
case7:
update_flag=2;break;
case11:
update_flag=3;break;
case15:
update_flag=4;break;
default:
update_flag=0;
}
}
}
}
2、实验结果
100度设定温度仿真结果
零下25度设定温度仿真结果
3、实验总结
温度控制广泛应用于人们的生产和生活中,人们使用温度计来采集温度,通过人工操51系列单片机直流电机闭环调速实验劳动强度大。
即使有些用户采用半导体二极管作温度传感器,但由于其互换性差,效果也不理想。
在某些行业中对温度的要求较高,由于工作环境温度不合理而引发的事故时有发生。
对工业生产可靠进展造成影响,甚至操作人员的安全。
为了防止这些缺点,需要在某些特定的环境里安装数字温度测量与控制设备。
在工业生产和日常生活中,对温度控制系统的要求,主要是保证温度在一定温度X围内变化,稳定性好,不振荡,对系统的快速要求不高。
在报告中中简单分析了温度控制系统基于Protuse仿真实验,采用热电偶作为温度检测器,应用LED显示,通过键盘4X4来对PID进展参数控制。
本实验设计使用8031作为主芯片进展控制,单片机具有集成度高,通用性好,功能强,特别是体积小,重量轻,耗能低,可靠性高,抗干扰能力强和使用方便等独特优点,在数字、智能化方面有广泛用途。
其温度控制所用的热电偶,X围广泛,在系统中如果加强算法,会大大提高控制精度,同时降低本钱,提高效率。
经过这次的实验,我们通过小组合作分工完成了本次实验,又一次加深了对LED的认识和加强了对keil以与Protues等软件的使用技能。
在实验过程中,我们都要足够细心有耐心,在调试程序的时候要细心的检查错误。
在以后的学习中我们都要会学好理论知识,将理论与实践相结合,不断提高自己动手能力。