您好,欢迎来到微智科技网。
搜索
您的当前位置:首页51系列单片机闭环温度控制实验报告

51系列单片机闭环温度控制实验报告

来源:微智科技网
 成 绩:

综合实验报告

题 目:班 级:小组成员: 指导教师:完成时间:

51系列单片机闭环温度控制

2015年11月

一、实验名称:

51系列单片机闭环温度控制实验

——基于Protuse仿真实验平台实现

基本情况: 1.实验项目组长: 2. 小组成员: 序号 1 2 3

3.具体分工:负责程序编写,主要负责查询资料与实验报告撰写。 4.实验要求: ①设计硬件电路:

温度检测:采用热电偶或热电阻

温度给定:采用电位器进行模拟电压给定,0——5V AD转采用12位转换

显示采用8位LED,或者LCD1602显示 键盘4X4,PID等参数通过键盘设置。 ②软件

控制算法:数字PID,参数在线修改。

显示窗口:显示温度的设置值SV、温度的实际值PV。

实际温度值,温度峰值、峰值时间等通过串口上传到上位机(选做)

姓 名 班 级 学 号 分工系数 二、实验内容

1、系统基本原理(实验原理介绍)

根据实验要求,温度闭环控制,即对加温速度、超调量、调节时间级误差参数,选择PID控制参数级算法,实现对温度的自动控制。

闭环温度控制系统原理图如下: 计算机PID 数字输出 温控 测温 2、PID算法的数字实现

本次试验通过8031通过OVEN 是模拟加热的装置,加一定的电压便开始不停的升温,直到电压要消失则开始降温。仿真时,U形加热器为红色时表示正在加热,发红时将直流电压放过来接,就会制冷,变绿。T端输出的是电压,温度越高,电压就越高。

8031对温度的控制是通过可控硅实现的。可控硅通过时间可以通过可控硅控制板上控制脉冲控制。该触发脉冲想8031用软件在P1.3引脚上产生,受过零同步脉冲后经光偶管和驱动器输送到可控硅的控制级上。偏差控制原理是要求对所需温度求出偏差值,然后对偏差值处理而获得控制信号去调节加热装置的温度。

PID控制方程式:

式中e是指测量值与给定值之间的偏差 TD 微分时间 T 积分时间

KP 调节器的放大系数

将上式离散化得到数字PID位置式算法,式中在位置算法的基础之上得到数字PID 增量式算法:

3、温度控制软件设计 程序结构图如下:

4、硬件电路设计

在温度控制中,经常采用是硬件电路主要有两大部分组成:模拟部分和数字部分,对这两部分调节仪表进行调节,但都存在着许多缺点,用单片机进行温度控制使构成的系统灵活,可靠性高,并可用软件对传感器信号进行抗干拢滤波和非线性补偿处理,可大大提高控制质量和自动化水平;总的来说本系统由四大模块组成,它们是输入模块、单片机系统模块、计算机显示与控制模块和输出控制模块。输入模块主要完成对温度信号的采集和转换工作,由温度传感器及其与单片机的接口部分组成。 利用模拟加热的装置来控制温度。

该闭环温度控制系统采用ATS51八位机作为微处理单元进行控制。采用4X4键盘把设定温度的最高值和最低值存入单片机的数据存储器,还可以通过键盘完成温度检测功能的转换。温度传感器把采集的信号与单片机里的数据相比较来控制温度控制器。

5、电路原理图 1、仿真完整电路图

2、12位AD转换模块

3、OVEN模型及信号调理电路

4、单片机主电路

三、实验结果分析(含程序、数据记录及分析和实验总结等,可附页): 1、51系列单片机闭环温度控制实验程序

Main.c

#include \"includes.h\" char measure_temperature[6] {'+','0','0','0','C','\\0'}; char setting_temperature[6] {'0','1','0','0','C','\\0'};

