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

     绩:           

重庆邮电大学

自动化学院综合实验报告

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

学生姓名:蒋运和                      

    级:0841004                    

    号:2010213316                  

同组人员:李海涛  陈超                  

指导教师:郭鹏                      

完成时间:201312                  


一、实验名称:

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

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

基本情况:

1. 学生姓名:

2.     号:

3.     级: 4. 同组其他成员:

二、实验内容(实验原理介绍)

1、系统基本原理

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

闭环温度控制系统原理如图:

 


2、PID算法的数字实现

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

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

PID控制方程式:

               

  

式中e是指测量值与给定值之间的偏差

TD 微分时间

T   积分时间

     

         

KP 调节器的放大系数

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

增量式算法:

       

            

3、硬件电路设计

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

程序结构图如下:

3、电路原理图


三、实验结果分析(含程序、数据记录及分析和实验总结等,可附页):

1、51系列单片机直流电机闭环调速实验程序

/*--------------------------------------------------------------------------

REG52.H

Header file for generic 80C52 and 80C32 microcontroller.

Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.

All rights reserved.

--------------------------------------------------------------------------*/

#ifndef __REG52_H__

#define __REG52_H__

/*  BYTE Registers  */

sfr P0    = 0x80;

sfr P1    = 0x90;

sfr P2    = 0xA0;

sfr P3    = 0xB0;

sfr PSW   = 0xD0;

sfr ACC   = 0xE0;

sfr B     = 0xF0;

sfr SP    = 0x81;

sfr DPL   = 0x82;

sfr DPH   = 0x83;

sfr PCON  = 0x87;

sfr TCON  = 0x88;

sfr TMOD  = 0x89;

sfr TL0   = 0x8A;

sfr TL1   = 0x8B;

sfr TH0   = 0x8C;

sfr TH1   = 0x8D;

sfr IE    = 0xA8;

sfr IP    = 0xB8;

sfr SCON  = 0x98;

sfr SBUF  = 0x99;

/*  8052 Extensions  */

sfr T2CON  = 0xC8;

sfr RCAP2L = 0xCA;

sfr RCAP2H = 0xCB;

sfr TL2    = 0xCC;

sfr TH2    = 0xCD;

/*  BIT Registers  */

/*  PSW  */

sbit CY    = PSW^7;

sbit AC    = PSW^6;

sbit F0    = PSW^5;

sbit RS1   = PSW^4;

sbit RS0   = PSW^3;

sbit OV    = PSW^2;

sbit P     = PSW^0; //8052 only

/*  TCON  */

sbit TF1   = TCON^7;

sbit TR1   = TCON^6;

sbit TF0   = TCON^5;

sbit TR0   = TCON^4;

sbit IE1   = TCON^3;

sbit IT1   = TCON^2;

sbit IE0   = TCON^1;

sbit IT0   = TCON^0;

/*  IE  */

sbit EA    = IE^7;

sbit ET2   = IE^5; //8052 only

sbit ES    = IE^4;

sbit ET1   = IE^3;

sbit EX1   = IE^2;

sbit ET0   = IE^1;

sbit EX0   = IE^0;

/*  IP  */

sbit PT2   = IP^5;

sbit PS    = IP^4;

sbit PT1   = IP^3;

sbit PX1   = IP^2;

sbit PT0   = IP^1;

sbit PX0   = IP^0;

/*  P3  */

sbit RD    = P3^7;

sbit WR    = P3^6;

sbit T1    = P3^5;

sbit T0    = P3^4;

sbit INT1  = P3^3;

sbit INT0  = P3^2;

sbit TXD   = P3^1;

sbit RXD   = P3^0;

/*  SCON  */

sbit SM0   = SCON^7;

sbit SM1   = SCON^6;

sbit SM2   = SCON^5;

sbit REN   = SCON^4;

sbit TB8   = SCON^3;

sbit RB8   = SCON^2;

sbit TI    = SCON^1;

sbit RI    = SCON^0;

/*  P1  */

sbit T2EX  = P1^1; // 8052 only

sbit T2    = P1^0; // 8052 only

            

/*  T2CON  */

sbit TF2    = T2CON^7;

sbit EXF2   = T2CON^6;

sbit RCLK   = T2CON^5;

sbit TCLK   = T2CON^4;

sbit EXEN2  = T2CON^3;

sbit TR2    = T2CON^2;

sbit C_T2   = T2CON^1;

sbit CP_RL2 = T2CON^0;

#endif

#ifndef WENDU_H_

#define WENDU_H_

#define u8 unsigned char

#define u16 unsigned int

#define PULSE 200

//////LCD///////

sbit RS = P2^5;

sbit RW = P2^6;

sbit EN = P2^7;

sbit LED = P3^0;

sbit ENA = P3^7;

sbit IN2 = P3^6;

sbit IN1 = P3^5;

void delay_ms(u16 z);

void LCD_WriteData(u8 Dat);

void LCD_WriteCOM(u8 com);

void Show_Num(u8 x,u8 y,u8 n,u16 num);     //n为数字长度   num小于等于65535

void Show_fNum(u8 x,u8 y,u16 num);

void LCD_Init(void);

void key_scan(void);

//void key_scan(void);

extern u16 read_tlc2543(u8 port);

#endif

#ifndef TLC2543_H_

#define TLC2543_H_

//////TLC2543////

sbit SDO = P2^0;

sbit SDI = P2^1;

sbit CS  = P2^2;

sbit CLK = P2^3;

sbit EOC = P2^4;

//u16 read_tlc2543(u8 port);

#define u8 unsigned char

#define u16 unsigned int

u16 read_tlc2543(u8 port);

u8 AD_deal(void);

 #endif

#include<reg52.h>

#include"tlc2543.h"

//#include"wendu.h"

void delay_us(u16 z)

{

    u16 i;

   for(i=z;i>0;i--);;

}

u16 read_tlc2543(u8 port)

{

   static u8 PORT = 0;

   u8 Temp,i,k=0;

   u16 AD_value=0;

   Temp = port;

   CS = 1;

   CLK = 0;

   delay_us(1);

   Temp<<=4;

   CS = 0;

     while(1)

         {

            for(i=0;i<8;i++)

             {

                 CLK = 0;

                 if(Temp&0x80)

                    SDI = 1;

                      else

                       SDI = 0;

                 

                     AD_value<<=1;

                  if(SDO)

                       AD_value |= 0x01;

      

                 CLK = 1;

                 delay_us(2);

                 Temp<<=1;

                }

           for(i=8;i<12;i++)

                {

                 CLK = 0;

      

                 AD_value<<=1;

                 if(SDO)

                   AD_value |= 0x01;

      

                 delay_us(2);

                 CLK = 1;

                }

            CLK = 0;

            CS = 1;

               if(PORT == port)

                  break;

                else

                   {

                          Temp = port;

                             Temp<<=4;

                             delay_us(2);

                             CS = 0;

                             //PORT = port;

                      }

                k++;

                if(k>2)

                 {

                   PORT = port;

                 }

         }

   return AD_value;

}

u8 AD_deal(void)

{

   u16 AD_value;

   u16 temp;

   float temp1;

   AD_value = read_tlc2543(0x00);

   temp1 =(AD_value*0.04069);

   temp =(u16)(temp1*10);

   if((temp%10)>4)

     temp = temp/10+1;

       else

        temp = temp/10;

       temp = (u8)temp;

        return temp;

}

#include<reg52.h>

#include"wendu.h"

#include"tlc2543.h"

u8 S_Temp=100;  //设置温度

u8 P_Temp=25;   //实际温度

u8 pulse = 0;

u8 Kp=30,Ki=0;Kd=10;

int uk=0;

int num=0;

struct FLAG

{

   u8 turn;

}

myflag;

/*************

函数功能:延时

****************/

void delay_ms(u16 z)

{

   u16 i;

   u8 j;

   for(i=z;i>0;i--)

     for(j=120;j>0;j--);                                                                 

}

/*************

函数功能:LCD写数据

****************/

void LCD_WriteData(u8 Dat)

{

   RS = 1;

  // delay_ms(5);

   P1 = Dat;

   EN = 1;

   delay_ms(5);

   EN = 0;

}

/*************

函数功能:LCD命令

****************/

void LCD_WriteCOM(u8 com)

{

   RS = 0;

  // delay_ms(5);

   P1 = com;

   EN = 1;

   delay_ms(5);

   EN = 0;

}

/*************

函数功能:Show_Num初始化

****************/

void Show_Num(u8 x,u8 y,u8 n,u16 num)      //n为数字长度   num小于等于65535

{

   u16 Temp=num;

   u8 a[5],i;

   for(i=0;i<n;i++)

     {

          a[i] = Temp%10;

          Temp = Temp/10;

        }

 

   if(y%2 == 1)

          LCD_WriteCOM(0x80+x);

        else

          LCD_WriteCOM(0x80+0x40+x);

       for(i=n;i>0;i--)

       LCD_WriteData(a[i-1]+0x30); 

}

/*************

函数功能:Show_fNum初始化 

****************/

void Show_fNum(u8 x,u8 y,u16 num)

{

   u8 a,b;

   a = num/10%10;

   b = num%10;

   if(y%2 == 1)

          LCD_WriteCOM(0x80+x);

        else

          LCD_WriteCOM(0x80+0x40+x);

   LCD_WriteData(a+0x30); 

   LCD_WriteData(b+0x30);

}

/*************

函数功能:Show_Num初始化

****************/

void Show_char(u8 x,u8 y,u8 ch)

{

   if(y%2 == 1)

          LCD_WriteCOM(0x80+x);

        else

          LCD_WriteCOM(0x80+0x40+x);

   LCD_WriteData(ch); 

}

/*************

函数功能:LCD初始化

****************/

void LCD_Init(void)

{

   RW = 0;

   EN = 0;

   //delay_ms(20);

   LCD_WriteCOM(0x38);

   LCD_WriteCOM(0x0c);

   LCD_WriteCOM(0x06);

   LCD_WriteCOM(0x01);

}

/*************

函数功能:LCD初始化

****************/

void LCD_display(void)

{

   Show_char(0,1,'P');

   Show_char(1,1,'T');

   Show_char(2,1,':');

   Show_char(9,1,'S');

   Show_char(10,1,'T');

   Show_char(11,1,':');

   Show_Num(12,1,3,S_Temp);

   Show_char(0,2,'P');

   Show_char(1,2,':');

   Show_Num(2,2,2,Kp);

   Show_char(5,2,'I');

   Show_char(6,2,':');

   Show_Num(7,2,2,Ki);

   Show_char(10,2,'D');

   Show_char(11,2,':');

   Show_Num(12,2,2,Kd);

}

/*************

函数功能:定时器2初始化

****************/

void timer2_init()

{

  RCAP2H =(65536-100)/256;    //100us

  RCAP2L =(65536-100)%256;

  TH2 = RCAP2H;

  TL2 = RCAP2L;

  ET2 = 1;

  TR2 = 1;

  EA = 1;

}

void Temp_crl()

{

   static int ess[3]={0};

   static sum = 0;

   ess[0]=S_Temp-P_Temp;

   uk=Kp*ess[0]+Ki*sum+Kd*(ess[0]-ess[1]);

   ess[2]=ess[1];

   ess[1]=ess[0];

   sum = sum+ess[0];

   uk=(int)(uk/10);

   if(uk>=0)

     {

           if(uk>=200)

                uk = 199;

              myflag.turn = 1;

        }

        else

         {

           uk=-uk;

            if(uk>=200)

                uk = 199;

              myflag.turn = 0;

         }

       pulse = uk;

}

 int main(void)

  {

     u16 AD_value1=0;

        myflag.turn=0;

        ENA = 1;

        LCD_Init();

        LCD_display();

        timer2_init();

        while(1)

         {

           AD_value1 = read_tlc2543(0);

            P_Temp = AD_deal();

              Temp_crl();

              Show_Num(3,1,3,P_Temp);

           key_scan();

        

         }

     return  0;    

  }

void timer2() interrupt 5

{

   static u16 num1=0;

    TF2 = 0;

    num1++;

   if(num1<pulse)

      {

           if(myflag.turn)

               {

            IN1 = 0;

                     IN2 = 1;

               }

               else

               {

                  IN1 = 1;

                     IN2 = 0;

               }

         }

       else

         {ENA=0;IN1=0;IN2=0;}

   if(num1>=PULSE)

         {num1=0;ENA=1;} 

}

void key_scan(void)

{

   u8 Temp=P0;

   static u8 Add_Ver=0,one_ten=0;

   static Tri=0,CON=0;

   Temp = Temp^0xff;

   Tri = Temp&(Temp^CON);

   CON = Temp;

   if(Tri==0x10)

     {Add_Ver++;Add_Ver=Add_Ver%2;}

   else if(Tri==0x20)

     {one_ten++;one_ten=one_ten%2;}

   else if(Tri==0x01)

      {

           if(S_Temp+1<=120&&Add_Ver==0&&one_ten==0)

                 S_Temp++;

              else if(S_Temp>=1&&Add_Ver==1&&one_ten==0)

                 S_Temp--;

              else if(S_Temp+10<=100&&Add_Ver==0&&one_ten==1)

                 S_Temp=S_Temp+10;

           else if(S_Temp>=10&&Add_Ver==1&&one_ten==1)

                 S_Temp=S_Temp-10;

               Show_Num(12,1,3,S_Temp);

         }

   else if(Tri==0x02)

      {

           if(Kp+1<=100&&Add_Ver==0&&one_ten==0)

                   Kp++;

              else if(Kp>=1&&Add_Ver==1&&one_ten==0)

                   Kp--;

              else if(Kp+10<=100&&Add_Ver==0&&one_ten==1)

                   Kp=Kp+10;

           else if(Kp>=10&&Add_Ver==1&&one_ten==1)

                   Kp=Kp-10;

           Show_Num(2,2,2,Kp); 

         }

        else if(Tri==0x04)

      {

           if(Ki+1<=100&&Add_Ver==0&&one_ten==0)

                   Ki++;

              else if(Ki>=1&&Add_Ver==1&&one_ten==0)

                   Ki--;

              else if(Ki+10<=100&&Add_Ver==0&&one_ten==1)

                   Ki=Ki+10;

           else if(Ki>=10&&Add_Ver==1&&one_ten==1)

                   Ki=Ki-10;

              Show_Num(7,2,2,Ki);  

         }

         else if(Tri==0x08)

      {

           if(Kd+1<=100&&Add_Ver==0&&one_ten==0)

                   Kd++;

              else if(Kd>=1&&Add_Ver==1&&one_ten==0)

                   Kd--;

              else if(Kd+10<=100&&Add_Ver==0&&one_ten==1)

                   Kd=Kd+10;

           else if(Kd>=10&&Add_Ver==1&&one_ten==1)

                   Kd=Kd-10;

              Show_Num(12,2,2,Kd);

         }

}


2、程序分析结果

3、结论分析

在工业生产和日常生活中,对温度控制系统的要求,主要是保证温度在一定温度范围内变化,稳定性好,不振荡,对系统的快速要求不高。在论文中简单分析了温度控制系统基于Protuse仿真实验,采用热电偶作为温度检测器,应用LED显示,通过键盘4X4来对PID进行参数控制。

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

实验总结

    经过这次的实验,我又一次加深了对LED的认识和加强了对keil以及Protues等软件的使用技能。虽然之前做过很多的实验,但是自己任然存在很大的问题。在本次实验中任然有很多东西不会,所以又重新学了一遍单片机,加大了对单片机学习的兴趣。刚开始做实验时是很盲目的,胡乱的查资料。所以经过这次的实验我明白了做任何事之前都得有充分的准备和必要的预习。遇到困难是不可避免的,所以我们要做好随时挑战困难的准备,和同学团结,虚心请教老师,一起解决问题。做实验是需要耐心和信心的。比如在调试程序的时候要细心的检查错误。从这次的实验中我学会了把自己学的东西学以致用,学到了课本上没有的东西。很感谢学校,老师给我们这次锻炼的机会,在以后的学习中我会学好理论知识,将理论与实践相结合。不断提高自己动手能力。

     

相关推荐