51单片机DHT11测量温湿度在LCD1602上显示

img

问题:主机发送信号后DHT11无响应,求解答,谢谢!
代码如下:
lcd1602.h

#ifndef _LCD1602_H_
#define _LCD1602_H_

#define uchar unsigned char 
#define uint unsigned int 

#define data_1602 P0
uchar code table_num[]="0123456789abcdefg";

sbit rs=P2^5;     //¼Ä´æÆ÷Ñ¡ÔñÐźŠH:Êý¾Ý¼Ä´æÆ÷      L:Ö¸Áî¼Ä´æÆ÷
sbit rw=P2^6;     //¼Ä´æÆ÷Ñ¡ÔñÐźŠH:Êý¾Ý¼Ä´æÆ÷      L:Ö¸Áî¼Ä´æÆ÷
sbit e =P2^7;     //ƬѡÐźŠ  ϽµÑØ´¥·¢




/***********************ÑÓʱº¯Êý************************/
void delay_uint(uint q)
{
    while(q--);
}

/***********************lcd1602дÃüÁÊý************************/
void write_com(uchar com)
{
    e=0;
    rs=0;
    rw=0;
    data_1602=com;
    delay_uint(10);
    e=1;
    delay_uint(50);
    e=0;
}

/***********************lcd1602дÊý¾Ýº¯Êý************************/
void write_data(uchar dat)
{
    e=0;
    rs=1;
    rw=0;
    data_1602=dat;
    delay_uint(10);
    e=1;
    delay_uint(50);
    e=0;    
}

/***********************lcd1602³õʼ»¯ÉèÖÃ************************/
void init_1602()
{
    write_com(0x38);    //
    write_com(0x0c);
    write_com(0x06);
}




/***********************lcd1602ÉÏÏÔʾÕâ×Ö·ûº¯Êý************************/
void write_string(uchar hang,uchar add,uchar *p)
{
    if(hang==1)   
        write_com(0x80+add);
    else
        write_com(0x80+0x40+add);
        while(1)                                                         
        {
            if(*p == '\0')  break;
            write_data(*p);
            p++;
        }    
        
}
void write_sfm2(uchar hang,uchar add,uint date)
{
    uchar ge,shi;
    if(hang==1)   
        write_com(0x80+add);
    else
        write_com(0x80+0x40+add);
    ge=date%10;
    date=date/10;
    shi=date%10;

      write_data(table_num[shi]);    
      write_data(table_num[ge]);

    
}




/****************¿ª»úÒº¾§ÏÔʾº¯Êý ³õʼ»¯Òº¾§µÄÄÚÈÝ********************************/
void init_1602_dis_csf()
{
    write_string(1,2,"WD:");  
    write_string(2,2,"SD:"); 
write_string(1,9,".");
write_string(2,9,".");    
    write_string(1,13,"C");
write_string(2,13,"%");

}



main.c

#include 
#include "lcd1602.h"

sbit DATA = P2^0; //DHT11 数据引脚

unsigned char DHTDATA[5] = {'\0'}; //存放温湿度40位 数据

// 延时10*n微秒
void delayus(unsigned int n)
{
    unsigned char i;
    i = 2*n;
    while (--i);
}

//延时n毫秒
void delayms(unsigned int n)
{
    unsigned int i,y;
    for(i=n;i>0;i--)
        for(y=114;y>0;y--);
}


/*DHT11接收数据函数*/
unsigned char DHT_receive_data()
{
    unsigned char i;
    unsigned char dat=0;  //0000 0000

        
    for(i=0;i<8;i++)
    {
        while(!DATA); //等待DHT 50us低电平信号过去
        delayus(3); //延时大概30us 如何还是高电平 则为1
        

        dat<<=1; //左移一位 因为数据是从高位开始传
        if(DATA == 1)
        {
            dat|=0x01;
        }
        while(DATA); //等待DHT 拉低 准备下一位开始

    }
    return dat;
    
}


