电子开发网

电子开发网电子设计 | 电子开发网Rss 2.0 会员中心 会员注册
搜索: 您现在的位置: 电子开发网 >> 电子开发 >> 单片机实例 >> 正文

基于51单片机的SHT11温湿度测量仪设计(源码+仿真+文档)

作者:佚名    文章来源:本站原创    点击数:    更新时间:2023/7/1

电路原理图如下:

 


仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)

 
 

 

一、总体设计要求3
二、方案论证 3
三、系统硬件设计 3
3.1复位电路3
3.2时钟电路3
3.3 温湿度测量电路4
3.4显示电路5
四、系统软件设计
4.1DHT11软件设计6
4.2软件设计流程图 6
4.3 原理图以及原理分析7
五、电路仿真及仿真结果分析
5.1电路仿真图 7
5.2仿真结果分析 8
六、心得体会8
七、参考文献9

 

一、总体设计要求:

1、能够检测出环境中的温度和湿度,并且显示在LCD1602上面

2、技术参数有以下要求:
湿度测量范围:0%~100%RH;温度测量范围-40~+110℃。

湿度测量分辨率:1%RH;温度测量分辨率:1℃。

湿度测量精度:±2.0%RH;温度测量精度:±0.5℃。

3、电源工作范围:DC 4.5~5.5V。


二、构思与选择:

方案一:

使用AM2301数字温湿度传感器。该型号温湿度传感器,采用3.3—6V直流电源供电,它的各部分参数:湿度测量范围为20%~90%RH;温度测量的范围为0~+50℃;湿度测量精度为±5.0%RH;温度测量精度为±2.0℃。虽然它的价格比较便宜,单测温的范围和测湿的范围太小,温度的精度和湿度的精度太低,不符合设计的要求。

方案二:

使用AM2302电容式数字温湿度传感器。它的各部分参数如下:由于传感器参数:湿度0%~100%相对是湿度的测量范围;温度测量范围为40~+80℃;湿度的测量精度为±3.0%RH;温度的测量精度为±0.5℃。价格也比较适合,基本可以满足设计要求。

方案三:

使用数字温湿度传感器SHT11。湿度测量范围:0%~100%RH;温度测量范围:40~+120℃;湿度测量精度:±2%相对湿度;温度测量精度:±0.2%℃温度测量精度。改传感器价格便宜。温度和湿度都达到或超过了标题的精度要求,属于低功率传感器。

综上分析,设计应以最大化利用内部资源,电路简易,节约成本为原则,而且利用从系统技术参数要求和低功率方面考虑。因此采用方案三。


三、系统硬件设计:

3.1复位电路:

复位是单片机的初始化操作。单片机启动运行时,都需要先复位,作用是使CPU和系统中其他部件处于一个确定的初始状态,并从这个状态开始工作。因此,复位是一个很重要的操作方式。但单片机本身是不能自动进行复位的,必须配合相应的外部电路才能实现。

单片机通电时,从初始态开始执行程序,称为上电复位。单片机死机时,通过手工按“重启”键使其从初始态开始执行程序,称为手工复位。

复位条件:复位引脚RST(全称RESET)出现2个机器周期以上的高电平时,单片机就执行复位操作;但如果RST持续为高电平,单片机就处于循环复位状态。

3.2时钟电路:

1.时钟电路

利用芯片内部的振荡电路,在XTAL1、XTAL2的引脚上外接定时元件,内部振荡器便能产生自激振荡。定时元件可以采用石英晶体和电容组成的并联谐振电路。

晶振可以在1.2~12MHZ之间任选,甚至可以达到24MHz,但是频率越高功耗也就越大。和晶振并联的电容C1、C2的大小对振荡频率有微小影响,可以起到频率微调作用。当采用石英晶振时,电容可以在20~40pF之间选择。晶体和电容应尽可能与单机片芯片靠近,以减少引线的寄生电容,保证振荡器可靠工作。

 

 

3.3.温湿度测量电路:

 

 