char code_table[16] = {'7','8','9','T', '4','5','6','P', '1','2','3','I', '+','0','-','D'}; char Pv[6]={'P','0','9','0',' ','\\0'}; char Iv[6]={'I','0','0','0',' ','\\0'}; char Dv[6]={'D','0','0','5',' ','\\0'}; int PWM_Period = 100; int PWM_Hight = 1; int PWM_Hights = 50; short m_temperature = 0; short s_temperature = 100; float pc = 090.0; float ic = 0.0; float dc = 5.0; float e1 = 0; float e2 = 0;

PWM.c

#include \"includes.h\"

uchar T_update = 0; uchar P_update = 0; uchar I_update = 0; uchar D_update = 0;

void T0_time() interrupt 1 //PWM

{ PWM_Hights--; if(PWM_Hights == 0) { PWM_EN = 0; PWM_Hights = 1; }

char RX_Data[5] = {0}; =

int main() =

{ 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); } return 0;

PWM_Period--; if(PWM_Period == 0) { PWM_EN = 1; PWM_Period = 100; PWM_Hights = PWM_Hight; } }

void pid() { static long sum = 0; e2 = e1;

e1 = s_temperature-m_temperature; sum += e1; if(e1 > 20) { PWM_Hight = 100; } else if(e1 < -20) { PWM_Hight = 1; } else { PWM_Hight = PWM_Hight+ pc*(e1+ic*sum+dc*(e1-e2)); } if(PWM_Hight > 100) PWM_Hight = 100; else if(PWM_Hight < 1) PWM_Hight = 1; }

void Interrupt_T1() interrupt 3 { static int count = 0; TH1 = 0x3C;//定时50ms TL1 = 0xB0; count++; if(count == 20) { pid(); count = 0; } }

void update_Temp() { short j = 0; short tmp = 0; for(j = 1;j<=3;j++) { tmp = tmp*10+(setting_temperature[j]-'0'); } if(setting_temperature[0] == '-')

tmp = -tmp; s_temperature = tmp; }

void update_Pv() { short j = 0; short tmp = 0; for(j = 1;j<=3;j++) { tmp = tmp*10+(Pv[j]-'0'); } pc = tmp; }

void update_Iv() { short j = 0; short tmp = 0; for(j = 1;j<=3;j++) { tmp = tmp*10+(Iv[j]-'0'); } ic = tmp; }

void update_Dv() { short j = 0; short tmp = 0; for(j = 1;j<=3;j++) { tmp = tmp*10+(Dv[j]-'0'); } dc = tmp; }

void Data_update() //循环检查每一次T、PID值是否有修改 { if(T_update == 1) { update_Temp(); T_update =0; } else if(P_update == 1)

{

update_Pv(); P_update =0; }

else if(I_update == 1) {

update_Iv(); I_update =0;

Timer.c

#include \"includes.h\" void timer_init() { EA = 0;//关闭总中断 ET0 = 1;//ET0用于PWM产生 ET1 = 1;//ET1测速计时 TMOD = 0x12;//T0:工作方式2 工作方式1 TH0 = 0x9C;

ADS7824.c

#include \"includes.h\"

void itoa(short num,char str[]) { int i=3; num = (num/2047.0)*999.0; for(i=3; i>0; i--) { str[i] = (num % 10) + '0'; num = num / 10; } str[5] = '\\0'; }

void ADCRead() { short num = 0;//无符号16位 RC = 0;//启动转换

}

else if(D_update == 1) { update_Dv(); D_update =0; }

}

TL0 = 0x9C;

TH1 = 0x3C;//定时50ms TL1 = 0xB0;

TR0 = 1;//运行定时器0 TR1 = 1;//运行定时器1 PT0 = 1; //T0中断优先级高 T1: EA = 1; //打开总中断

}

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; }

Delay.c

#include \"includes.h\"

void delay_ms(int n)//1ms延时 { uint i=0,j=0; for(i=0;iDisplay.c

#include \"includes.h\"

void lcd_wcom(uchar com) //1602 写命令函数 单片机给 1602 写命令 { rs=0; //选择指令寄存器 rw=0; //选择写 P0=com; //把命令字送入 delay_ms(1); en=1; //使能线电平变化, 命令送入 1602 的 8 位数据口 delay_ms(1); en=0; }