/*DHT11读取函数*/
void DHT_receive()
{
    unsigned char R_H,R_L,T_H,T_L,CHECK;
    
    /*主机发送信号*/
    DATA = 1;
    delayus(3);
    DATA = 0;
    delayms(20); //延时大于18ms
    DATA=1;
    delayus(3);     //延时30us  20-40us 均可

    DATA=1;
    if(DATA == 0)   //判断DHT是否进入响应
    {

        while(!DATA);       //等待从机80us低电平响应信号过去
        while(DATA); //等待从机80us高电平信号过去

           /*获取温湿度数据*/
        R_H = DHT_receive_data();    //湿度整数部分
        R_L = DHT_receive_data();    //湿度小数部分
        T_H = DHT_receive_data();    //温度整数部分
        T_L = DHT_receive_data();    //温度小数部分

        CHECK = DHT_receive_data(); //校验位

        DATA=0; //当最后一bit数据传送完毕后,DHT11拉低总线 50us
        delayus(5); //这里延时55us
        DATA=1;    //随后总线由上拉电阻拉高进入空闲状态。
    
        /*校验接收到的数据是否正确*/
        if((R_H + R_L + T_H + T_L) == CHECK) 
        {
            DHTDATA[0] = R_H;
            DHTDATA[1] = R_L;
            DHTDATA[2] = T_H;
            DHTDATA[3] = T_L;
            
        }
            
    }
}

/*显示DHT11数据函数*/
void DHT_display()
{
write_sfm2(1,7,DHTDATA[2]);
write_sfm2(1,10,DHTDATA[3]);
write_sfm2(2,7,DHTDATA[0]);
write_sfm2(2,10,DHTDATA[1]);
}



/*主函数入口*/
void main()
{

    init_1602(); //初始化1602
  init_1602_dis_csf();

    while(1)
    {
        delayms(1000); //等待 1s 以越过不稳定状态
        DHT_receive();   //DHT11读取函数
        DHT_display();//1602显示温湿度
                    
    }
}


DHT11模块未正确连接:请检查DHT11模块的引脚连接是否正确,包括DATA、VCC和GND。

主机发送的信号不正确:根据代码分析,主机通过将DATA引脚拉低并持续一段时间,再释放DATA引脚,来触发DHT11的数据读取。请确认发送信号的时间和方式是否正确。

DHT11模块损坏:如果以上两种情况均未发现问题,可以考虑更换DHT11模块,或使用另一台主机进行测试。

建议:

首先检查引脚连接是否正确,并确认是否给DHT11模块供电,VCC和GND是否正确连接。

确认主机发送的信号是否正确,可以使用示波器或逻辑分析仪等工具进行验证。

如果以上两种情况均未发现问题,可以考虑更换DHT11模块或使用另一台主机进行测试。

建议在程序中增加适当的错误处理和异常处理机制,便于排查问题和维护代码。

以下内容部分参考ChatGPT模型:


问题的原因可能是主机发送信号的时候没有成功发送信号,或者是DHT11没有正确响应。可以在代码中添加一些调试信息,比如在发送信号前后分别通过串口输出一些信息,来排查问题所在。同时,可以尝试重新连接DHT11,确保电路连接正确。以下是可能有用的代码示例:

#include <reg52.h>
#include "lcd1602.h"

sbit DATA = P2^0; //DHT11 数据引脚

unsigned char DHTDATA[5] = {'\0'}; //存放温湿度40位 数据

// 延时10*n微秒
void delayus(unsigned int n)
{
    unsigned char i;
    i = 2*n;
    while (--i);
}

//延时n毫秒
void delayms(unsigned int n)
{
    unsigned int i,y;
    for(i=n;i>0;i--)
        for(y=114;y>0;y--);
}

/*DHT11接收数据函数*/
unsigned char DHT_receive_data()
{
    unsigned char i;
    unsigned char dat=0;  //0000 0000

    for(i=0;i<8;i++)
    {
        while(!DATA); //等待DHT 50us低电平信号过去
        delayus(3); //延时大概30us 如何还是高电平 则为1

        dat<<=1; //左移一位 因为数据是从高位开始传
        if(DATA == 1)
        {
            dat|=0x01;
        }
        while(DATA); //等待DHT 拉低 准备下一位开始

    }
    return dat;
}