SHT11是瑞士Scnsirion公司推出的一款数字温湿度传感器芯片。该芯片广泛应用于暖通空调、汽车、消费电子、自动控制等领域。共主要特点如下: 高度集成,将温度感测、湿度感测、信号变换、A/D转换和加热器等功能集成到一个芯片上;提供二线数字串行接口SCK和DATA,接口简单,支持CRC传输校验,传输可靠性高;测量精度可编程调节,内置A/D转换器(分辨率为8~12位,可以通过对芯片内部寄存器编程选择); 测量精确度高,由于同时集成温湿度传感器,可以提供温度补偿的湿度测量值和高质量的露点计算功能;封装尺寸超小(7.62 mm×5.08mm×2.5 mm),测量和通信结束后,自动转入低功耗模式; 高可靠性,采用CMOSens工艺,测量时可将感测头完全浸于水中。SHT11温湿度传感器采用SMD(LCC)表面贴片封装形式,接口非常简单,引脚名称及排列顺序如图下所示。

 

仿真电路图

 

 

3.4、显示电路:
3.4.1电路工作原理

该模块采用LCD1602液晶屏将电子时钟工作的实时状态显示在屏幕上,结构简单,显示清晰。其中GND接地,VCC接VCC,LCD偏压输入引脚V0通过接一个电位器来调节显示屏的背光度,数据/命令选择端RS、读/写控制信号端RW、LCD使能端分别由单片机引脚P2.6、P2.5、P2.7进行控制。数据传输端D0-D7则用单片机的P0口进行控制。如图是LCD1602详细的电路引脚连线图。
 

 

3.4.2LCD显示模块电路图

 

系统软件设计:

   4.1.1 DHT11软件设计
微处理器和温湿度传感器通信采用串行二线接口SCK和DATA,其中SCK为时钟线,DATA为数据线。该二线串行通信协议和I2C协议是不兼容的。在程序开始,微处理器需要用一组"启动传输"时序表示数据传输的启动,当SCK时钟为高电平时,DATA翻转为低电平;紧接着SCK变为低电平,随后又变为高电平;在SCK时钟为高电平时,DATA再次翻转为高电平。
根据SHT11湿度测试时序可以知道。主机发出启动命令,随后发出一个后续8位命令码,该命令码包含3个地址位(芯片设定地址为000)和5个命令位;发送完该命令码,将DATA总线设为输入状态等待SHT11的响应;SHT11接收到上述地址和命令码后,在第8个时钟下降沿,将DATA下拉为低电平作为从机的ACK;在第9个时钟下降沿之后,从机释放DATA(恢复高电平)总线;释放总线后,从机开始测量当前湿度,测量结束后,再次将DATA总线拉为低电平;主机检测到DATA总线被拉低后,得知湿度测量已经结束,给出SCK时钟信号;从机在第8个时钟下降沿,先输出高字节数据;在第9个时钟下降沿,主机将DATA总线拉低作为ACK信号。然后释放总线DATA;在随后8个SCK周期下降沿,从机发出低字节数据;接下来的SCK下降沿,主机再次将DATA总线拉低作为接收数据的ACK信号;最后8个SCK下降沿从机发出CRC校验数据,主机不予应答(NACK)则 表示测量结束。
4.1.2总体程序流图的设计:

 

4.3.原理图以及原理分析:

 

 


通过AD19绘制出如上图所示的原理图,包括时钟电路、晶振电路、DHT11温湿度检测电路、lcd1602显示电路,因为温湿度传感器与单片机连接电路比较简单。所以可以容易的绘制出电路图。

 

五、仿真图及仿真分析:

 

5.1、总体仿真结果:

 

 


5.2、仿真分析:

首先,将程序的hex文件加载到单片机中,开始仿真。可以清楚地看到LCD1602上面显示了SHT11当前的温度和湿度,虽然有误差但是误差并不是很大可以忽略不计,调节传感器上面的按钮可以实时的将传感器所在环境的温度显示到LCD1602上面,具有可控性,而且显示性和可控性较好。

 

