成绩:综合实验报告题目:51系列单片机闭环温度控制班级:小组成员:指导教师:完成时间:2015年11月一、实验名称:51系列单片机闭环温度控制实验——基于Protuse仿真实验平台实现基本情况:1.实验项目组长:2. 小组成员:3.具体分工:负责程序编写,主要负责查询资料与实验报告撰写。
4.实验要求:①设计硬件电路:温度检测:采用热电偶或热电阻温度给定:采用电位器进行模拟电压给定,0——5VAD转采用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、硬件电路设计在温度控制中,经常采用是硬件电路主要有两大部分组成:模拟部分和数字部分,对这两部分调节仪表进行调节,但都存在着许多缺点,用单片机进行温度控制使构成的系统灵活,可靠性高,并可用软件对传感器信号进行抗干拢滤波和非线性补偿处理,可大大提高控制质量和自动化水平;总的来说本系统由四大模块组成,它们是输入模块、单片机系统模块、计算机显示与控制模块和输出控制模块。
输入模块主要完成对温度信号的采集和转换工作,由温度传感器及其与单片机的接口部分组成。
利用模拟加热的装置来控制温度。
该闭环温度控制系统采用AT89S51八位机作为微处理单元进行控制。
采用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; char RX_Data[5] = {0};int main(){timer_init();lcd_init();while(1){ADCRead();keyscan();Data_update();LCD_Display(0x80+0x08,setting_temp erature);LCD_Display(0x80+0x40,Pv);LCD_Display(0x80+0x45,Iv);LCD_Display(0x80+0x4A,Dv);}return 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;}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;//定时50msTL1 = 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;}else if(D_update == 1){update_Dv();D_update =0;}}Timer.c#include "includes.h"void timer_init(){EA = 0;//关闭总中断ET0 = 1;//ET0用于PWM产生ET1 = 1;//ET1测速计时TMOD = 0x12;//T0:工作方式2 T1:工作方式1TH0 = 0x9C;TL0 = 0x9C;TH1 = 0x3C;//定时50msTL1 = 0xB0;TR0 = 1;//运行定时器0TR1 = 1;//运行定时器1PT0 = 1; //T0中断优先级高EA = 1; //打开总中断}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;//启动转换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_temperatu re);RC = 0;}Delay.c#include "includes.h"void delay_ms(int n)//1ms延时{uint i=0,j=0;for(i=0;i<n;i++)for(j=0;j<123;j++);}Display.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);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_temperatu re);LCD_Display(0x80+0x40,Pv);LCD_Display(0x80+0x45,Iv);LCD_Display(0x80+0x4A,Dv); }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;}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;D_update = 1;}}else{switch(keyno){case 3:update_flag = 1;break;case 7:update_flag = 2;break;case 11:update_flag = 3;break;case 15:update_flag = 4;break;default:update_flag = 0;}}}}2、实验结果100度设定温度仿真结果零下25度设定温度仿真结果3、实验总结温度控制广泛应用于人们的生产和生活中,人们使用温度计来采集温度,通过人工操51系列单片机直流电机闭环调速实验劳动强度大。