/*DHT11读取函数*/
void DHT_receive()
{
    unsigned char R_H,R_L,T_H,T_L,CHECK;
    
    /*主机发送信号*/
    DATA = 1;
    delayus(3);
    DATA = 0;
    delayms(20); //延时大于18ms
    DATA=1;
    delayus(3);     //延时30us  20-40us 均可

    DATA=1;
    if(DATA == 0)   //判断DHT是否进入响应
    {
        // 通过串口输出调试信息
        SBUF = 'D';
        while(!TI);
        TI = 0;

        while(!DATA);       //等待从机80us低电平响应信号过去
        while(DATA); //等待从机80us高电平信号过去

        // 通过串口输出调试信息
        SBUF = 'H';
        while(!TI);
        TI = 0;

        /*获取温湿度数据*/
        R_H = DHT_receive_data();    //湿度整数部分
        R_L = DHT_receive_data();    //湿度小数部分
        T_H = DHT_receive_data();    //温度整数部分
        T_L = DHT_receive_data();    //温度小数部分

        CHECK = DHT_receive_data(); //校验位

        DATA=0; //当最后一bit数据传送完毕后,DHT11拉低总线 50us
        delayus(5); //这里延时55us
        DATA=1;    //随后总线由上拉电阻拉高进入空闲状态。

        /*校验接收到的数据是否正确*/
        if((R_H + R_L + T_H + T_L) == CHECK) 
        {
            DHTDATA[0] = R_H;
            DHTDATA[1] = R_L;
            DHTDATA[2] = T_H;
            DHTDATA[3] = T_L;

            // 通过串口输出调试信息
            SBUF = 'C';
            while(!TI);
            TI = 0;
        }
    }
}

/*显示DHT11数据函数*/
void DHT_display()
{
    write_sfm2(1,7,DHTDATA[2]);
    write_sfm2(1,10,DHTDATA[3]);
    write_sfm2(2,7,DHTDATA[0]);
    write_sfm2(2,10,DHTDATA[1]);
}

/*初始化串口函数*/
void init_serial()
{
    SCON = 0x50; //8位数据,可变波特率
    TMOD |= 0x20; //Timer1模式2
    TH1 = 0xfd; //波特率9600
    TL1 = 0xfd;
    TR1 = 1; //启动Timer1
    TI = 0; //清除发送中断标志
}

/*主函数入口*/
void main()
{
    init_serial(); //初始化串口
    init_1602(); //初始化1602
    init_1602_dis_csf();

    while(1)
    {
        delayms(1000); //等待 1s 以越过不稳定状态
        DHT_receive();   //DHT11读取函数
        DHT_display();//1602显示温湿度
    }
}

如果我的建议对您有帮助、请点击采纳、祝您生活愉快

  • 看下这篇博客,也许你就懂了,链接:单片机+DHT11的温湿度采集监测系统,LCD1602显示,带报警功能,C代码、原理图和Proteus仿真
  • 除此之外, 这篇博客: DHT11温湿度传感器(详细)中的 DHT11温湿度传感器——使用LCD1602显示 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 先上效果图,以及简单的和室内温度对比图,相交而言测量的值还是非常准的。
    我的这个做的很简陋,大家可以理解原理后自行升级。
    在这里插入图片描述

    注意学习单片机最重要的就是学习如何阅读说明文档,会看文档+会一些c语言编程你就做出你想要的小东西了,下面放上一个我常用的查芯片说明文档的网站。
    https://www.114ic.cn/ ic芯片网(戳它进入)

    这是我已经下载好的芯片资料,懒一点的朋友可以上百度云上下载。
    链接:https://pan.baidu.com/s/19Q9CKAih-KpnPlicplpx_w 戳它
    提取码:4ivd
    在这里插入图片描述