六、心得体会:

我这次做的是基于单片机的温湿度测量仪。我们知道,单片机和传感器的应用如今已经在工业、电子等方方面面展示出了它的优越性,利用单片机和传感器设计电路也逐渐成了趋势,它与外围的简单电路再加上优化程序就可以构建任意的产品,使得这次设计成为现实。随着单片机和传感器的日益发展,它们必将在未来显示出更大的活力,为人们提供更好的产品。
虽然这个电路我已经设计出来了,但是在这次的设计当中,我遇到了不少的问题。最开始我不知道要用哪一种传感器作为我的设计,纠结了好久,最终我确定了选择用DHT11作为我的温湿度传感器模块,因为老师说不能用书本上的DS18B20作为此次设计模块,因为书上有该模块的详细电路图原理图以及写好的程序,所以我就仔细的查阅资料,结合以前在实验室学习的经验,通过一个多星期的时间来准备,从方案的选择原理图的绘制再到程序的编写和仿真图的绘制和调试,最终顺利的完成了这一次的传感器设计。
在学习传感器与检测技术这门中,我的收获是特别大的,完成这次设计,不仅巩固了单片机的知识,而且对传感器与单片机的应用也熟悉了基本的操作方法。相信在以后的设计中,就会排除现在遇到的问题,更好的完成设计。以前我不知道传感器到底是什么,只是在字面上理解它的意思,把一个物理量转换成另外一个物理量。但是传感器没有我们想象的那么简单,它有它的工作原理,使用条件。通过这一个学期的学习,我学习了好多传感器,比如说:温度传感器、湿度传感器、位移传感器、压力传感器等等,现在的我大致地能理解他们的一些特性,也能够运用他们来设计作品。在这里,我非常感谢我的老师。同时,对于这门课,我也想提出一些建议,希望我们班能够经常开设一些关于传感器设计与制作的活动。这样既能提高我们的动手水平,也能开发我们设计传感器的思维。

单片机源程序如下:

#include "all.h"
typedef union    
{ 
  uint i;        //定义了两个共用体   
  float f;  
} value;   
  enum 
  {
          TEMP,HUMI   //TEMP=0,HUMI=1
  };
