数字温湿度计的设计汇总.docx
《数字温湿度计的设计汇总.docx》由会员分享,可在线阅读,更多相关《数字温湿度计的设计汇总.docx(21页珍藏版)》请在冰点文库上搜索。
数字温湿度计的设计汇总
电子系统
综合设计与仿真
题目:
数字温湿度计的设计
1课程设计目的
通过数字温湿度计的设计,使对温湿度测量仪的应用有更深的理解,熟练protuse仿真软件的使用,加深对单片机系统应用的理解。
对仿真电路与实际电路的差距有更深的理解。
2课程设计的内容及要求
(1)使用热敏电阻和湿敏电阻,不允许使用集成的温度传感器和湿度传感器。
(2)温度测量范围0℃-100℃,测量误差1℃;湿度测量范围20%-100%,测量误差5%以内。
(3)能进行摄氏度和华氏度的转换。
(4)有设置的报警的门限,有报警的声音。
(5)自己设计测试方案,并论证方案的合理性。
3元器件的选择
本设计以检测温度和湿度并较为精确的显示为目的,按照系统设计要求功能的要求,确定由四个模块组成:
主控器,测温电路,测湿电路,显示电路。
系统以热敏电阻作为温度敏感器件,以湿敏电阻作为湿度敏感器件,经过分压电路和模数转换芯片,将温度模拟量转化为电压数字量以总线传入单片机。
以AT89C52为主芯片,在主芯片对A/D转换芯片传入的电压值进行处理,由单片机程序控制,将处理后的温度和湿度由显示屏进行显示。
3.1热敏电阻的选择
市场上常用的热敏电阻有PT100,MF58-NTC-10K,NTC10D-9等。
我们选择了NTC10D-9这一个负温度系数的热敏电阻。
PT100的测温范围为-200~650℃,特点是精度高,但是价格较贵。
MF58-NTC的测温范围为-45~+300℃。
其特点是稳定性好,可靠性高。
阻值范围宽:
0.1~5000K欧。
阻值及B值精度高。
玻璃封装,可在高温和高湿等恶劣环境下使用。
体积小,结构坚固,便于自动化安装。
热感应快,灵敏度高等。
负温度系数的热敏电阻NTC10D-9特点是过流控制范围宽,材料常数(B值)大,残余电阻小,功率大,抑制浪涌电流能力强等。
在选择的过程中,我们初步选择了性能优良,价格便宜的MF58型热敏电阻,在购买中,未买到,就选择了依然可以满足要求的NTC10D-9。
3.2湿敏电阻的选择
目前市场上的湿敏电阻主要为氯化锂湿敏电阻和有机高分子膜湿敏电阻。
氯化锂湿敏电阻是利用湿敏元件的电气特性(如电阻值),随湿度的变化而变化的原理进行湿度测量的传感器。
氯化锂湿度传感器具有稳定性、耐温性和使用寿命长多项重要的优点。
其可在120度高温环境中稳定工作,这一点是其他高分子电容是湿度传感器不可比拟的;但是氯化锂湿敏电阻线性测湿量程较窄,约在20%RH左右,在该测量范围内,其线性误差小于2%RH。
所以,在全范围湿度测量环境中要想达到高精度的湿度测量,目前普遍采用的单片湿敏元件测量方法就很难实现了。
有机高分子膜湿敏电阻的特点是在基片上覆盖一层用感湿材料制成的膜,当空气中的水蒸气吸附在感湿膜上时,元件的电阻率和电阻值都发生变化,利用这一特性即可测量湿度。
此湿敏电阻的优点是线性优良,性价比高,能耗低,测量范围宽,响应速度快,抗污染能力强,性能稳定等。
因此我们选择了此类湿敏电阻。
型号为HR202.
3.3模数转换芯片的选择
温度的测量范围为0℃到100℃,精度为
1℃,分散为100个数据,故采用8位的采样芯片即可满足要求。
对湿度进行采样所需的数据宽度小于温度的数据宽度,故此次试验中的温湿度测量仪采用一个8位的采样芯片即可满足要求。
在众多AD转换芯片中,ADC0809是国内应用最广泛的芯片,价格便宜,购买方便,参数与性能也满足了本实验的要求,故在此实验中,我们选择了ADC0809。
ADC0808是采样分辨率为8位的、以逐次逼近原理进行模/数转换的器件。
其内部有一个8通道多路开关,它可以根据地址码锁存译码后的信号,只选通8路模拟输入信号中的一个进行A/D转换。
3.4主控芯片的选择
此次试验所处理的数据并不复杂,对主控器的要求不高,故使用我们已经用的比较熟练的C51系列单片机即可。
在此,我们选用了MCS89C52单片机,89C52内置8位中央处理单元、256字节内部数据存储器RAM、8k片内程序存储器(ROM)32个双向输入/输出(I/O)口、3个16位定时/计数器和5个两级中断结构,一个全双工串行通信口,片内时钟振荡电路。
此外,89C52还可工作于低功耗模式,可通过两种软件选择空闲和掉电模式。
在空闲模式下冻结CPU而RAM定时器、串行口和中断系统维持其功能。
掉电模式下,保存RAM数据,时钟振荡停止,同时停止芯片内其它功能。
89C52有PDIP(40pin)和PLCC(44pin)两种封装形式。
我们选用了40pin的封装。
3.5显示屏的选择
市面上应用最广泛的显示屏之一就是LCD1602,价格便宜,使用方便,而且现成的资源很多,便于开发利用,最重要的是,LCD1602完全满足了本次试验的要求。
1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。
它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形。
1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。
目前市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。
其引脚图如下:
4硬件系统设计
4.1总体设计电路
本次设计是采用AT89S52控制ADC0809对NTC热敏电阻进行采样和控制HR202来实现温湿度的测量和控制。
硬件电路主要包括单片机控制模块、温度采集模块、湿度采集模块、显示模块、报警器模块和键盘输入模块。
整个系统的原理图如下:
4.2温湿度的检测电路
不同的温度使热敏电阻感应到了不同的阻值,其上的分压也相应作出了改变。
将此电压通过ADC0809的采样,转换为数字信号,再将数字信号传输到单片机中,有单片机进行后续的处理和计算。
4.2.1温度采集模块部分
温度测量部分,Rt1为温敏电阻,选用的阻值较小,约为十几欧姆,和R4分压产生的电压很小,再采用集成运放放大一倍最后将放大的电压进行采样。
4.2.2湿度采集模块部分
利用单片机的IO口输出1kHz的方波,通过HR200湿敏电阻对电容进行充电,当检测到IO口发生有低电平转化到高电平时,记下充电的时间,经过运算即可得到当前的湿度值。
4.2单片机控制模块
送入单片机内部的数字信号经过单片机的处理,根据程序提供的公式计算出此电压下所对应的温度(湿度),再将数据通过显示屏显示出来。
其处理过程主要由单片机控制程序进行控制。
4.3显示电路模块
使用LCD1602液晶显示屏进行显示。
单片机将温湿度数据经处理后由P0.0~P0.7口输出到LCD。
4.4报警器模块
报警器部分由三极管和有源蜂鸣器组成。
输入来的电流经过三极管的放大来驱动蜂鸣器。
具体电路如下:
4.5键盘输入模块
4.1电阻R4阻值的确定
由温敏电阻的数据手册可知当温度为0时,RT为28.5Ω左右,V=RT/(RT+R4),现有材料中最小电阻为51Ω,所以取R4为51Ω,且V<2.5,所以可用运放放大2倍。
4.2温敏电阻B值的计算
根据数据手册,温敏电阻的B值为3250±5%。
5软件系统设计
5.1电阻R4阻值的确定
由温敏电阻的数据手册可知当温度为0时,RT为28.5Ω左右,V=RT/(RT+R4),现有材料中最小电阻为51Ω,所以取R4为51Ω,且V<2.5,所以可用运放放大2倍。
5.2温敏电阻B值的计算
根据数据手册,温敏电阻的B值为3250±5%。
5.3程序部分的设计
系统程序采用单片机C语言编写。
程序简洁,可靠性高,可维护性好。
主程序流程图:
模数转化流程图
6数据测量与分析
6.1测量方案
在测量中,我们需要一个成品的温湿度计来作数据的基准比较。
对这个温湿度计的要求为:
能够完整的测量实验作品所测范围内的温度和湿度,所测温度和湿度的误差范围在
1℃和
1%以内。
6.1.1温度测量
由于作品的测温范围为从为0℃到100℃,正好为水所能表现出来的温度范围,所以测试中我们采用侧水温的方法来测量不同的温度。
测试步骤:
(1)将刚刚烧沸的水倒入容器中,并将基准温度计的感应温度的部分完全浸入水中,读取水的温度值。
将所做的温湿度计的热敏电阻完全浸入水中,再读取现在两个仪器所显示出来的温度值,记录于数据记录表中。
(2)然后再缓慢的,往刚才的沸水中加入冷水,边加边缓慢的搅动,使水温均匀、缓慢的下降。
当基准温度计显示的温度下降了5℃,停止加水,读取二者的具体温度,记录于数据记录表中。
(3)然后再继续加水,每5℃测量一次。
直到水的温度达到冷水的温度。
(4)向其中加入冰块,做成冰水混合物,测量此时,水的温度。
(5)最后测试温度报警。
任意设置报警门限为60℃,将热敏电阻放入沸水中,验证蜂鸣器是否响起。
6.1.2湿度测量
要求中,湿度的测量范围为20%-100%,由于湿度受到空气中所含水分的多少和温度的高低的影响。
所以测试时采用和温度一起测试的方法,也就是利用水温的不同来使水表面空气的温度不同,进而相对湿度值也就不同。
在测试温度的同时,将标准温湿度计的湿度感应部分与作品的湿敏电阻一起悬置的水的上方但不能碰触到水滴。
6.2数据测量
温度测量结果记录表
环境温度(℃)
0
5
10
15
20
25
30
35
40
45
测得温度(℃)
环境温度(℃)
50
55
60
65
70
75
80
85
90
95
测得温度(℃)
湿度测量结果记录表
环境湿度(%)
20
25
30
35
40
45
50
55
60
测得湿度(%)
环境湿度(%)
65
70
75
80
85
90
95
100
测得湿度(%)
6.3数据分析
6.4电路改进
电路改进的方向就是提高输入电压精度。
而电压源是很难满足这一要求的,所以,在这应考虑用恒流源来处理。
假如给恒流源一个I=1mA的电流,然后再用1KΩ的热敏电阻加到恒流源上,这样电压就很好控制了。
V=I*RT.
则,当RT为KΩ时,其电压值就为),最大为1V,这大大提高了分辨率,使得到的温度值更加精确。
7参考文献
[1]ADC0809用户手册
[2]LCD1602用户手册
[3]AT89S52用户手册
[4]LM358用户手册
[5]热电型红外传感器用户手册
[6]HC74LS74用户手册
[7]HR202用户手册
[8]XX搜索引擎
附录一:
代码
Main.c
#include
#include
#include"LCD1602.h"
#include"ADC0808.h"
#include"RH.h"
externuchardisplay_buffer_1[][16];
externuchardisplay_buffer_2[][16];
externucharKeynum;
ucharFlag=0;
voidmain()
{
TMOD=0x10;
TH1=(65536-4000)/256;
TL1=(65536-4000)%256;
EA=1;
ET1=1;
TR1=1;
//unsignedintKeynum=4;
Initialize_LCD1602();
delay50us(10);
Write_LCD_Command(0x80);//设置显示的初始位置
LCD_Display(display_buffer_1[0]);//显示"TheTempis:
"
while
(1)
{
adc0808_init();
Refresh_show();
Write_LCD_Command(0xc0);//设置显示的初始位置
LCD_Display(display_buffer_1[1]);//显示测得的数据
keyscan();
if(Keynum==0)
{
Keynum=4;Flag=1;
while(Flag==1)
{
Write_LCD_Command(0x80);//设置显示的初始位置
LCD_Display(display_buffer_2[0]);
keyscan();
if(Keynum==3){Flag=0;}
}
}
Keynum=4;
Write_LCD_Command(0x80);//设置显示的初始位置
LCD_Display(display_buffer_1[0]);//显示"TheTempis:
"
}
}
ADC0809.C
//ADC0809控制&&数据采样&&数据处理
#include
#include
#include
#include"ADC0808.h"
unsignedlongdat_adc0808;
uchardisplay_buffer_1[][16]={
{"CurrentTemp:
"},
{"(T)=0.00C"}
};
voiddelay50us(uintm)
{
uintn,k;
for(n=m;n>0;n--)
for(k=25;k>0;k--);
}
uintadc0808_init()//AD初始化
{
START=0;
OE=0;
START=1;
START=0;
while(EOC==0);
OE=1;
dat_adc0808=P1;
OE=0;
returndat_adc0808;
}
voidRefresh_show()//刷新显示
{
uintt=dat_adc0808*500.0/255;//
display_buffer_1[1][6]=t/100+'0';//整数位
display_buffer_1[1][8]=t/10%10+'0';//两个小数位
display_buffer_1[1][9]=t%10+'0';
display_buffer_1[1][10]=0xdf;
}
Lcd1602.C
//液晶控制与显示驱动程序
#include
#include
#include
#include"LCD1602.h"
#include"ADC0808.h"
//---------------忙检查-------------------//
ucharLCD_Busy_Check()
{
ucharLCD_Status;
RS=0;
RW=1;
E=1;
delay4us();
LCD_Status=P0;
E=0;
returnLCD_Status;
}
//--------------向LCD写入命令--------------------//
voidWrite_LCD_Command(ucharcmd)
{
while((LCD_Busy_Check()&0x80)==0x80);//忙等待
RS=0;
RW=0;
E=0;
P0=cmd;
delay4us();
E=1;
delay4us();
E=0;
}
//-----------向LCD写入一个字节的数据函数-----------------*/
voidWrite_LCD_Data(uchardat)
{
while((LCD_Busy_Check()&0x80)==0x80);
RS=1;
RW=0;
E=0;
P0=dat;
delay4us();
E=1;
delay4us();
E=0;
}
//-----------LCD初始化-----------------*/
voidInitialize_LCD1602()//液晶初始化函数
{
Write_LCD_Command(0x38);delay50us(10);//功能设置,数据长度为8位,双行显示,5×7点阵字体
Write_LCD_Command(0x0C);delay50us(10);//显示开,关光标
Write_LCD_Command(0x06);delay50us(10);//字符进入模式:
屏幕不动,字符后移
Write_LCD_Command(0x01);delay50us(10);//清屏
}
//-----------在LCD上显示字符串-----------------*/
voidLCD_Display(uchar*str)
{
uchari;
for(i=0;i{
Write_LCD_Data(str[i]);
delay50us(100);
}
}
RH.C
//湿度控制&&键盘控制&&报警设置
#include
#include
#include
#include"RH.h"
#include"LCD1602.h"
#include"ADC0808.h"
sbitH1=P2^4;
sbitH2=P2^5;
sbitH3=P2^6;
sbitKey0=P2^0;
sbitKey1=P2^1;
sbitKey2=P2^2;
sbitKey3=P2^3;
sbitCLOCK=P3^6;
sbitBuzzer=P2^7;
ucharKeynum=4;
uchardisplay_buffer_2[][16]={
{"SettingTemp:
"},
{"(T)=0.00C"}
};
voidkeyscan()
{
ucharTemp1,Temp2;
Temp1=P2;//读P2口数据
Temp1=Temp1&0x0f;//提取按键相关数据——P2口的低四位
if(Temp1!
=0x0f)//判断键是否有按下的
{
delay50us(500);//延时消抖
Temp2=P2;//再读P0口
Temp2=Temp2&0x0f;//取P0口低四位数据
if(Temp1==Temp2)//如果两次读取的按键数据一样,则表示有按键按下
{
switch(Temp2)//判断键值
{
case0x0e:
Keynum=0;break;
case0x0d:
Keynum=1;break;
case0x0b:
Keynum=2;break;
case0x07:
Keynum=3;break;
default:
break;
}
while(Temp2!
=0x0f)//按键释放检测
{
Temp2=P2;//必须赋值确实必须赋值不赋值Temp2就不变了
Temp2=Temp2&0x0f;
}
}
}
}
voidSetting()
{
}
voidt1(void)interrupt3using0
{
TH1=(65536-4000)/256;
TL1=(65536-4000)%256;
CLOCK=~CLOCK;
}
ADS0809.h
#ifndef__ADC0808_H__
#define__ADC0808_H__
#include
#definedata_portP1
#defineucharunsignedchar
#defineuintunsignedint
sbitSTART=P3^3;
sbitEOC=P3^4;
sbitOE=P3^5;
voiddelay50us(uintm);//延时
uintadc0808_init();//AD初始化
voidRefresh_show();
#endif
LCD1602.h
#ifndef__LCD1602_H__
#define__LCD1602_H__
#include
#definedat_portP0
#defineucharunsignedchar
#defineuintunsignedint
#definedelay4us(){_nop_();_nop_();_nop_();_nop_();}
sbitRS=P3^2;//RS=1数据RS=0命令
sbitRW=P3^0;//RW=1读取RW=0写入
sbitE=P3^1;//E使能信号
ucharLCD_Busy_Check();//忙检查
voidWrite_LCD_Command(ucharcmd);//向LCD写入命令
voidWrite_LCD_Data(uchardat);//向LCD写入一个字节的数据函数
voidInitialize_LCD1602();//液晶初始化函数
voidLCD_Display(uchar*str);//在LCD上显示字符串
#endif
RH.H
#ifndef__RH_H__
#define__RH_H__
#include
#defineucharunsignedchar
#defineuintunsignedint
voidkeyscan();
#endif