【无标题】基于51单片机和DHT11的温湿度检测系统

 

基于51单片机的温湿度检测系统

摘 要:设计一款能够实时检测当前空气温度和湿度的装置。主控芯片采用STC12C5A60S2芯片,温湿度传感器采用DHT11数字温湿度传感器,显示屏幕采用OLED屏幕。整个设计采用模块化设计,分别为三大模块。分别为MCU模块,检测模块和显示模块。当环境中的温湿度发生变化时,DHT11温湿度传感器随着温度、湿度的变化而变化,然后将变化的电阻通过转换电路和转换信号检测为相对应变化的电压,然后把模拟电压信号由A/D转换器转换为数字信号并送入到单片机中,单片机处理之后控制OLED显示屏显示出检测出的温度以及湿度的量值。

关键词:STC12C5A60S2芯片;DHT11数字温湿度传感器;OLED显示屏

  1. 整体方案

1.1总体设计方案

本设计要实现的功能是:实时检测当前空气中的温度和湿度并将检测结果通过OLED显示屏显示出来。

  1. 硬件准备:1块51单片机学习开发板(主控芯片为STC12C5A60S2);1个DHT11温湿度传感器;一块0.96寸的OLED 屏幕;杜邦线若干;一根下载线;Keil5编程软件;stc-isp上位机。
  2. 组装方式:首先先将OLED和dht11的Vcc接+5V电压端口,GND接到开发板的GND端口。其次将OLED和dht11的其他的端口分别与定义好的IO口相连。
  3. 实现过程:单片机上电后,约过1秒后dht11开始正常工作。Dht11将变化的电阻通过转换电路和转换信号检测为相对应变化的电压,然后把模拟电压信号由A/D转换器转换为数字信号并送入到单片机中,单片机接受到传回的数字信号后进行处理转换,再将电信号传给OLED显示屏,OLED接受到单片机传出的信号后将温度和湿度的数值显示出来。

1.2系统设计简图

2.硬件选择

由于51单片机已经上市多年,网上有很多相关的资料且很多同学都掌握了51单片机的基础性知识;OLDE工作方式和原理比较复杂,网上有许多相关的库,使用时只需调用库即可。所以接下来将重点介绍DHT11温湿度传感器的工作原理。

2.1 DHT11温湿度传感器

2.1.1 DHT11知识储备

DHT11是一款有已校准数字信号输出的温湿度传感器。 其精度湿度±5%RH, 温度±2℃,量程湿度20-90%RH,温度0~50℃。传感器包括一个电阻感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准,校准系数以程序的形式存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数,采用单线制串行接口[5],使系统集成变得简易快捷。

2.1.2 DHT11通信协议及数据格式

DHT11 采用单总线协议与单片机通信,单片机发送一次复位信号后,DHT11 从低功耗模式转换到高速模式,等待主机复位结束后,DHT11 发送响应信号,并拉高总线准备传输数据。一次完整的数据为 40bit,按照高位在前,低位在后的顺序传输

数据格式为:8bit 湿度整数数据+8bit 湿度小数数据+8bit 温度整数数+8bit 温度小数数据+8bit 校验和,一共 5 字节(40bit)数据。由于 DHT11 分辨率只能精确到个位,所以小数部分是数据全为 0。校验和为前 4 个字节数据相加,校验的目的是为了保证数据传输的准确性。

2.1.3 DHT11操作时序

(1)主机发送复位信号:DHT11 的初始化过程同样分为复位信号和响应信号。首先主机拉低总线至少 18ms,然后再拉高总线,延时 20~40us,取中间30us,此时复位信号发送完毕。

(2)dht11发送响应信号:DHT11 检测到复位信号后,触发一次采样,并拉低总线 80us 表示响应信号,告诉主机数据已经准备好了;然后 DHT11 拉高总线 80us,之后开始传输数据。当复位信号发送完毕后,如果检测到总线被拉低,就每隔 1us 计数一次,直至总线拉高,计算低电平时间;当总线被拉高后重新计数检测 80us 的高电平。如果检测到响应信号之后的80us 高电平,就准备开始接收数据。实际上 DHT11 的响应时间并不是标准的 80us,往往存在误差,当响应时间处于 30~90us 之间时就可以认定响应成功。

3.程序源码

3.1主程序代码

#include "STC12C5A60S2.h"

#include "Delay.h"

#include "dht11.h"

#include "LCD1602.h"

#include "OLED.h"

void main()