void s_transstart(void)   // 生成传输启动
{        
        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)  
{       
        uchar i;      
        DATA=1; 
        SCK=0;                          
        for(i=0;i<9;i++)                  
        {       
                SCK=1;     
                SCK=0;    
        }     
        s_transstart();                   //传输开始
}
char s_write_byte(uchar value)   //在敏总线上写入一个字节并检查应答  
{      
        uchar i,error=0;       
        for (i=0x80;i>0;i/=2)              
        {        
                if(i&value) 
                        DATA=1;          //用i屏蔽值,写入敏总线   
                else 
                        DATA=0;                               
                SCK=1;                            
                _nop_();_nop_();_nop_();          
                SCK=0;    
        }     
        DATA=1;                           //释放数据线
        SCK=1;                              
        error=DATA;                       //DATA在第9个上升沿将被DHT90自动下拉为低电平。    
        _nop_();_nop_();_nop_();   
        SCK=0;    
        DATA=1;                           //释放数据线 
        return error;                     //返回:0成功,1失败 
}
char s_read_byte(uchar ack)        // 从敏感总线读取字节,并在“ack=1”的情况下给出确认
{      
        uchar i,val=0;     
        DATA=1;                           //释放数据线 
        for (i=0x80;i>0;i/=2)             //shift bit for masking
        { 
                SCK=1;                          //clk for SENSI-BUS      
                if (DATA) val=(val|i);        //read bit      
                _nop_();_nop_();_nop_();        //pulswith约3 us     
                SCK=0;                 
        }     
        if(ack==1)
            DATA=0;                          //如果“ack==1”下拉数据线   
        else DATA=1;                      //如果是校验(ack==0),读取完后结束通讯   
            _nop_();_nop_();_nop_();          //pulswith约3 us    
        SCK=1;                            //clk #9 for ack    
        _nop_();_nop_();_nop_();          //pulswith约3 us     
        SCK=0;                     
        _nop_();_nop_();_nop_();          //pulswith约3 us    
        DATA=1;                           //释放数据线   
        return val;  
}
char s_measure(uchar *p_value,uchar *p_checksum,uchar mode)  //用校验和进行测量(湿度/温度)
{      
        uint error=0;    
        uint 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<65535;i++) 
        if(DATA==0) 
                break;                        //等待传感器完成测量
        if(DATA) error+=1;                // 或超时(~2秒)   
                *(p_value)  =s_read_byte(ACK);    //读取第一个字节(MSB)
                *(p_value+1)=s_read_byte(ACK);    //读取第二个字节(LSB) 
                *p_checksum =s_read_byte(noACK);  //读取校验和
        return error;  
}
void calc_dht90(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位   
        const float T2=+0.00008;           // 14位
        float rh=*p_humidity;             // rh:      湿度[滴答声]12位    
        float t=*p_temperature;           // t:       温度[刻度]14位  
        float rh_lin;                     // rh_lin:  湿度线性   
        float rh_true;                    // rh_true: 温度补偿湿度
        float t_C;                        // t_C   :  温度 [C]     
        t_C=t*0.01-40;                  // 温度从刻度到[C]  
        rh_lin=C3*rh*rh+C2*rh+C1;     
        rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;   //.温度补偿湿度[%RH]
        if(rh_true>100)rh_true=100;       //如果值在外面,则削减   
        if(rh_true<0.1)rh_true=0.1;       //物理可能范围  
……………………
…………限于本文篇幅 余下代码请从下载附件…………

基于51单片机的SHT11温湿度测量仪设计.rar
www.dzkfw.com.cn/Article/UploadFiles/202307/2023070115583466.rar

Tags:温湿度,温湿度测量,51单片机  
责任编辑:admin
相关文章列表
基于51单片机的恒温控制器系统 protues+keil c
51单片机数码管显示程序, 共阴数码管显示程序 数码管原理(显示
51单片机学习笔记直流电机驱动(PWM)C语言程序
MCU-51单片机直流电机驱动(PWM)51单片机驱动直流电机
先学51还是先学STM32?STM32和51单片机的区别
51单片机和STM32单片机的结构有什么不同
51单片机、AVR单片机和PIC单片机的IO口操作
在西门子plc 200smart中,通过Modbus RTU协议读取温湿度传感器的
关于51单片机IO引脚的驱动能力与上拉电阻
51单片机“呼吸灯”程序
51单片机入门之静态数码管电路设计
AT89C51,51单片机1602液晶显示时钟程序
4位单片机数字钟 电子钟制作
51单片机4位数码管电子钟源程序
AT89C2051电脑机箱风扇智能温控仪,AT89C2051 Temperature contro
51单片机温控风扇(含程序+原理图+仿真+PCB)
51单片机蜂鸣器播放音乐代码
利用单片机AT89S51与ADC0809设计数字电压表,Voltmeter
单片机制作的纯正弦波逆变器,12V Pure Sine Wave Inverter
51单片机00-59秒计时器 0-59s Timer
51单片机按键程序中 while(!key)的作用
51系列单片机寻址方式
认识单片机引脚【详解】
用51单片机设计的无线防盗报警器技术
51单片机汇编模拟串口通信程序
51单片机双极型PWM 的软件实现
用51单片机制作的厨房定时器
51单片机的液晶显示温度计程序
51单片机定时系统
51单片机扩展RAM读写子程序
请文明参与讨论,禁止漫骂攻击,不要恶意评论、违禁词语。 昵称:
1分 2分 3分 4分 5分

还可以输入 200 个字
[ 查看全部 ] 网友评论
关于我们 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 在线帮助 - 文章列表
返回顶部
刷新页面
下到页底
晶体管查询