基于单片机的智能温度控制系统的设计Word下载.docx
《基于单片机的智能温度控制系统的设计Word下载.docx》由会员分享,可在线阅读,更多相关《基于单片机的智能温度控制系统的设计Word下载.docx(24页珍藏版)》请在冰豆网上搜索。
(2)加热装置有效功率控制模块
根据题目,可以使用电热炉进行加热,控制电热炉的功率即可以控制加热的速度。
当水温过高时,关掉电热炉进行降温处理,让其自然冷却。
在制作中,我们装设一个小电风扇,当水温超高时关闭电炉开启风扇散热,当需要加热时开启电炉关闭风扇。
由于加热的功率较大,考虑到简化电路的设计,我们直接采用220V电源。
对加热装置控制模块有以下两种方案:
采用可控硅来控制加热器有效功率。
可控硅是一种半控器件,应用于交流电的功率控制有两种形式:
控制导通的交流周期数达到控制功率的目的;
控制导通角的方式控制交流功率。
由交流过零检测电路输出方波经适当延时控制双向可控硅的导通角,延时时间即移相偏移量由温度误差计算得到。
可以实现对交流电单个周期有效值周期性控制,保证系统的动态性能指标。
该方案电路稍复杂,需使用光耦合驱动芯片以及变压器等器件。
但该方案可以实现功率的连续调节,因此响应速度快,控制精度高。
采用继电器控制。
使用继电器可以很容易实现地通过较高的电压和电流,在正常条件下,工作十分可靠。
继电器无需外加光耦,自身即可实现电气隔离。
这种电路无法精确实现电热丝功率控制,电热丝只能工作在最大功率或零功率,对控制精度将造成影响。
通过比较,我们选择方案一。
(3)温度采集模块
题目要求温度静态误差小于等于0.2℃,温度信号为模拟信号,本设计要对温度进行控制和显示,所以要把模拟量转换为数字量。
该温度采集模块有以下三种方案:
利用热电阻传感器作为感温元件,热电阻随温度变化而变化,用仪表测量出热电阻的阻值变化,从而得到与电阻值相应的温度值。
最常用的是铂电阻传感器,铂电阻在氧化介质中,甚至在高温的条件下其物理,化学性质不变。
由铂电阻阻值的变化经小信号变送器XTR101将铂电阻随温度变化的转换为4~20mA线形变化电路,再将电流信号转化为电压信号,送到A/D转换器——ADC0809.即将模拟信号转换为数字信号。
该方案线性度优于0.01%。
采用温度传感器AD590K。
AD590K具有较高精度和重复性,良好的非线性保证±
0.1℃的测量精度。
加上软件非线性补偿可以实现高精度测量。
AD590将温度转化为电流信号,因此要加相应的调理电路,将电流信号转化为电压信号。
送入8为A/D转换器,可以获得255级的精度,基本满足题目要求。
方案三:
采用数字温度传感器DS18B20。
DS18B20为数字式温度传感器,无需其他外加电路,直接输出数字量。
可直接与单片机通信,读取测温数据,电路简单。
基于以上分析和现有器件所限,温度采集模块选用方案三。
DS18B20与传统的热敏电阻相比,他能够直接读出被测温度并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。
并且从DS18B20读出的信息或写入DS18B20的信息仅需要一根口线(单线接口)读写,因而使用DS18B20可使系统结构更趋简单,可靠性更高。
他在测温精度、转换时间、传输距离、分辨率等方面带来了令人满意的效果。
(4)键盘与显示模块
根据题目要求,水温要由人工设定,并能实时显示温度值。
对键盘和显示模块有下面两种方案:
采用液晶显示屏和通用矩阵键盘。
液晶显示屏(LCD)具有功耗小、轻薄短小无辐射危险,平面直角显示以及影象稳定不闪烁,可视面积大,画面效果好,抗干扰能力强,并可灵活的现实多种状态。
采用三位LED七段数码管分别显示温度的十位、个位和小数位。
按键采用单列3按键进行温度设定。
数码管具有:
低能耗、低损耗、低压、寿命长、耐老化,对外界环境要求较低。
同时数码管采用BCD编码显示数字,程序编译容易,资源占用较少。
根据以上论述,51单片机资源丰富,根据需要,我们选用方案一。
1.3.2系统各模块的最终方案
根据以上分析,结合器件和设备等因素,确定如下方案:
1.采用AT89C51单片机作为控制器,分别对温度采集、LCD显示、温度设定、加热装置功率控制。
2.温度测量模块采用数字温度传感器DS18B20。
此器件经软件设置可以实现高分辨率测量。
3.电热丝有效功率控制采用光隔离器和双向可控硅控制。
4.显示用LCD液晶显示实时温度值。
系统的基本框图如图1.1所示。
CPU(AT89C51)首先写入命令给DS18B20,然后DS18B20开始转换数据,转换后通过89S52来处理数据。
数据处理后的结果就显示到数码管上。
另外由键盘设定温度值送到单片机,单片机通过数据处理发出温度控制信息到继电器。
1.1系统基本框图
2.系统硬件设计
2.1温度采集部分设计
本系统采用半导体温度传感器作为敏感元件。
传感器我们采用了DS18B20单总线可编程温度传感器,来实现对温度的采集和转换,DQ接上拉电阻,与单片机P2.6口相连,直接与单片机通讯,大大简化了电路的复杂度。
DS18B20的测温电路如图2.1所示。
图2.1DS18B20测温电路
2.2矩阵键盘的设计
由于控制键位较多,方便程序设计,硬件安全可靠,我们设计4×
4矩阵键盘,与单片机P1口相连,电路如图2.2所示。
图2.2矩阵键盘电路
2.3液晶显电路
我们用单片机P0口作为1602的数据传输口,P2.0为数据命令选择端、P2.1读写、P2.2使能端。
硬件电路如图2.3所示。
图2.3液晶硬件电路图
2.4水温升温将温控制.
本设计中涉及到了强电部分,因此对电炉的控制我们用moc3041和bt13电路如图2.4,对风扇我们采用继电器,电路如图2.5.
图2.4电炉控制图
图2.5风扇电路图
3.系统软件设计
3.1读取DS18B20温度模块子程序
每次对DA18B20操作时多要按造DS18B20工作过程中的协议进行。
初始化->
RoM操作命令->
存储器操作命令->
处理数据程序流程图如图3.1所示。
3.2数据处理子程序
由于DS18B20转换后的代码并不是实际的温度值,所以要进行数据处理。
由于本程序采用的是0.0625的精度,小数部分的值,可以用后四位代表的实际数值乘以0.0625,得到真正的数值,数值可能带几个小数位,所以采取四舍五入,保留一位小数即可。
也就说,本系统的温度精确到了0.1度。
首先程序判断温度是否是零下,如果是,则DS18B20保存的是温度的补码值,需要对其低8位(LSByte)取反加一变成原码。
处理过后把DS18B20的温度复制到单片机的RAM中,里面已经是温度值的Hex码了,然后转换Hex码到BCD码,分别把小数位,个位,十位的BCD码存入RAM中。
数据处理子程序流程图如图3.2所示。
图3.1读取DS18B20温度子程序流程图
图3.2数据处理子程序流程图
3.3键盘扫描子程序
图3.3键盘子程序流程图
3.4主程序流程图
总模块流程图如图3.4所示。
本软件设计采用循环查询来处理各个模块,温度是缓慢变化量所以可以满足性能要求。
4.系统测试
4.1静态温度测试
测试方式:
由于条件的限制,采用模拟加热方式进行测试。
测量仪器:
空调温度显示屏
测试结果如表4.1所示:
表4.1测试结果数据
标准温度/℃
20
22
25
27
28
测量温度/℃
19.8
22.1
24.7
26.8
27.6
误差/℃
0.2
0.1
0.3
0.4
4.2动态温控测量
加热方式用体温对传感器DS18B20进行加热。
设定控制温度,记录超调温度,稳态误差。
超调温度与加热的功率有关,这里不再测量。
测量结果如表4.2所示:
表4.2测试结果数据
设定温度/℃
29
30
33
35
超调温度/℃
1.3
0.9
1.1
0.6
稳态误差/℃
4.3结果分析
有以上的测量结果可见,系统基本上达到了所要求的指标,静态测温的精度主要由DS18B20来决定。
在控温指标中,影响系统的性能的因素很多。
最关键的是加热系统本身的物理性质及控制算法。
由于条件的限制,在本设计中采用体温进行测试。
附录1.参考文献
[1]刘勇编数字电路电子工业出版社2004
[2]陈正振编电子电路设计与制作广西交通职业技术学院信息工程系2007
[3]杨子文编单片机原理及应用西安电子科技大学出版社2006王法能编
[4]单片机原理及应用科学出版社2004
[5]全国大学生电子设计竞赛培训系列教程高吉祥主编
附录2.源代码
#defineucharunsignedchar
#defineuintunsignedint
unsignedcharkey_value;
//bitdir=1;
unsignedcharpwm=30;
floattemperature;
//存放键盘返回
unsignedchart[2],*pt//用来存放温度值,测温程序就是通过这个数组与主函数通信的
ucharkey_flag=0;
//定义有键按下的标志
#include"
reg52.h"
user.h"
hardware.c"
lcd.c"
ds18b20.h"
key.c"
voidmain()
{
LCD_Initial();
sys_init();
setds18b20(TH,TL,RS);
//设置上下限报警温度和分辨率
delay_18B20(100);
Init_DS18B20();
while
(1)
pt=ReadTemperature();
//读取温度,温度值存放在一个两个字节的数组中,
temper_LCD();
//实测温度转化为ACSII码,并送液晶显示缓冲区
LCD_Print(0,0,TempBuffer0);
LCD_Print(0,1,TempBuffer1);
key_value=kbscan();
if(key_flag==1)
key_command(key_value);
alarm=1;
delay_20ms(20);
alarm=0;
}
elsealarm=0;
useralarm();
voidtimer1(void)interrupt3
TH1=(65536-pwm*100)/256;
TL1=(65536-10000)%256;
#include<
intrins.h>
//液晶显示程序
//PortDefinitions**********************************************************
sbitLcdRs=P2^0;
sbitLcdRw=P2^1;
sbitLcdEn=P2^2;
sfrDBPort=0x80;
//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
voidlcd_delay(unsignedchart)
{unsignedchari,j;
for(i=0;
i<
t;
i++)
for(j=0;
j<
100;
j++);
}//内部等待函数
voidLCD_Wait(void)//读忙状态
LcdRs=0;
LcdRw=1;
//向LCD写入命令或数据
#defineLCD_COMMAN0//Command
#defineLCD_DATA1//Data
#defineLCD_CLEAR_SCREEN0x01//清屏
#defineLCD_HOMING0x02//光标返回原点
voidLCD_Write(bitstyle,unsignedcharinput)//写数据1/命令0
LcdRs=style;
LcdRw=0;
DBPort=input;
LcdEn=1;
lcd_delay(10);
LcdEn=0;
LCD_Wait();
//设置显示模式
#defineLCD_SHOW0x04//显示开
#defineLCD_HIDE0x00//显示关
#defineLCD_CURSO0x02//显示光标
#defineLCD_NO_CURSOR0x00//无光标
#defineLCD_FLASH0x01//光标闪动
#defineLCD_NO_FLASH0x00//光标不闪动
//设置输入模式
#defineLCD_AC_UP0x02
#defineLCD_AC_DOWN0x00//default
#defineLCD_MOVE0x01//画面可平移
#defineLCD_NO_MOVE0x00//default
//初始化LCD
voidLCD_Initial(void)//初始化LCD
LCD_Write(0,0x38);
//8位数据端口,2行显示,5*7点阵
lcd_delay(300);
LCD_Write(0,0x0c);
//显示模式
LCD_Write(0,0x01);
//清屏
LCD_Write(0,0x06);
//输入模式
//************************************************************************
voidGotoXY(unsignedcharx,unsignedchary)
EA=0;
if(y==0)LCD_Write(0,0x80|x);
if(y==1)LCD_Write(0,0xc0|x);
EA=1;
//输出字符串
voidPrint(unsignedchar*str)
while(*str!
='
\0'
)
LCD_Write(1,*str++);
voidLCD_Print(unsignedcharx,unsignedchary,unsignedchar*str)
GotoXY(x,y);
Print(str);
//hardware.c硬件程序
sbitalarm=P2^5;
sbithot=P2^7;
sbitcold=P2^4;
voidsys_init(void)
{/*
ET1=1;
TMOD=0X01;
TH1=15536/256;
TL1=15536%256;
TR1=1;
*/
cold=0;
hot=0;
/////////////////////矩阵键盘程序
string.h>
charcodetab[4][4]={{'
.'
1,4,7},//7,8,9,EUP
{0,2,5,8},//4,5,6,Ddown
{'
F'
3,6,9},//1,2,3,CSET
B'
'
C'
D'
E'
}};
//0到F的16个键植//A.,0,F+/-,BOK
voiddelay(unsignedchara)
unsignedchari;
while(a--)
for(i=100;
i>
0;
i--);
unsignedcharkbscan()//键盘扫描
unsignedcharhang,lie,key;
key_flag=0;
P1=0x0f;
if(P1!
=0x0f)
delay(10);
delay_20ms(3);
key_flag=1;
switch(P1&
0x0f)
case0x0e:
lie=0;
break;
case0x0d:
lie=1;
case0x0b:
lie=2;
case0x07:
lie=3;
P1=0xf0;
0xf0)
case0xe0:
hang=0;
case0xd0:
hang=1;
case0xb0:
hang=2;
case0x70:
hang=3;
while(P1!
=0x0f);
key=tab[hang][lie];
return(key);
elsereturn(key_value);
voidsettmper(void)
LCD_Write(0,1);
GotoXY(0,0);
Print("
H_Tmp:
"
);
2;
while(key_flag==0)key_value=kbscan();
if(key_value!
&
key_value!
)break;
elsekey_value=kbscan();
get_ht[i]=key_value;
LCD_Write(1,key_value+0x30);
GotoXY(0,1);
L_Tmp:
get_lt[i]=key_value;