void lcd_wdat(uchar dat) //1602 写数据函数 { rs=1; //选择数据寄存器 rw=0; //选择写 P0=dat; //把要显示的数据送入 delay_ms(1); en=1; //使能线电平变化, 数据送入 1602 的 8 位数据口 delay_ms(1);

itoa(num,measure_temperature);

LCD_Display(0x80,measure_temperature); RC = 0; }

en=0;

}

void LCD_Display(uint location, uchar Display_Part[]) { int i=0; lcd_wcom(location); for(i=0;Display_Part[i] != 0;i++) { lcd_wdat(Display_Part[i]); delay_ms(1); } }

void lcd_init() //1602 初始化函数 { lcd_wcom(0x38); //8 位数据, 双列, 5*7 字形 lcd_wcom(0x0c); //开启显示屏, 关光标, 光标不闪烁 lcd_wcom(0x06); //显示地址递增, 即写一个数据后, 显示位置右移一位 lcd_wcom(0x01); //清屏

LCD_Display(0x80+0x08,setting_temperature); Keyboard.c

#include \"includes.h\" void keyscan() { uint keyno = 16; uchar temp = 0; uchar i = 0; static char update_flag = 0; static int update_index = 0; char key_code = 0; P3 = 0x0F; if(P3 != 0x0F) { P3 = 0x0F; //delay_ms(1); temp = P3; i = temp^0x0F; switch(i) { case 1: keyno = 0;break; case 2: keyno = 1;break; case 4: keyno = 2;break; case 8: keyno = 3;break; default: keyno = 16; //无键按下 } P3 = 0xF0; temp = P3; //delay_ms(1); i = (temp >> 4) ^ 0x0F; switch(i) { case 1: keyno += 0;break; case 2: keyno += 4;break; case 4: keyno += 8;break; case 8: keyno += 12;break; } LCD_Display(0x80+0x40,Pv); LCD_Display(0x80+0x45,Iv); LCD_Display(0x80+0x4A,Dv);

}

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; } } else if(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; } } else if(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; } } else if(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; 2、实验结果

1;break; 2;break; 3;break; 4;break; 0; } }

D_update = 1; } } else {

switch(keyno) { case 3:update_flag =

case 7:update_flag = case 11:update_flag = case 15:update_flag = default:update_flag =

} }

100度设定温度仿真结果

零下25度设定温度仿真结果

3、实验总结

温度控制广泛应用于人们的生产和生活中,人们使用温度计来采集温度,通过人工操51系列单片机直流电机闭环调速实验劳动强度大。即使有些用户采用半导体二极管作温度传感器,但由于其互换性差,效果也不理想。在某些行业中对温度的要求较高,由于工作环境温度不合理而引发的事故时有发生。对工业生产可靠进行造成影响,甚至操作人员的安全。为了避免这些缺点,需要在某些特定的环境里安装数字温度测量及控制设备。在工业生产和日常生活中,对温度控制系统的要求,主要是保证温度在一定温度范围内变化,稳定性好,不振荡,对系统的快速要求不高。在报告中中简单分析了温度控制系统基于Protuse仿真实验,采用热电偶作为温度检测器,应用LED显示,通过键盘4X4来对PID进行参数控制。

本实验设计使用8031作为主芯片进行控制,单片机具有集成度高,通用性好,功能强,特别是体积小,重量轻,耗能低,可靠性高,抗干扰能力强和使用方便等独特优点,在数字、智能化方面有广泛用途。其温度控制所用的热电偶,范围广泛,在系统中如果加强算法,会大大提高控制精度,同时降低成本,提高效率。

经过这次的实验,我们通过小组合作分工完成了本次实验,又一次加深了对LED的认识和加强了对keil以及Protues等软件的使用技能。在实验过程中,我们都要足够细心有耐心,在调试程序的时候要细心的检查错误。在以后的学习中我们都要会学好理论知识,将理论与实践相结合,不断提高自己动手能力。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 7swz.com 版权所有 赣ICP备2024042798号-8

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务