51单片机基础之DHT11温湿度传感器

发布者:stampie最新更新时间:2022-10-11 来源: csdn关键字:51单片机  DHT11  温湿度传感器 手机看文章 扫描二维码
随时随地手机看文章

接线: 

代码:


main.c文件

 

/*

使用DHT11模块,检测温湿度,在lcd1602上面显示,因为1602显示不是每次都能出来,所以加了串口打印,会更加直观。

*/

#include

#include "lcd.h"

#include

#include

 

sbit Temp_data=P3^6; //信号引脚

 

unsigned int rec_dat[4];

unsigned char rec_dat_lcd0[6];

unsigned char rec_dat_lcd1[6];

unsigned char rec_dat_lcd2[6];

unsigned char rec_dat_lcd3[6];

 

void DHT11_delay_us(unsigned char n);

void DHT11_delay_ms(unsigned int z);

void DHT11_start();

unsigned char DHT11_rec_byte();

void DHT11_receive();

void InitUART(void);

 

//主函数

void main()

{

InitUART(); //串口中断初始化

P1=0xf0;

InitLcd1602();

LcdShowStr(0,0,"Shidu:");

LcdShowStr(0,1,"Wendu:");

 

while(1)

{

DHT11_delay_ms(150);

DHT11_receive();

 

//这个函数是打印字符函数,应该是起到数值转化的作用。

sprintf(rec_dat_lcd0,"%d",rec_dat[0]);

sprintf(rec_dat_lcd1,"%d",rec_dat[1]);

sprintf(rec_dat_lcd2,"%d",rec_dat[2]);

sprintf(rec_dat_lcd3,"%d",rec_dat[3]);

DHT11_delay_ms(100);

//湿度

LcdShowStr(7,0,rec_dat_lcd0);

LcdShowStr(9,0,".");

LcdShowStr(10,0,rec_dat_lcd1);

LcdShowStr(11,0," %");

//温度

LcdShowStr(7,1,rec_dat_lcd2);

LcdShowStr(9,1,".");

LcdShowStr(10,1,rec_dat_lcd3);

LcdShowStr(11,1," C");

//下面通过串口助手打印温度

//我也为什么他不用中断服务函数,就可以打印,那好需要这个中断干嘛,不是可以直接打印吗?这是我的疑问。

printf("Humi:%d.%d n",rec_dat[0],rec_dat[1]);

printf("Temp:%d.%d °Cn",rec_dat[2],rec_dat[3]);

}

}

 

//DHT11起始信号

void DHT11_start()

{

Temp_data=1;

DHT11_delay_us(2);

Temp_data=0;

DHT11_delay_ms(20);

Temp_data=1;

DHT11_delay_us(13);

}

 

//接收一个字节

unsigned char DHT11_rec_byte()

{

unsigned char i,dat;

for(i=0;i<8;i++)

{

while(!Temp_data);

  DHT11_delay_us(8);

dat<<=1;

if(Temp_data==1)

{

dat+=1;

}

while(Temp_data);

}

return dat;

}

 

//接收温湿度数据

void DHT11_receive()

{

unsigned int R_H,R_L,T_H,T_L;

unsigned char RH,RL,TH,TL,revise;

DHT11_start();

Temp_data=1;

if(Temp_data==0)

{

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

        DHT11_delay_us(40);  //拉高后延时80us

        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)      //校正

        {

            RH=R_H;

            RL=R_L;

            TH=T_H;

            TL=T_L;

        } 

        /*数据处理,方便显示*/

        rec_dat[0]=RH;

        rec_dat[1]=RL;

        rec_dat[2]=TH;

        rec_dat[3]=TL;

}

}

//延时us   --2*n+5us

void DHT11_delay_us(unsigned char n)

{

    while(--n);

}

 

//延时ms

void DHT11_delay_ms(unsigned int z)

{

   unsigned int i,j;

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

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

}

 

//使用定时器1作为串口波特率发生器

void InitUART(void)

{

TMOD=0x20; //定时器1的工作方式2

SCON=0x40; //串口通信工作方式1

REN=1; //允许接收

TH1=0xFD,TL1=0xFD; //波特率=9600

TI=1;                       //这里一定要注意

TR1=1;

EA = 1;                  //开总中断

}


Lcd.c文件

 

#include"lcd.h"

 

void Lcd1602_Write_Cmd(unsigned char cmd)     //写命令

{

    //Read_Busy();

    LCD1602_RS = 0;

    LCD1602_RW = 0;

    LCD1602_DB = cmd;

LCD_Delay10ms(1);

    LCD1602_EN = 1;

LCD_Delay10ms(1);

    LCD1602_EN = 0;    

}

 

void Lcd1602_Write_Data(unsigned char dat)   //写数据

{

      //Read_Busy();

      LCD1602_RS = 1;

      LCD1602_RW = 0;

      LCD1602_DB = dat;

LCD_Delay10ms(1);

      LCD1602_EN = 1;

LCD_Delay10ms(1);

      LCD1602_EN = 0;

}

//指定位置开始显示数据!

void LcdSetCursor(unsigned char x,unsigned char y)  //坐标显示

{

    unsigned char addr;

    if(y == 0)

        addr = 0x00 + x;//第一行开始,x表示一行的第x个

    else

        addr = 0x40 + x;//第二行开始,x表示一行的第x个

    

    Lcd1602_Write_Cmd(addr|0x80);

}

 

void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str)     //显示字符串

{

    LcdSetCursor(x,y);      //当前字符的坐标

    while(*str != '')

    {

        Lcd1602_Write_Data(*str++);

    }

}

 

void InitLcd1602()              //1602初始化

{

    Lcd1602_Write_Cmd(0x38);    //打开,5*8,8位数据

    Lcd1602_Write_Cmd(0x0c);

    Lcd1602_Write_Cmd(0x06);

    Lcd1602_Write_Cmd(0x01);    //清屏   

}

 

void LCD_Delay10ms(unsigned int c)   //误差 0us

{

    unsigned char a,b;

    for(;c>0;c--)

        for(b=38;b>0;b--)

            for(a=130;a>0;a--);

}


Lcd.h文件

 

#ifndef __LCD_H_

#define __LCD_H_

/**********************************

当使用的是4位数据传输的时候定义,

使用8位取消这个定义

**********************************/

//#define LCD1602_4PINS

/**********************************

包含头文件

**********************************/

#include

//---重定义关键词---//

#ifndef uchar

#define uchar unsigned char

#endif

#ifndef uint 

#define uint unsigned int

#endif

/**********************************

PIN口定义

**********************************/

#define LCD1602_DB  P0      //data bus 数据总线

sbit LCD1602_RS = P2^6;

sbit LCD1602_RW = P2^5;

sbit LCD1602_EN = P2^7;  

/**********************************

函数声明

**********************************/

/*在51单片机12MHZ时钟下的延时函数*/

//void Lcd1602_Delay1ms(uint c);   //误差 0usvo

void LCD_Delay10ms(unsigned int c);

//void Read_Busy();           //忙检测函数,判断bit7是0,允许执行;1禁止

void Lcd1602_Write_Cmd(unsigned char cmd);     //写命令

void Lcd1602_Write_Data(unsigned char dat);   //写数据

void LcdSetCursor(unsigned char x,unsigned char y);  //坐标显示

void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str);     //显示字符串

void InitLcd1602();              //1602初始化

  

#endif


运行结果:

 

关键字:51单片机  DHT11  温湿度传感器 引用地址:51单片机基础之DHT11温湿度传感器

上一篇:51单片机基础之DS1302
下一篇:51单片机基础之串口通信

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved