|
基于单片机的炉温控制系统设计 摘要:随着生产水平的提高,热电设备对温度控制的要求也越来越高,而传感器技术和单片机技术等不断发展,为智能温度测控系统精度的提高和稳定性改善等提供了条件。本系统为以AT89S51单片机为核心的炉温控制系统。该系统在硬件设计上主要是通过温度传感器DS18B20对温度进行采集,直接输出数字式的温度值。AT89S51将采集到的数字温度送到LCD1602,以数字形式显示测量温度,并采用PID控制来实现对温度的调节。 关键词:单片机;温度传感器;PID控制
1.1 课题的目的与意义温度是生活及生产中最基本的物理量,自然界中任何物理、化学过程都与温度紧密联系。随着现代工业水平的逐步提高,温度控制在工业生产中显得越来越重要。在许多工业领域,都需要对各种热处理炉、加热炉、反应炉和锅炉进行控制,如轧钢工业需要对钢坯进行前加热,塑料的定型、高精度模具制造,机床制造,量具等高精密仪器、机器都要求环境温度管控。在这些领域对温度的控制至关重要,温度过低,达不到工艺的要求。温度过高,不仅影响品质,还会产生不必要的能源浪费,甚至可能有爆炸的危险。 不同领域对于温度的高低范围、测温元件、控制精度都不尽相同。一致的是现场一般都会比较复杂,有的人无法靠近,有的不需要人来现场监测。总的来说温度控制复杂多样,所以设计一个较为通用的温度控制系统具有重要意义。众所周知,加热炉是一个具有强耦合性、强非线性、大滞后、时变等特点的典型的复杂工业被控对象,用传统的控制方法对其进行控制很难取得满意的控制效果。随着传感器技术和单片机技术等不断发展,为智能温度测控系统精度的提高和稳定性改善等提供了条件,并得到日益发展和完善。 1.2 课题发展现状和前景展望由于工业过程控制的需要,特别是微电子技术和计算机技术的迅猛发展以及自动控制理论和设计方法发展的推动下,国外温度测控系统发展迅速,尤其是控制方面,在智能化、自适应、参数自整定等方面取得显著成果。在这方面,以日本、美国、德国、瑞典等国家技术领先,都生产出了一批商品化、性能优异的温度控制仪表,并在各行业广泛应用。 其特点是适应于大惯性、大滞后等复杂温度测控系统,具有参数自整定功能和自学习功能,即温控器对控制对象、控制参数及特性进行自动整定,并根据历史经验及控制对象的变化情况,自动调整相关控制参数,以保证控制效果的最优化。温度控制系统具有控制精度高、抗干扰力强等特点。目前,国外温度控制仪表正朝着高精度、智能化、小型化等方向发展。 微处理技术的发展和数字智能式控制器的实际应用,在控制领域出现的一系列新的技术课题之一的被控对象动静态参数、控制系统结构、参数发生较大范围变化的情况下,控制系统仍能满足给定的品质指标,这是自适应控制的最基本特征, 自适应PID 控制可以在线不断整定参数,克服干扰,跟踪系统的时变特性,使控制对象达到一定的目标。同时,随着现代控制理论(诸如智能控制、自适应模糊控制和神经网络技术等)研究和应用的发展与深入,为控制复杂无规则系统开辟了新途径,逐步弱化或取消了对受控对象数学模型结构不变的限制。 随着社会需要和技术发展,优化算法的种类会越来越多并越来越完善,也会有越来越多的优化算法被提出并在不同的应用场合中出现,其优越性也会越来越明显,在目前的研究中,只有几种基本的和改进的优化算法在炉温优化设定中应用。可以预见,在以后的研究工作中,将会有更多先进的优化算法应用于炉温的优化设定。智能控制的优越性、有效性已经无法被取代,它已经成为现在控制技术的主要手段和方法,并且可以与其他多种控制方法进行结合,在炉温控制中,主要是采用智能控制方法或智能控制与其他方法相结合。随着计算机的普及及计算机性能的提高,计算机控制也逐渐发展并完善起来,智能控制技术与计算机控制技术相结合已经成为一种趋势,也是加热炉控制方法的一种趋势! 1.3 课题主要内容
本次设计总体叙述了基于单片机对工业生产中温度的控制与设计,包括硬件组成和软件的设计,该系统在硬件设计上主要分为温度采集和温度控制两部分。以AT89S51单片机为核心器件,通过温度传感器DS18B20对温度进行采集,DS18B20将采集到的温度信号直接以数字形式输入给单片机,然后单片机再将将采集到的数字温度送到显示器LCD1602,以数字形式显示测量的温度。温度控制部分主要是以PID控制进行温度的调节,将采集到的温度和设定温度进行PID运算,单片机通过其输出量控制可控硅调控器的接通时间,来调节温度的。整个系统的软件编程对单片机实现其控制功能。整个系统简单可靠,操作灵活,性能价格比高,较好的满足了现代生产和科研的需要。
系统总体方案 系统设计要求:以MCS-51单片机为核心,设计一个炉温控制系统。 1) 采用液晶显示器显示温度测量值。 2) 检测的温度范围为0~128℃。 3) 温度超过警戒值时能报警提示。 4) 能通过键盘输入设定温度并显示。 5) 用PID控制温度,控温精度≦±2℃。 根据要求,以电炉为控制对象,单片机AT89S51为核心器件。该温度控制系统按功能分主要包括了显示模块、温度调节模块、键盘模块、报警模块。温度传感器采用数字式温度传感器DS18B20,对温度进行实时采样,并将模拟信号转换成数字信号返回给单片机,通过LCD1602显示。系统可通过键盘设定温度,单片机根据当前炉内温度和预设温度进行计算,通过控制双向可晶闸管的通断来调节炉内温度。当温度一旦超出设定范围,报警模块就会工作。借助KeilC51开发工具,以C语言开发语言,分别编写程序实现对各模块的控制。最后以Proteus为基础,画出系统电路图,加载程序模拟实际电路的运行进行仿真并调试。系统总体结构框架如图2.1。 图2.1系统结构框图 2.2 单片机的选择 目前我国最常用的单片机有Intel公司的MCS-51系列,MCS-96系列(16位);Philips公司的87、80系列(51内核)、AVR系列;Microchip公司的PIC系列;ATMEL公司的89系列(51内核)等;其中ATMEL公司所产的ATMEL89系列的单片机是基于Intel公司的MCS-51系列而研制的。ATMEL公司把自身的先进的Flash存储器技术和80C31核心相结合。从而产生出了Flash单片机系列。 根据初步设计方案分析,应选择具有以下功能的单片机: 1) 片内有Flash ROM的单片机,可以反复的烧录、擦除程序,应用程序直接存储在片内,不用再扩展存储器,可以简化电路。Philips80C51系列单片机、ATMEL公司的AT89系列单片机和AVR的单片机、STC单片机、PIC单片机均带有片内Flash ROM。 2)支持在线可编程(ISP)的单片机,在单片机开发开发过程中,编程器是必不可少的。选用具有ISP技术的单片机,只要通过一条下载线与计算机相连就可以直接将程序烧录到内部,不但可以方便,还省去了昂贵的编程器。带ISP的单片机主要有:ATMEL公司的AT89S5x系列、AVR;Microchip公司的带8为的PIC单片机,结尾不带e的pic24系列和dsPIC系列;飞思卡尔的所有STC系列单片机;意法半导体的SST系列单片机。
除了上述基本要求外,还要尽可能的降低成本。由于系统控制方案简单 ,数据量不大 ,经分析对比本系统选用AT89S51单片机。A T89S51芯片内含有4 kB的 E2PROM ,无需外扩存储器 ,电路简单可靠 ,其时钟频率为 0~24 MHz ,并且价格低廉 ,批量价在 10元以内。
- #include<reg52.h>
- #include<math.h>
- float R;
- float Kp;
- float T;
- float Ti;
- float Td;
- float e2;
- float e1,e;
- float a0,a1,a2;
- #define ui unsigned int
- #define uc unsigned char
- sbit bj=P2^4; //低电平报警模块工作
- sbit lcden=P2^7; //LCD E
- sbit lcdrs=P2^6; //LCD RS
- sbit lcdrw=P2^5; // //LCD RW
- sbit control=P2^3; //加热模块相关。低电平启动
- char lshi,lge,hshi,hge;
- uc num,flag;
- ui temp;
- sbit dsio=P3^7; //DS18B20输入口
- //延时
- void delay(ui z)
- {
- uc x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- //DS18B20控制
- void dsinit()
- {
- uc i;
- dsio=0;
- i=70;
- while(i--);
- dsio=1;
- i=4;
- while(i--);
- }
- void dswritebyte(uc dat)
- {
- uc i,j;
- for(j=0;j<8;j++)
- {
- dsio=0;
- i++;
- dsio=dat&0x01;
- i=6;
- while(i--);
- dsio=1;
- dat>>=1;
- }
- }
- uc dsreadbyte()
- {
- uc i,j,byte,b;
- for(j=0;j<8;j++)
- {
- dsio=0;
- i++;
- dsio=1;
- i++;i++;
- b=dsio;
- byte=(byte>>1)|(b<<7);
- i=4;
- while(i--);
- }
- return byte;
- }
- void dschangetemp()
- {
- dsinit();
- delay(1);
- dswritebyte(0xcc);
- dswritebyte(0x44);
- }
- void dsreadtemp()
- {
- dsinit();
- delay(1);
- dswritebyte(0xcc);
- dswritebyte(0xbe);
- }
- ui gettemp()
- {
- int temp;
- uc h,l;
- dschangetemp();
- dsreadtemp();
- l=dsreadbyte();
- h=dsreadbyte();
- temp=h;
- temp<<=8;
- temp|=l;
- temp=temp*0.0625*100+0.5;
- return temp;
- }
- //LCD控制程序
- void lcdwritecom(uc com)
- {
- lcdrs=0;
- P0=com;
- delay(10);
- lcden=1;
- delay(10);
- lcden=0;
- }
- void lcdwritedata(uc date)
- {
- lcdrs=1;
- P0=date;
- delay(10);
- lcden=1;
- delay(10);
- lcden=0;
- }
- void lcdinit()
- {
- lcdrw=0;
- lcden=0;
- lcdwritecom(0x38);
- lcdwritecom(0x0c);
- lcdwritecom(0x06);
- lcdwritecom(0x01);
- }
- //LCD显示
- void lcddisplay(int temp)
- {
- ui tab[]={0,0,0,-2,0,0};
- lcdwritecom(0x80);
- lcdwritedata('+');
- tab[0]=temp/10000;
- tab[1]=temp%10000/1000;
- tab[2]=temp%1000/100;
- tab[4]=temp%100/10;
- tab[5]=temp%10;
- lcdwritecom(0x81);
- for(num=0;num<6;num++)
- {
- lcdwritedata('0'+tab[num]);
- }
- }
- void adjust()
- {
- delay(100);
- flag++;
- if(flag==5)flag=1;
- if(flag==1)
- {
- lcdwritecom(0x80+0x44);
- lcdwritecom(0x0f);
- }
- if(flag==2)
- {
- lcdwritecom(0x80+0x45);
- lcdwritecom(0x0f);
- }
- if(flag==3)
- {
- lcdwritecom(0x80+0x47);
- lcdwritecom(0x0f);
- }
- if(flag==4)
- {
- lcdwritecom(0x80+0x48);
- lcdwritecom(0x0f);
- }
- }
- void inc()
- {
- delay(100);
- switch(flag)
- {
- case 1:lshi++; if(lshi==10)lshi=0;
- lcdwritedata('0'+lshi);
- lcdwritecom(0x10);
- break;
- case 2:lge++; if(lge==10)lge=0;
- lcdwritedata('0'+lge);
- lcdwritecom(0x10);
- break;
- case 3:hshi++; if(hshi==10)hshi=0;
- lcdwritedata('0'+hshi);
- lcdwritecom(0x10);
- break;
- case 4:hge++; if(hge==10)hge=0;
- lcdwritedata('0'+hge);
- lcdwritecom(0x10);
- break;
- }
- }
- void dec()
- {
- delay(100);
- switch(flag)
- {
- case 1:lshi--; if(lshi<0)lshi=9;
- lcdwritedata('0'+lshi);
- lcdwritecom(0x10);
- break;
- case 2:lge--; if(lge<0)lge=9;
- lcdwritedata('0'+lge);
- lcdwritecom(0x10);
- break;
- case 3:hshi--; if(hshi<0)hshi=9;
- lcdwritedata('0'+hshi);
- lcdwritecom(0x10);
- break;
- case 4:hge--; if(hge<0)hge=9;
- lcdwritedata('0'+hge);
- lcdwritecom(0x10);
- break;
- }
- }
- //键盘扫描
- void keyscan()
- {
- uc test,num;
- num=0;
- test=P1;
- if(test!=0xff)
- delay(5);
- test=P1;
- if(test==0xf7)
-
- {
- while(P1!=0xff);
- num++;
- while(1)
- {
- test=P1;
- if(test!=0xff)
- delay(5);
- test=P1;
- if(test!=0xff)
- {
- if(test==0xf7)
- num++;
- if(num==2)
- { lcdwritecom(0x0c);
- break;}
- switch(test)
- {
- case 0xfe:adjust();
- break;
- case 0xfd:inc();
- break;
- case 0xfb:dec();
- break;
- }
- }
- while(P1!=0xff);
-
- }
- }
- }
- //PID
- void PIDinit()
- {
-
- Kp=2;Ti=4;Td=1;T=1;R=25;
- a0=Kp*(1+T/Ti+Td/T);
- a1=-Kp*(1+(2*Td)/T);
- a2=Kp*(Td/T);
- e2=e1=0;
- }
- void PIDdeal()
- {
- float y ,u ;
- y=gettemp();
- e=y/100-R;
- u=a0*e+a1*e1+a2*e2;
- e2=e1;e1=e;
- if(u>0.5||u<-0.5)
- control=0;
- else control=1;
- }
- void main()
- {
- uc code tab2[]="SET:20~80C";
- uc i;
- TMOD=0x01;
- TH0=(65535-10900)/256;
- TL0=(65535-10900)%256;
- ET0=1;
- TR0=1;
- lcdinit();
- lcdwritecom(0x87);
- lcdwritedata('C');
- lcdwritecom(0x80+0x40);
- for(i=0;i<10;i++)
- lcdwritedata(tab2[i]) ;
- lshi=2;lge=0;hshi=5;hge=0;
- while(1)
- {
- lcddisplay(gettemp());
- keyscan() ;
- EA=1; while(1);
- }
- }
- void t0() interrupt 1
- {
- uc i;
- TH0=(65535-10900)/256;
- TL0=(65535-10900)%256;
- i++;
- if(i==100)
- {
- void PIDinit();
- void PIDdeal();
- }
- }
复制代码
|