单片机温湿度传感器课程设计
信息与电气工程学院
课程设计说明书 (2015 /2016 学年第 2 学期)
课程名称 :单片机应用课程设计
题 目 :温湿度监测系统
专业班级 :自动化3班
学生姓名 :
学 号:
指导教师 :苗敬利、王立国、王静爽、侯帅、何明星、赵奇 设计周数 :2周
设计成绩 :
2016 年 7 月 6 日
摘要
本设计实现的是单片机温湿度测量与控制系统,通过在LCD1602上实时显示室内环境的温度和相对湿度。系统采用集温湿度传感器与A/D转换器为一体的DHT90传感器芯片,通过单片机AT89C52处理进行显示,其它模块包括了实时时钟/日期产生电路和超限报警处理电路,对所测量的值进行实时显示和报警处理。 本文介绍了基于ATMEL 公司的AT89C52系列单片机的温湿度实时测量与控制系统和显示系统的设计,包括介绍了硬件结构原理,并分析了相应的软件的设计及其要点,包括软件设计流程及其程序实现。 系统结构简单、实用,提高了测量精度和效率。
关键词: 温湿度;SHT10传感器;单片机;DHT11传感器
1设计目的:制定温湿度监测系统的操作流程,指导温湿度监测系统的正确使用和维护,防止温湿度监测系统操作不当而造成损坏,并保证测试的数据准确。
2 温湿度检测的简介
2.1 系统的概述
温湿度测量技术在当今的工厂加工、医疗区域、农业区域中已经起来重要的位子,例如资源的节约、产品质量的提高、产品数目的提高,这些问题现在已经越来越受到外界的关注了。当今,知识信息和知识的工业化已经开始了飞一般的进步,温度与湿度的问题影响的范围距离已经不再之前谈到的那些方面,它还体现在科技发展、卫生用品、医药卫生、国家安全基础等多种方面。就上述几个问题和情况,温湿度检测的准确性、稳定性、快速性、安全性这些方面的设计要求变得尤其重要。在最近几年中,使用SHT10控制的温湿度传感器和温湿度数据的网上直接检验技术现已成为当下的一种发展方向和追求。本次毕业设计介绍和实现了一种单片机与自动化温湿度传感器互相结合,它们两就组成了一种简单的温湿度检测器系统。这种检测系统具有以下的特点:易操作、制作成本低、准确性较高、持续时间长、较为稳定。
2.2 系统设计选题的背景
2.2.1国内外研究现状
关于我国国内温湿度研究的时间相对于国外还是比较晚的,毕竟我国对于温湿度检测技术的研究才刚刚起步 。初期我国只运用了相对落后的温湿度的微机控制测量技术,而这门技术还是在参考当时国外发展国家的检测技术的基础上,这门技术局限于测量单方面环境因素,不支持复杂、多项的环境控制。我国关于温湿度检测技术从对国外发达技术的学习,经过慢慢时间的不断地实验,现已经发展到微测量计算机应用的层次上。目前,国内用的技术基本上包括单片机,这种技术是利用单片机控制的温湿度检测的系统,过程与步骤都比较简单,还不能实现多参数多回路的温湿度控制系统,相对于那些发达的国家,技术还是比较落后。我国的温湿度测量存在着下列问题:实现功能少、产量水平低,操作检修步骤繁琐。
2.2.2国外外研究现状
关于国外温湿度研究的时间相对于国内来说还是较早。国外初期首先设计出通过组合的形式的模拟式器件,运用了就地取材的方法,将其收集的信号进行一系列的指示并加以记录。近阶段世界各国都在研究与开发基于计算机的控制温湿度系统,此系统受多因子的控制,其主要特点为精确性高、稳定性强。以后温湿度发展趋势向着无人操作化、精度稳定化发展。
2.3系统的分类
水汽压型:测出大气中对某一装置的总压力,然后再测出大气中的水汽对同一装置的压力,将测出的两个压力进行百分比的对比压力,即可以得出温湿度的大小值。
电阻式湿度片:通过外界温湿度变化与电阻值的关系的来设计出的测量仪器。当外界的温湿度改变时,与其用电路连接的电阻也随之改变。温湿度片就是这里的核心器件,它可以感应到外界温湿度的变化。
干湿球温度表:通过两只完全相同的温度表,使他们并列在一起,其中用一只温度表测量气温,另外一支温度表表头需要缠绕着浸透过纯蒸馏水的脱脂纱布,这两种温度表结合起来就是干湿球温度表。
2.4 系统设计的内容与要求
对某一特定环境下用温室度传感器感受到温度和湿度变化,把这种变化转化为电信号输入到单片机中,然后进行各端口的控制使其数据显示在LCD 显示屏上,完成了对仓库额的温室与湿度的测量。要求误差在上下10%之内。
3 数据采集部分
3.1温度传感器
采用热电阻温度传感器。热电阻是利用导体的电阻随温度变化的特性制成的测温元件。现应用较多的有铂、铜、镍等热电阻。其主要的特点为精度高、测量范围大、便于远距离测量。 铂的物理、化学性能极稳定,耐氧化能力强,易提纯,复制性好,工业性好,电阻率较高,因此,铂电阻用于工业检测中高精密测温和温度标准。缺点是价格贵,温度系数小,受到磁场影响大,在还原介质中易被玷污变脆。按IEC 标准测温范围-200~650℃,百度电阻比W (100)=1.3850时,R0为100Ω和10Ω,其允许的测量误差A 级为±(0.15℃+0.002|t|),B 级为±(0.3℃+0.005|t|)。 铜电阻的温度系数比铂电阻大,价格低,也易于提纯和加工;但其电阻率小,在腐蚀性介质中使用稳定性差。在工业中用于-50~180℃测温。
3.2湿度传感器 测量空气湿度的方式很多,其原理是根据某种物质从其周围的空气吸收水分后引起的物理或化学性质的变化,间接地获得该物质的吸水量及周围空气的湿度。电容式、电阻式和湿涨式湿敏原件分别是根据其高分子材料吸湿后的介电常数、电阻率和体积随之发生变化而进行湿度测量的。 采用HS1100/HS1101湿度传感器。HS1100/HS1101电容传感器,在电路构成中等效于一个电容器件,其电容量随着所测空气湿度的增大而增大。不需校准的完全互换性,高可靠性和长期稳定性,快速响应时间,专利设计的固态聚合物结构,由顶端接触(HS1100)和侧面接触(HS1101)两种封装产品,适用于线性电压输出和频率输出两种电路,适宜于制造流水线上的自动插件和自动装配过程等。相对湿度在1%—100%RH范围内;电容量由16pF 变到200pF ,其误差不大于±2%RH;响应时间小于5s ;温度系数为0.04 pF/℃。
3.3采用的传感器
大连北方测控工程有限公司生产的温湿度传感器DHT90,将两者的功能集成在一起,并且输出的是数字信号,不需要再进行A/D转换,其温度测量的范围为-40℃~123.8℃,分辨率为0.01℃;测湿范围为0~100%RH,分辨率为0.03%RH。 综合上面各种设计的技术要求和传感器的特性,考虑到设计简约化,选择使用传感器DHT90,输出的是数字信号,不需要进行A/D转换,简化了系统设计。
4系统设计方案
4.1系统框架图
本系统由单片机主控电路,DHT11温湿度采集模块,1602液晶显示模块3部分组成,下图为框架图。
4.2.1
方案一:采用温湿度一体化的传感器DHT11采集温湿度数据,DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和
温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC
测温元件,
并与一个高性能
8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。 DHT11原理图 DHT11实物图
4.2.2方案二:由于本实验proteus 库中无dht11模块,使用sht11代替。为了营造无人看守状态, 本次设计中还应用了远程通信系统。方案一中系统的控制核心是AT89C52单片机,它的主要作用是读取温湿度传感器工作时的内部参数,测试的结果可以显示在LCD 上面。
4.3系统功能模块设计
4.3.1 中央控制单元
本次温湿度检测系统设计中,由单片机组成的中央控制单元有十分重要的作用。这是整个系统的大脑,它发出操作命令指挥系统工作。该单片机不仅可以控制LCD 显示屏幕的工作状态,还可以时时刻刻管理着监测着外部环境的温湿度的变化的温湿度传感器的工作状态。依照所需设计的要求和控制的目的,本次毕业设计选择了AT89C52芯片,该芯片里面包含4k Bytes ISP的能多次烧入的Flash 器件,是一类简单高效率的CMOS 8位芯片。AT89C52芯片是使用了ATMEL 公司厂家中的较为先进高级的控制与制作技术做为支持动力。AT89C52芯片还包括MCS-52系统的操作命令与89C52管脚的排列,其中较重要的8位CPU 和ISP Flash 存储单元是它的核心部件。
AT89C52芯片的系统功能具有巨大的优势,它可以满足设计中系统稳定运行的基本要求。AT89C52芯片具16位可编程定时计数器3个,有引脚40个,全双工串行通信口2个,外部双向输入/输出(I/O)端口32个,外中断口2个,读写口线2个,AT89C52芯片的管脚结构如下图所示:
单片机
4.3.2 晶振电路模块与复位电路模块
晶振电路模块:单片机的工作条件是要在时钟驱动的作用下才可以稳定的进行工作, 所需的电容大小通常为30PF 。单片机工作时需要一个信号脉冲,晶振的作用就是提供这个信号脉冲。在时钟驱动作用下,晶振电路所提供的信号脉冲就是单片机的工作速度。举个例子来说明,一个频率为12MHZ 的晶振电路芯片,它的工作速度是12MHZ 每秒的运行速度, 和我们使用的电脑手机的CPU 一个道理。就于多大的频率才能使单片机更好的更稳点的工作的问题,一般情况下其工作时所需要的频率在24MHZ 左右,超过这个值,系统工作就不稳定了。单片机系统的工作速度取决于时钟信号,其内部镶有时钟振荡电路,在单片机的外部接通一个振荡源就可以工作了。
复位电路模块:
复位电路在设计的系统中起着重要的作用,它保障了设计的系统可以在
稳定的环境下工作,复位电路的主要作用功能就是上电复位。当复位信号消除的时候,系统微机电路才可以稳定高效的工作,消除复位信号的条件是VCC 的电压在4.7V 与5.2V 之间,只有在提供稳定无误差的时钟信号才能实现本次的设计。下图为其仿真图:
晶振电路和复位电路
4.3.3显示模块
LCD 显示电路是本系统的功能具体体现的重要模块,实现了对温湿度检测的液晶屏控制的功能。温湿度显示电路的组成有SHT10温湿度传感器、LCD 液晶显示屏幕。其显示模块先接受来自单片机处理后的信号,再将其结果显示在液晶屏幕。STC89C52的P2口接1602的8位数据线,通过输出数据控制1602显示不同的提示字符。1602本身内置各种字符,还可以自定义显示字符。本设计中根据不同场合1602会显示各种提示字符。 P0.0~P0.2接1602控制端,其中P0.0接使能端E ,写操作时,使能端下降沿有效。P0.1接读写控制端R/W,R/W=0,读操作;R/W=1,写操作。P0.2接寄存器选择端RS ,RS=0,写操作时指向指令寄存器,读操作时指向地址寄存器;RS=1,无论读操作还是写操作都指向数据寄存器。 LCD1602的VSS 为电源地,需接地;VDD 为电源电压;V0为LCD 驱动电压,接电位器,通过调节电位器控制显示的亮度,使LCD 显示清晰而无黑影。背光电源线LCD 正负两端分别接电源和地即可。。下图为其仿真图:
显示模块
4.3.4温湿度传感器
利用型号为SHT10的温湿度传感器来测试仓库的温度和湿度。下图为其仿真图:
温湿度传感器
仿真图上三个按键:↑ ↓ 来控制操作。当打到左边时为湿度的调节,当打到右边的时候为温度的调节; ↑是增大按键,↓是减小按键。
5系统的仿真与调试
5.1Proteus 对系统仿真
根据设计要求,从Proteus 元件库中找到所需要用到的元件,画好电路图并且检查有无错误。最后通过keil uVision软件编写的C 语言程序,转换成HEX 文件下载到画好的的电路上进行调试。以下是系统的仿真电路图:
系统运行图
5.2LCD 的仿真
Lcd 运行图
5.3硬件运行结果
运行结果图
实物运行图
6总结
历经两周的课设,又懂得了很多的知识,在这两周的时间里,感受良多吧可以算是。因为我们做的课设里面因为proteus 库中没有DHT11元件,
导致我们做了将近一个星期的课设全
部推翻。无奈的对着那一堆程序没日没夜的改着。从一开始的不了解,觉得很复杂,有传感器、单片机和1602,最麻烦的是还要编程序;到最后的完成,对各个模块都有了更深认知。 本设计综合利用单片机技术、传感器技术、数字电子技术和LCD 显示等科学知识,完成了单片机控制的温度、湿度和显示装置的设计,比较系统地介绍了硬件的组成及设计方法并利用单片机C 语言完成了系统软件的设计。
1. 把传感器技术应用到单片机控制系统中,实现了对环境温度和湿度的数据采集和读取。
2. 利用LCD 液晶的显示技术完成了环境温度、湿度及显示电路的设计。
3. 在本设计的基础上皆有继电器模块,可以外接调温调湿电器,把功能扩展延伸为实现对环境温湿度的控制。
4. 整个系统软硬件搭配合理,设计、开发、维护方便,性价比高
原理图的绘制使我从新学习了一次proteus, 对软件种元器件更加熟悉,画仿真图时更为流畅。在进行设计之前有着很多要解决的问题,比如元器件的选择问题、各个模块的设计和主程序的编程。通过这次设计,我从到图书馆的网站查找相应的资料应用到对应电路参与设计的思考。每个模块都要经过多次的设计,不断的试验,让我对之前在学校所学的书本上的理论知识有了更为深刻的了解。在完成毕业设计的过程是一次难得的理论与实际相结合的过程,在这段时间我更为深刻的理解和掌握了大学期间所学的一些知识,例如C 语言的编程、数字模拟电路、单片机的简单应用、proteus 和keil 软件的使用与设计。
在设计过程中,由于时间和本人能力的限制,设计中存在一些需要改进和优化的地方。测量精度有待进一步提高,软件设计也存在不合理之处。但从设计过程中,对于单片机有更进一步的认识,对用于单片机仿真的软件操作能力也明显提高,通过此设计,本人受益颇丰。
参考文献
[1] 李全利等编著. 《单片机原理及应用》. 北京:清华大学出版社,2006.02:14~36.
[2] 杨西明, 朱骐主编. 《单片机编程与应用入门》. 北京:机械工业出版社,2004.06:24~38.
[3] 先锋工作室编著. 《单片机程序设计实例》. 北京:清华大学出版社,2003.01:68~78.
[4] 谢宜仁主编. 《单片机实用技术问答》. 北京:人民邮电出版社, 2003.02:11~20. [5] 孙江宏, 李良玉等编著. 《Protel99电路设计与应用》. 北京:机械工业出版社,2004.07.
[6] 房小翠, 王金凤编著. 《单片机实用系统设计技术》. 北京:国防工业出版社,1999.06. [7] 南建辉等编著. 《MCS-51单片机原理及其应用实例》. 北京:清华大学出版社,2004.03.
[8] 何宏主编. 《单片机原理与接口技术》. 北京:国防工业出版社,2006.07:15~30
[9] 叶健斌. 《基于单片机嵌入式系统的GPS 应用》. 电子质量,2008:(7)16~24.
[10] 王静. 《通用库房温湿度测控系统》. 青岛:中国海洋大学,2009.05:30~33.
[11] 刘宝元,张玉虹. 《基于单片机的温湿度监控系统设计》. 国外电子测量技术,2009.12.
[12] 陈汝全. 《实用微机与单片机控制技术》. 成都:电子科技大学出版,2005.06:16~17.
附录1:DHT11程序
// 湿度20-90 温度0-50 采样间隔1S
#include
#include "lcd.h"
sbit DQ=P3^7; //DTH11
uchar code ASCII[]="0123456789%c";
uchar code table0[]=" Hum:00";
uchar code table1[]=" Tem:00";
uchar tem;
uchar hum;
display0[2]={0,0};
display1[2]={0,0};
//**************************延时函数
void delay_ms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
//**************************初始化DTH11
bit Init_DTH11()
{
bit flag;
uchar num;
DQ=0;
delay_ms(19); // >18ms
DQ=1;
for(num=0;num
for(num=0;num
flag=DQ;
for(num=0;num
for(num=0;num
return flag;
}
//****************************读DTH11数据
uchar DTH11_RD_CHAR()
{
uchar byte=0;
uchar num;
uchar num1;
while(DQ==1);
for(num1=0;num1
{
while(DQ==0);
byte
for(num=0;DQ==1;num++);
if(num
byte|=0x00;
else
byte|=0x01;
}
return byte;
}
//******************************读取DTH11温度和湿度
void DTH11_DUSHU()
{
uchar num;
if(Init_DTH11()==0)
{
hum=DTH11_RD_CHAR(); //比正常值高7度左右
DTH11_RD_CHAR();
tem=DTH11_RD_CHAR();
DTH11_RD_CHAR();
DTH11_RD_CHAR();
for(num=0;num
DQ=1;
}
}
//***********************************显示函数
void Display_DTH11()
{
display0[1]=hum/10%10;
display0[0]=hum%10;
LcdShowStr(0, 0, table0);
DisplayOneChar (8, 0, ASCII[ display0[1] ] );
DisplayOneChar (9, 0, ASCII[ display0[0] ] );
DisplayOneChar (10, 0, ASCII[10] ); //显示湿度
display1[1]=tem/10%10;
display1[0]=tem%10;
LcdShowStr(0, 1, table1);
DisplayOneChar (8, 1, ASCII[ display1[1] ] );
DisplayOneChar (9, 1, ASCII[ display1[0] ] );
DisplayOneChar (10, 1, 0xdf );
DisplayOneChar (11, 1, ASCII[11] ); //显示温度
}
//*******************************主函数
main()
{
tem=0;
hum=0;
delay_ms(1000); //DTH11开始1s 有错误输出
InitLcd1602();
while(1)
{
DTH11_DUSHU();
Display_DTH11();
delay_ms(2000);
}
}
附录2:SHT10程序
#include
#include
#define uchar unsigned char
#define noACK 0 //继续传输数据,用于判断是否结束通讯
#define ACK 1 //结束数据传输;
//地址 命令 读/写
#define STATUS_REG_W 0x06 //000 0011 0
#define STATUS_REG_R 0x07 //000 0011 1
#define MEASURE_TEMP 0x03 //000 0001 1
#define MEASURE_HUMI 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0
enum {TEMP,HUMI};
sbit DATA = P2^5;
sbit SCK = P2^4;
sbit RS = P2^0;
sbit RW = P2^1;
sbit E = P2^2;
sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
/******** DS1602函数声明 ********/
void LCD_Initial();
void GotoXY(unsigned char x, unsigned char y);
void Print(unsigned char *str);
void LCD_Write(bit style, unsigned char input);
/******** SHT10函数声明 ********/
void s_connectionreset(void);
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);
void calc_sth10(float *p_humidity ,float *p_temperature);
//float calc_dewpoint(float h,float t);
/****************************************************************/
//写字节程序
char s_write_byte(unsigned char value)
{
unsigned char i,error=0;
for (i=0x80;i>0;i>>=1) //高位为1,循环右移 {
if (i&value) DATA=1; //和要发送的数相与,结果为发送的位
else DATA=0;
SCK=1;
_nop_();_nop_();_nop_(); //延时3us
SCK=0;
}
DATA=1; //释放数据线
SCK=1;
error=DATA; //检查应答信号,确认通讯正常
_nop_();_nop_();_nop_();
SCK=0;
DATA=1;
return error; //error=1 通讯错误 }
//读字节程序
char s_read_byte(unsigned char ack)
//----------------------------------------------------------------------------------
{
unsigned char i,val=0;
DATA=1; //释放数据线
for(i=0x80;i>0;i>>=1) //高位为1,循环右移 {
SCK=1; if(DATA) val=(val|i); //读一位数据线的值
SCK=0;
}
DATA=!ack; //如果是校验,读取完后结束通讯;
SCK=1;
_nop_();_nop_();_nop_(); //延时3us
SCK=0;
_nop_();_nop_();_nop_();
DATA=1; //释放数据线
return val;
}
//启动传输
void s_transstart(void)
// generates a transmission start
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______
{
DATA=1; SCK=0; //准备
_nop_();
SCK=1;
_nop_();
DATA=0;
_nop_();
SCK=0;
_nop_();_nop_();_nop_();
SCK=1;
_nop_();
DATA=1;
_nop_();
SCK=0;
}
//连接复位
void s_connectionreset(void)
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart // _____________________________________________________ ________ // DATA: |_______| // _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______ {
unsigned char i;
DATA=1; SCK=0; //准备
for(i=0;i
{
SCK=1;
SCK=0;
}
s_transstart(); //启动传输
}
//软复位程序
char s_softreset(void)
// resets the sensor by a softreset
{
unsigned char error=0;
s_connectionreset(); //启动连接复位
error+=s_write_byte(RESET); //发送复位命令
return error; //error=1 通讯错误 }
/*读状态寄存器
char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
{
unsigned char error=0;
s_transstart(); //transmission start error=s_write_byte(STATUS_REG_R); //send command to sensor *p_value=s_read_byte(ACK); //read status register (8-bit)
*p_checksum=s_read_byte(noACK); //read checksum (8-bit) return error; //error=1 in case of no response form the sensor
}
//写状态寄存器
char s_write_statusreg(unsigned char *p_value)
// writes the status register with checksum (8-bit)
{
unsigned char error=0;
s_transstart(); //transmission start error+=s_write_byte(STATUS_REG_W);//send command to sensor error+=s_write_byte(*p_value); //send value of status register
return error; //error>=1 in case of no response form the sensor
} */
//温湿度测量
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
// 进行温度或者湿度转换,由参数mode 决定转换内容;
{
// enum {TEMP,HUMI}; //已经在头文件中定义
unsigned error=0;
unsigned int i;
s_transstart(); //启动传输
switch(mode) //选择发送命令
{
case TEMP : error+=s_write_byte(MEASURE_TEMP); break; //测量温度
case HUMI : error+=s_write_byte(MEASURE_HUMI); break; //测量湿度
default : break;
}
for (i=0;i
*(p_value) =s_read_byte(ACK); //读第一个字节,高字节 (MSB) *(p_value+1)=s_read_byte(ACK); //读第二个字节,低字节 (LSB)
*p_checksum =s_read_byte(noACK); //read CRC校验码
return error; // error=1 通讯错误
}
//温湿度值标度变换及温度补偿
void calc_sth10(float *p_humidity ,float *p_temperature)
{
const float C1=-4.0; // 12位湿度精度 修正公式 const float C2=+0.0405; // 12位湿度精度 修正公式 const float C3=-0.0000028; // 12位湿度精度 修正公式 const float T1=+0.01; // 14位温度精度 5V条件 修正公式
const float T2=+0.00008; // 14位温度精度 5V条件 修正公式
float rh=*p_humidity; // rh: 12位 湿度 float t=*p_temperature; // t: 14位 温度 float rh_lin; // rh_lin: 湿度 linear值 float rh_true; // rh_true: 湿度 ture值 float t_C; // t_C : 温度 ℃
t_C=t*0.01 - 40; //补偿温度
rh_lin=C3*rh*rh + C2*rh + C1; //相对湿度非线性补偿
rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //相对湿度对于温度依赖性补偿
if(rh_true>100)rh_true=100; //湿度最大修正
if(rh_true
*p_temperature=t_C; //返回温度结果
*p_humidity=rh_true; //返回湿度结果
}
//从相对温度和湿度计算露点
/*float calc_dewpoint(float h,float t)
{
float logEx,dew_point;
logEx=0.66077+7.5*t/(237.3+t)+(log10(h)-2);
dew_point = (logEx - 0.66077)*237.3/(0.66077+7.5-logEx); return dew_point;
} */
/***********************************************************************************************************************************************************/ //DS1602程序(1602.c ):
//#include
//内部等待函数************************************************************** unsigned char LCD_Wait(void)
{
RS=0;
RW=1; _nop_();
E=1; _nop_();
E=0;
return DBPort;
}
//向LCD 写入命令或数据********************************************************
#define LCD_COMMAND 0 // Command #define LCD_DATA 1 // Data #define LCD_CLEAR_SCREEN 0x01 // 清屏
#define LCD_HOMING 0x02 // 光标返回原点 void LCD_Write(bit style, unsigned char input) {
E=0;
RS=style;
RW=0; _nop_();
DBPort=input; _nop_();//注意顺序 E=1; _nop_();//注意顺序 E=0; _nop_(); LCD_Wait(); }
//设置显示模式************************************************************ #define LCD_SHOW 0x04 //显示开 #define LCD_HIDE 0x00 //显示关
#define LCD_CURSOR 0x02 //显示光标
#define LCD_NO_CURSOR 0x00 //无光标
#define LCD_FLASH 0x01 //光标闪动 #define LCD_NO_FLASH 0x00 //光标不闪动
void LCD_SetDisplay(unsigned char DisplayMode) {
LCD_Write(LCD_COMMAND, 0x08|DisplayMode); }
//设置输入模式************************************************************ #define LCD_AC_UP 0x02
#define LCD_AC_DOWN 0x00 // default
#define LCD_MOVE 0x01 // 画面可平移 #define LCD_NO_MOVE 0x00 //default
void LCD_SetInput(unsigned char InputMode) {
LCD_Write(LCD_COMMAND, 0x04|InputMode); }
//初始化LCD************************************************************ void LCD_Initial()
{
E=0;
LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,5*7点阵 LCD_Write(LCD_COMMAND,0x38);
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标 LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不动 }
//液晶字符输入的位置************************ void GotoXY(unsigned char x, unsigned char y) {
if(y==0)
LCD_Write(LCD_COMMAND,0x80|x); if(y==1)
LCD_Write(LCD_COMMAND,0x80|(x-0x40)); }
//将字符输出到液晶显示
void Print(unsigned char *str) {
while(*str!='\0') {
LCD_Write(LCD_DATA,*str); str++; } }
/***********************************************************************************************************************************************************/ //主函数(main.c ):
//#include
typedef union //定义共用同类型 { unsigned int i; float f; } value;
//延时函数
void delay(int z) //z为毫秒数 { int x,y;
for(x=z;x>0;x--) for(y=125;y>0;y--); }
void main() { unsigned int temp,humi; value humi_val,temp_val; //定义两个共同体,一个用于湿度,一个用于温度 // float dew_point; //用于记录露点值 unsigned char error; //用于检验是否出现错误 unsigned char checksum; //CRC uchar wendu[6]; //用于记录温度 uchar shidu[6]; //用于记录湿度 LCD_Initial(); //初始化液晶 GotoXY(0,0); //选择温度显示位置 Print("TEMP: %C"); //5格空格 GotoXY(0,1); //选择湿度显示位置 Print("HUMI: %RH"); //5格空格 s_connectionreset(); //启动连接复位 while(1) { error=0; //初始化error=0,即没有错误 error+=s_measure((unsigned char*)&temp_val.i,&checksum,TEMP); //温度测量 error+=s_measure((unsigned char*)&humi_val.i,&checksum,HUMI); //湿度测量 if(error!=0) s_connectionreset(); ////如果发生错误,系统复位 else { h umi_val.f=(float)humi_val.i; //转换为浮点数 temp_val.f=(float)temp_val.i; //转换为浮点数 calc_sth10(&humi_val.f,&temp_val.f); //修正相对湿度及温度
// dew_point=calc_dewpoint(humi_val.f,temp_val.f); //计算e dew_point t emp=temp_val.f*10; humi=humi_val.f*10; GotoXY(5,0); //设置温度显示位置 wendu[0]=temp/1000+'0'; //温度百位 //温度十位 //设置湿度显示位置 //湿度十位 } //等待足够长的时间,以现行下一次转换 }}
wendu[1]=temp%1000/100+'0'; w endu[2]=temp%100/10+'0'; //温度个位 wendu[3]=0x2E; //小数点 w endu[4]=temp%10+'0'; //温度小数点后第一位 P rint(wendu); //输出温度 GotoXY(5,1); s hidu[0]=humi/1000+'0'; //湿度百位 shidu[1]=humi%1000/100+'0'; s hidu[2]=humi%100/10+'0'; //湿度个位 shidu[3]=0x2E; //小数点 s hidu[4]=humi%10+'0'; //湿度小数点后第一位 P rint(shidu); //输出湿度 delay(800);