{

    unsigned char Str[3]="00\0";

    OLED_Init();//oled初始化

    OLED_Put16x16CNstr(0,0,"湿度:",1);

    OLED_Put16x16CNstr(0,45,"温度:",1);

    OLED_Refresh_AllGDRAM();//刷新显示

    Delay(500);//大约等待1.5秒

    Delay(500);

    Delay(500);

    while(1)

    {

             DHT11_receive(dat);//温湿度传感器开始采集数据

             Str[0]=dat[2]/10%10+0x30;

             Str[1]=dat[2]%10+0x30;

             OLED_Put12x12CNstr(40,5,Str,1);//显示湿度的整数位

             OLED_Put12x12CNstr(52,5,".",1);//整数和小数之间的点

             Str[1]=dat[3]/10%10+0x30;

             Str[0]=dat[3]%10+0x30;

             OLED_Put12x12CNstr(55,5,Str,1);//显示湿度的小数位

             OLED_Put12x12CNstr(70,5,"%RH",1);//湿度单位

             Str[0]=dat[0]/10%10+0x30;

             Str[1]=dat[0]%10+0x30;

             OLED_Put12x12CNstr(40,50,Str,1);//显示温度的整数位

             OLED_Put12x12CNstr(52,50,".",1);//整数和小数之间的点

             Str[1]=dat[1]/10%10+0x30;

             Str[0]=dat[1]%10+0x30;

             OLED_Put12x12CNstr(55,50,Str,1);//显示温度的小数位

             OLED_Put12x12CNstr(70,40,".",1);

             OLED_Put12x12CNstr(75,50,"C",1);

             OLED_Refresh_AllGDRAM();//刷新显示

    }

}

3.2 dht11模块源码

#include "STC12C5A60S2.h"

#include "Delay.h"

#include

#include "dht11.h"

void DHT11_delay_us(unsigned char n)//微秒

{

    while(--n);

}

void DHT11_delay_ms(unsigned int z)//毫秒

{

   unsigned int i,j;

   for(i=z;i>0;i--)

      for(j=110;j>0;j--);

}

void dht11_start(void)//dht11初始化

{

    dht=1;

    DHT11_delay_us(2);

    dht=0;//主机从高电平转为低电平

    DHT11_delay_ms(220);//主机拉低20ms

    dht=1;//主机拉高,然后模块将总线拉低

    DHT11_delay_us(50);//延时50微秒

    if(dht==0)//读到0,表示检测到响应信号

    {

        led=0;//亮灯表示响应到信号

    }

    else

    {

        led=1;//表示没检测到信号

    }

}

unsigned char DHT11_rec_byte()      //接收一个字节

{

   unsigned char i,dat=0;

  for(i=0;i<8;i++)    //从高到低依次接收8位数据

   {         

      while(!dht);   等待50us低电平过去

      DHT11_delay_us(80);     //延时60us,如果还为高则数据为1,否则为0

      dat<<=1;           //移位使正确接收8位数据,数据为0时直接移位

      if(dht==1)    //数据为1时,使dat加1来接收数据1

         dat+=1;

      while(dht);  //等待数据线拉低   

    } 

    return dat;

}

void DHT11_receive(unsigned char dat[])      //接收40位的数据

{

    unsigned char R_H,R_L,T_H,T_L,revise;

    dht11_start();

    if(dht==0)

    {

        while(dht==0);   //等待拉高    

        DHT11_delay_us(250);  //拉高后延时超过80us(80us时候下降沿,135时候上升)

        R_H=DHT11_rec_byte();    //接收湿度高八位 

        R_L=DHT11_rec_byte();    //接收湿度低八位 

        T_H=DHT11_rec_byte();    //接收温度高八位 

        T_L=DHT11_rec_byte();    //接收温度低八位

        revise=DHT11_rec_byte(); //接收校正位

        DHT11_delay_us(25);    //结束

        if((R_H+R_L+T_H+T_L)==revise)    //校正

        {

            dat[0]=T_H; //温度高8位(表示整数部分)

            dat[1]=T_L; //温度低8位(表示小数部分)

            dat[2]=R_H; //湿度高8位(表示整数部分)

            dat[3]=R_L; //湿度低8位(表示小数部分)

        }

    }

}

4.实际效果图

【无标题】基于51单片机和DHT11的温湿度检测系统_第1张图片

【无标题】基于51单片机和DHT11的温湿度检测系统_第2张图片

你可能感兴趣的:(单片机,51单片机)