计算机控制课程实训之简易空调系统设计.docx
《计算机控制课程实训之简易空调系统设计.docx》由会员分享,可在线阅读,更多相关《计算机控制课程实训之简易空调系统设计.docx(28页珍藏版)》请在冰豆网上搜索。
计算机控制课程实训之简易空调系统设计
《空调控制系统设计》任务书
设计内容
设计一空调房间温度控制系统,该系统能准确测量房间温度,并根据设定温度进行有效控制。
空调设计变频空调制冷(热)量与压缩机转速有关,通过控制压缩机转速频率来控制所需热量。
空调模型相当于一个积分环节与一个惯性环节的串联。
房间模型主要考虑室内外温度干扰与散热片热量共同作用于具有初始温度房间,经空气导热延迟,简化为具有一阶惯性环节。
设房间热惯性时间常数
=450,空气导热延迟τ=35,选择合适的控制算法进行控制。
设计步骤
一、总体方案设计
二、控制系统的建模和数字控制器设计
三、硬件的设计和实现
1、选择计算机字长(选用51内核的单片机)
2、设计支持计算机工作的外围电路(EPROM、RAM、I/O端口、键盘、显示接口电路等);
3、设计输入信号接口电路;
4、设计信号输出控制电路;
5、其它相关电路的设计或方案(电源、通信等)。
四、软件设计
1、分配系统资源,编写系统初始化和主程序模块框图;
2、编写A/D转换和位置检测子程序框图;
3、编写控制程序和D/A转换控制子程序模块框图;
4、其它程序模块(显示与键盘等处理程序)框图。
五、编写课程设计说明书,绘制完整的系统电路图(A3幅面)。
摘 要:
本课程设计详细的阐述了基于51单片机构建了一个空调控制系统。
在明确影响室内温度参数情况下,利用PID算法结合检测控制方法并对传感器测量电路、控制器执行电路及软件系统进行了设计。
关键词:
空调模型51单片机PID
1.引言
随着科技发展,计算机控制技术在各个方面都起到了举足轻重的作用。
作为本学期的一门专业课,通过对《计算机控制系统》学习使我们对计算机系统有一个基本的了解并掌握常规控制算法的使用方法和掌握简单微型计算机应用系统软硬的设计方法。
2.设计任务
2.1设计内容
设计一空调房间温度控制系统,系统能够实现准确测量房间温度,并根据设定温度进行有效控制。
2.2设计要求
1总体方案设计
2硬件的设计和实现
3选择计算机字长(选用51内核的单片机)
4设计支持计算机工作的外围电路(EPROM、RAM、I/O端口、键盘、显示接口电路等);
5设计输入信号接口电路;
6设计信号输出控制电路;
7其它相关电路的设计或方案(电源、通信等)。
8分配系统资源,编写系统初始化和主程序模块框图;
9编写A/D转换和位置检测子程序框图;
10编写控制程序和D/A转换控制子程序模块框图;
11其它程序模块(显示与键盘等处理程序)框图。
12编写课程设计说明书,绘制完整的系统电路图(A3幅面)。
3.方案设计
3.1设计思路
依据上面要求,可将系统分为信息采集模块、控制模块、驱动模块、执行模块、显示模块,分别模拟房间空调系统的相应模型。
温度的调节范围为-40~40度,有450惯性环节,35延迟环节。
3.2方案的论证与比较
一、控制系统模块
用AT89C52芯片作为控制芯片,51内核。
1、AT89C52除了与AT89C51所有的定时/计数器0和定时/计数器1外,还增加了一个定时/计数器2。
定时器2是一个16位定时/计数器。
它既可当定时器使用,也可作为外部事件计数器使用,其工作方式由特殊功能寄
中断
2、AT89C52共有6个中断向量:
两个外中断(INT0和INT1),3个定时器中断(定时器0、1、2)和串行口中断。
所有这些中断源如图9所示。
这些中断源可通过分别设置专用寄存器IE的置位或清0来控制每一个中断的允许或禁止。
IE也有一个总禁止位EA,它能控制所有中断的允许或禁止。
二、信号采集与转换模块
1.温度传感器选择
方案一:
DS18B20传感器,其是8位,传感器,采集信号后可直接输出数字信号,使用方便。
方案二:
AD590作为温度传感器。
其需要进行AD转换。
但是由于老师希望我们通过训练了解AD转换过程,所以我就选择了方案二即AD590。
温度传感器AD590基本知识:
AD590产生的电流与绝对温度成正比,它可接收的工作电压为4V-30V,检测的温度范围为-55℃-+150℃,它有非常好的线性输出性能,温度每增加1℃,其电流增加1uA,AD590温度与电流的关系如表1所示。
摄氏温度
AD590电流
经10KΩ电压
0℃
273.2uA
2.732V
10℃
283.2uA
2.832V
20℃
293.2uA
2.932V
30℃
303.2uA
3.032V
40℃
313.2uA
3.132V
50℃
323.2uA
3.232V
60℃
333.2uA
3.332V
100℃
373.2uA
3.732V
表1
2.AD转换器的选择
因为正常的室温变化范围是-40--40度,理论上AD位数只要7位(128级)就了,所以系统采用了经典的ADC0809(8位AD)作为AD采样芯片。
ADC0809是带有8位A/D转换器、8路多路开关以及微处理机兼容的控制逻辑的CMOS组件。
它是逐次逼近式A/D转换器,可以和单片机直接接口。
a.ADC0809的内部逻辑结构
图5ADC0809内部原理
由图5可知,ADC0809由一个8路模拟开关、一个地址锁存与译码器、一个A/D转换器和一个三态输出锁存器组成。
多路开关可选通8个模拟通道,允许8路模拟量分时输入,共用A/D转换器进行转换。
三态输出锁器用于锁存A/D转换完的数字量,当OE端为高电平时,才可以从三态输出锁存器取走转换完的数据。
引脚结构:
IN0-IN7:
8条模拟量输入通道。
ADC0809对输入模拟量要求:
信号单极性,电压范围是0-5V,若信号太小,必须进行放大;地址输入和控制线:
4条。
ALE为地址锁存允许输入线,高电平有效。
当ALE线为高电平时,地址锁存与译码器将A,B,C三条地址线的地址信号进行锁存,经译码后被选中的通道的模拟量进转换器进行转换。
A,B和C为地址输入线,用于选通IN0-IN7上的一路模拟量输入。
通道选择表如表2所示。
C
B
A
选择的通道
0
0
0
IN0
0
0
1
IN1
0
1
0
IN2
0
1
1
IN3
1
0
0
IN4
1
0
1
IN5
1
1
0
IN6
1
1
1
IN7
表2
数字量输出及控制线:
11条。
ST为转换启动信号。
当ST上跳沿时,所有内部寄存器清零;下跳沿时,开始进行A/D转换;在转换期间,ST应保持低电平。
EOC为转换结束信号。
当EOC为高电平时,表明转换结束;否则,表明正在进行A/D转换。
OE为输出允许信号,用于控制三条输出锁存器向单片机输出转换得到的数据。
OE=1,输出转换得到的数据;OE=0,输出数据线呈高阻状态。
D7-D0为数字量输出线。
CLK为时钟输入信号线。
因ADC0809的内部没有时钟电路,所需时钟信号必须由外界提供,通常使用频率为500KHZ,VREF(+),VREF(-)为参考电压输入。
ADC0809应用说明
ADC0809内部带有输出锁存器,可以与AT89S51单片机直接相连。
初始化时,使ST和OE信号全为低电平。
送要转换的哪一通道的地址到A,B,C端口上。
在ST端给出一个至少有100ns宽的正脉冲信号。
是否转换完毕,我们根据EOC信号来判断。
当EOC变为高电平时,给OE为高电平,转换的数据就输出给单片机了。
二、驱动模块(uln2003)
ULN2003是高压大电流达林顿晶体管阵列系列产品,具有电流增益高、工作电压高、温度范围宽、带负载能力强等特点,适应于各类要求高速大功率驱动的系统。
ULN2003芯片引脚介绍
引脚1:
CPU脉冲输入端,端口对应一个信号输出端。
引脚2:
CPU脉冲输入端。
引脚3:
CPU脉冲输入端。
引脚4:
CPU脉冲输入端。
引脚5:
CPU脉冲输入端。
引脚6:
CPU脉冲输入端。
引脚7:
CPU脉冲输入端。
引脚8:
接地。
引脚9:
该脚是内部7个续流二极管负极的公共端,各二极管的正极分别接各达林顿管的集电极。
用于感性负载时,该脚接负载电源正极,实现续流作用。
如果该脚接地,实际上就是达林顿管的集电极对地接通。
引脚10:
脉冲信号输出端,对应7脚信号输入端。
引脚11:
脉冲信号输出端,对应6脚信号输入端。
引脚12:
脉冲信号输出端,对应5脚信号输入端。
引脚13:
脉冲信号输出端,对应4脚信号输入端。
引脚14:
脉冲信号输出端,对应3脚信号输入端。
引脚15:
脉冲信号输出端,对应2脚信号输入端。
引脚16:
脉冲信号输出端,对应1脚信号输入端。
可以利用,51或52单片机,作为系统控制中心;利用PID控制电机的转速;利用利用空调模型相当于一个积分环节与一个惯性环节的串联。
房间模型主要考虑室内外温度干扰与散热片热量共同作用于具有初始温度房间,经空气导热延迟,简化为具有一阶惯性环节。
三、显示模块
为了能够最大限度的把信息展现出来,我才用了使用的的是1602
它的读写操作、屏幕和光标的操作都是通过指令编程来实现的。
(说明:
1为高电平、0为低电平)
指令1:
清显示,指令码01H,光标复位到地址00H位置。
指令2:
光标复位,光标返回到地址00H。
指令3:
光标和显示模式设置I/D:
光标移动方向,高电平右移,低电平左移S:
屏幕上所有文字是否左移或者右移。
高电平表示有效,低电平则无效。
指令4:
显示开关控制。
D:
控制整体显示的开与关,高电平表示开显示,低电平表示关显示C:
控制光标的开与关,高电平表示有光标,低电平表示无光标B:
控制光标是否闪烁,高电平闪烁,低电平不闪烁。
指令5:
光标或显示移位S/C:
高电平时移动显示的文字,低电平时移动光标。
指令6:
功能设置命令DL:
高电平时为4位总线,低电平时为8位总线N:
低电平时为单行显示,高电平时双行显示F:
低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符。
指令7:
字符发生器RAM地址设置。
指令8:
DDRAM地址设置。
指令9:
读忙信号和光标地址BF:
为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。
指令10:
写数据。
指令11:
读数据。
液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。
要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,表3是DM-162的内部显示地址。
四、算法模块
本系统采用的是PID控制算法,通过房间的温度反馈,采用增量式PID算法,控制电机的运转的速度,从而控制房间的温度。
以下便是利用MATLAB仿真的PID算法。
1MATLAB仿真
图1MATLAB仿真
2仿真结果
图2MATLAB仿真结果
五、按键模块
利用独立按键即可。
4总体设计
4.1硬件系统框图
根据任务书可知,该系统需要人机界面(按键输入LCD1602显示),AD采样,以及单片机控制部分等模块,并且可以得到以下硬件系统框图
4.2各部分硬件的设计
1信息采集及A/D转换
采用AD590进行A/D转换。
由于在系统仿真过程中,无法对0809进行编程,而且不能够找出AD590这块芯片,所以我采用了0808代替了0809,并且使用了电压表和滑动电阻替代我们的AD590热源传感器。
P1口就是对应的数字量输出通道。
2电机及驱动模块
由于c52单片机是大负载驱动能力差,所以在实际情况下应该对电机安装驱动模块,但是在本次设计中简化了,并不采用驱动。
3显示部分采用的是1602液晶显示屏。
采用的是P0口为信号的通道,并且由P2.2—P2.3作为控制信号的通道。
4输出控制
设计使用LCD1602显示当前设定温度和实际测量温度,用两个LED指示当前空调状态(加热或制冷),51单片机的低电平驱动能力较强,LED可以直接连接单片机的I/O口;单片机输出PWM波控制压缩机的转速。
5按键选择模块
利用按钮开关对P3.0、P3.1口的按键检测,分别控制其温度的设定。
6硬件设计电路图
图9硬件原理图
5.软件设计
5.1工作模式分析
很简单,初始温度为28度。
根据用户需要可自行设定温度,以后环境温度高于设定值,系统制冷;低于设定值,系统制热;与设定值一致则保持。
5.2系统程序流程图
一、主程序流程图
主程序流程图
二、按键、中断等子程序流程图
5.3AD转化程序设计
(1)进行A/D转换之前,要启动转换的方法:
ABC=000选择第一通道。
ST=0,ST=1,ST=0产生启动转换的正脉冲信号
(2)进行A/D转换时,采用查询EOC的标志信号来检测A/D转换是否完毕,若完毕则把数据通过P1端口读入进行处理。
5.4PID算法设计
intPID(intsetT,intache)
{
floatp=5,i=1,d=0.5;
staticfloateun=0.0;staticfloaten=0.0,en1=0.0,en2=0.0;
staticintoutput=0.0,output1=50;
en=setT-ache;
en=p*en-i*(en-en1)+d*(en1-en2);
output=output1+(int)en;
output1=output;
en2=en1;
en1=en;
return(output);
6.学习心得及体会
“漫漫其修远兮,吾将上下而求索!
”经过很多次的熬夜大干最终完成课程实训之后不禁有“一番风雨路三千”感慨。
在设计中最难的部分不是程序编写,而是对PID算法的应用和对电机的控制。
此外,一开始自己设想在空调控制系统中再引入一个外部中断,其作用是可以使空调的温度控制快慢程度进入手动调节的环节,但最终还是没有实现(编程能力未达到)。
在此我就在整个设计过程中所遇到的问题进行归纳。
首先我当时是选择一个人完成整份报告的,原因是我希望通过这次的课程实训,好好地锻炼一下自己;其次本次课程实训的题目设置上与社会环境联系的比较紧密,贴近生活,给人一种社会生产设计的感觉。
在课程实训中可谓困难重重,首先遇到的问题是,空调房间控制系统的原理是什么,被控量是什么空调控制系通过怎么去构建?
其次是采用什么样的算法去实现?
如何实现MATLAB仿真?
说实话,对于算法这些问题,是我思考了很长时间才有眉目的事情。
然而造成这些问题的真正的原因是出于自己这么几年的学习都在浑浑噩噩中度过的,所以很多知识都不知道。
通过本次课程实践,似乎也是自己给自己一个提醒。
7.感谢
在本次设计中,我得到了丁健老师很大的帮助。
这段日子里,丁老师不仅提供给我相关的资料,而且还给了我充足的时间,虽然到了最后还没有完成自己预想的结果,但是我感觉自己学到了很多东西。
参考文献
【1】于海生编著计算机控制技术.北京:
机械工业出版社,2009。
【2】谭浩强著c语言程序设计.北京:
清华大学出版社,2003年。
【3】田良黄正谨著综合电子设计与实践.南京:
东南大学出版社,2003年。
【4】彭伟编著单片机C语言程序设计实训100例.西安:
电子工业出版社。
附录
#include
intPID(setup_t,achieve);//PID函数声明
voidLcd_WData(unsignedcharTempData);//LCD初始化子程序声明
voidLcd_WCmd(unsignedcharTempData,unsignedcharBuysC);
voidLcd_RStatus(void);
voidLcd_Init(void);
#defineADC_OUTP1//AD端口定义
sbitup=P3^0;
sbitdown=P3^1;
sbitsetT=P3^2;
sbitsetF=P3^3;
sbitmakeC=P2^0;
sbitmakeH=P2^1;
sbitPWM=P3^6;
unsignedcharLcd_ReadData(void);
voidDisplayString(unsignedcharX,unsignedcharY,unsignedchar*DData);
voidDisplayChar(unsignedcharX,unsignedcharY,unsignedcharDData);
voidDelay(unsignedintdelaytime);
sbitLcd_RS=P2^2;
sbitLcd_RW=P2^3;
sbitLcd_E=P2^4;
#defineLcd_DataP0LCD端口定义
sbitST=P2^5;
sbitCLK=P3^0;
sbitEOC=P2^6;
sbitOE=P2^7;
sbita=P3^7;
unsignedintpwmData,pwmCount;
intsetup_t=250;
unsignedcharT0count;
unsignedchartimecount;
bitflag;
unsignedlongx;
intachieve;
unsignedchartemp[8];
unsignedintADC0809();
voidsetup(unsignedchar);
voiddisplay(inttemp1,inttemp2);
unsignedcharkey_scan();
voidSysInit();
voidmeasure();
voidmain(void)
{
unsignedintcurrent_t;
unsignedcharkey;
SysInit();
Lcd_Init();
while
(1)
{
current_t=ADC0809();
key=key_scan();
setup(key);
measure();
display(current_t,setup_t);
}
}
voidmeasure()
{
if(flag==1)
{
flag=0;
x=T0count*65536+TH0*256+TL0;
timecount=0;
T0count=0;
TH0=0;
TL0=0;
TR0=1;
}
}
voidSysInit()
{EX0=1;
IT0=0;
EX1=1;
IT1=0;
ET0=1;
ET1=1;
EA=1;
TMOD=0x15;
TH1=(65536-3000)/256;
TL1=(65536-3000)%256;
TR1=1;
TR0=1;
}
unsignedcharkey_scan()
{
unsignedchartemp=0;
if(up==0){temp=1;while(!
setT);}
elseif(down==0){temp=2;while(!
setF);}
return(temp);
}
voidsetup(unsignedchart1)
{
if(t1==1)setup_t++;
if(t1==2)setup_t--;
}
voiddisplay(inttemp1,inttemp2)
{
unsignedchartable[3],tt[9];
Lcd_Init();
if(a==1)
{
table[2]=temp1%10;
table[1]=(temp1/10)%10;
table[0]=(temp1/100)%10;
DisplayString(0,1,"NOWTemp:
");
DisplayChar(10,1,table[0]+0x30);
DisplayChar(11,1,table[1]+0x30);
DisplayChar(12,1,'.');//LCD显示测量值
DisplayChar(13,1,table[2]+0x30);
DisplayChar(14,1,'C');
//----------------------------------
table[2]=temp2%10;
table[1]=(temp2/10)%10;
table[0]=(temp2/100)%10;
DisplayString(0,0,"SetUpT:
");
DisplayChar(10,0,table[0]+0x30);
DisplayChar(11,0,table[1]+0x30);
DisplayChar(12,0,'.');//LCD显示测量值
DisplayChar(13,0,table[2]+0x30);
DisplayChar(14,0,'C');
}
else
{
tt[7]=x%10;
tt[6]=(x/10)%10;
tt[5]=(x/100)%10;
tt[4]=(x/1000)%10;
tt[3]=(x/10000)%10;
tt[2]=(x/100000)%10;
tt[1]=(x/1000000)%10;
tt[0]=(x/10000000)%10;
DisplayString(0,0,"measureV:
");
DisplayChar(0,1,tt[0]+0x30);
DisplayChar(1,1,tt[1]+0x30);
DisplayChar(2,1,tt[2]+0x30);
DisplayChar(3,1,tt[3]+0x30);
DisplayChar(4,1,tt[4]+0x30);
DisplayChar(5,1,tt[5]+0x30);
DisplayChar(6,1,tt[6]+0x30);
DisplayChar(7,1,tt[7]+0x30);
}
if(temp1>temp2){makeC=0;makeH=1;}
elseif(temp1else{makeC=1;makeH=1;}
if((temp1-temp2)<50&&(temp1-temp2)>-50)
pwmData=PID(setup_t,achieve);
elseif(pwmData>1000){pwmData=1000;}
else{pwmData=0;};
}
unsignedintADC0809()
{
unsignedintadc;unsignedlongintgetdata;
ST=0;OE=0;ST=1;ST