问题:主机发送信号后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模块或使用另一台主机进行测试。
建议在程序中增加适当的错误处理和异常处理机制,便于排查问题和维护代码。
问题的原因可能是主机发送信号的时候没有成功发送信号,或者是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显示温湿度
}
}
先上效果图,以及简单的和室内温度对比图,相交而言测量的值还是非常准的。
我的这个做的很简陋,大家可以理解原理后自行升级。
注意学习单片机最重要的就是学习如何阅读说明文档,会看文档+会一些c语言编程你就做出你想要的小东西了,下面放上一个我常用的查芯片说明文档的网站。
https://www.114ic.cn/ ic芯片网(戳它进入)
这是我已经下载好的芯片资料,懒一点的朋友可以上百度云上下载。
链接:https://pan.baidu.com/s/19Q9CKAih-KpnPlicplpx_w 戳它
提取码:4ivd