0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

将DHT11与PIC16F877A连接进行温度和湿度的测量

科技观察员 来源:circuitdigest 作者:Sourav Gupta 2022-08-22 16:07 次阅读

温度和湿度测量通常在家庭自动化、环境监测、气象站等许多应用中很有用。LM35旁边最常用的温度传感器是 DHT11,我们之前通过与Arduino和Raspberry连接构建了许多DHT11 项目Pi和许多其他开发板。在本文中,我们将学习如何将此DHT11 与 PIC16F87A连接,这是一个 8 位 PIC 微控制器。我们将使用这个微控制器通过 DHT11 读取温度和湿度的值并将其显示在液晶显示器上。

DHT11 – 规范和工作

DHT11 传感器以模块形式或传感器形式提供。在本教程中,我们使用的是传感器,两者之间的唯一区别在于,在模块形式中,传感器具有一个滤波电容和一个连接到传感器输出引脚的上拉电阻。因此,如果您正在使用该模块,则无需在外部添加它们。传感器形式的 DHT11 如下所示。

poYBAGMDOJGAGOsSAAFAlxfqC2o033.png

DHT11 传感器带有蓝色或白色外壳。 在这个外壳内,我们有两个重要的组件 可以帮助我们感知相对湿度和温度。 第一个组件是一对电极;这两个电极之间的电阻由保持水分的基板决定。所以测得的电阻与环境的相对湿度成反比。相对湿度越高,电阻值越低,反之亦然。另外,请注意相对湿度与实际湿度不同。相对湿度测量空气中相对于空气温度的水含量。

另一个组件是表面贴装的 NTC 热敏电阻。术语 NTC 代表负温度系数,随着温度的升高,电阻值将减小。传感器的输出经过工厂校准,因此作为程序员,我们不必担心校准传感器。1-Wire通信给出的传感器输出,我们看一下这个传感器的引脚和连接图。

pYYBAGMDOI2AERVOAAEjlw0WPUM086.png

产品采用 4pin 单排封装。第 1 个引脚跨接 VDD,第 4 个引脚跨接 GND。第二个引脚是数据引脚,用于通信目的。该数据引脚需要一个 5k 的上拉电阻。但是,也可以使用其他上拉电阻,例如 4.7k 到 10k。第 3 个引脚没有连接任何东西。所以它被忽略了。

数据表提供了技术规格以及可以在下表中看到的接口信息 -

poYBAGMDOImADZ12AAEl5wfpbgE823.png

上表显示了温度和湿度的测量范围和精度。它可以测量 0-50 摄氏度的温度,精度为 +/- 2 摄氏度,测量相对湿度 20-90%RH,精度为 +/- 5%RH。详细规格见下表。

pYYBAGMDOIWAXLyyAANKPdPVoFM730.png

与 DHT11 传感器通信

如前所述,为了使用 PIC 从DHT11读取数据,我们必须使用PIC 单线通信协议。有关如何执行此操作的详细信息,可以从其数据表中的 DHT 11 的接口图了解,如下所示。

poYBAGMDOIKAUtv4AAKm-le43io889.png

DHT11 需要来自 MCU 的启动信号来启动通信。因此,每次 MCU 都需要向 DHT11 Sensor 发送启动信号,要求其发送温度和湿度值。在完成启动信号后,DHT11 会发送一个 包含温度和湿度信息的响应信号。数据通信采用单总线数据通信协议。全数据长度为 40 位,传感器先发送高位数据。

poYBAGMDOH6AMdNTAAK6IH7VbqI826.png

由于上拉电阻,数据线在空闲模式下始终保持在 VCC 电平。MCU 需要将此电压从高到低拉低至少 18 毫秒。在此期间,DHT11 传感器检测到启动信号,微控制器将数据线拉高 20-40us。这 20-40us 的时间称为 DHT11 开始响应的等待期。在这个等待期之后,DHT11 将数据发送到微控制器单元。

DHT11 传感器数据格式

数据由组合在一起的小数部分和整数部分组成。传感器遵循以下数据格式 -

8bit 积分 RH 数据 + 8bit 十进制 RH 数据 + 8bit 积分 T 数据 + 8bit 十进制 T 数据 + 8bit 校验和。

可以通过使用接收到的数据检查校验和值来验证数据。可以这样做是因为,如果一切正常,并且传感器已经传输了正确的数据,那么校验和应该是“8 位 RH 积分数据+8 位十进制 RH 数据+8 位积分 T 数据+8 位十进制 T 数据”之和。

所需组件

对于这个项目,需要以下内容 -

PIC单片机(8位)编程设置。

面包板

5V 500mA 电源装置。

4.7k电阻2个

1k电阻

PIC16F877A

20mHz晶体

33pF电容2个

16x2 字符 LCD

DHT11传感器

跳线

示意图

将DHT11 与 PIC16F877A连接的电路图如下所示。

poYBAGMDOHiAMdeTAAFMJE3KRRs485.png

我们使用16x2 LCD来显示我们从 DHT11 测量的温度和湿度值。LCD 采用4 线模式连接,传感器和 LCD 均由 5V 外部电源供电。我使用面包板进行所有必需的连接,并使用了外部 5V 适配器。您还可以使用此面包板电源板为您的电路板供电 5V。

pYYBAGMDOHSAHMRzAATrTLah-uU041.png

电路准备好后,我们要做的就是上传本页底部给出的代码,我们可以开始读取温度和湿度,如下所示。如果您想知道代码是如何编写的以及它是如何工作的,请进一步阅读。您还可以在本页底部的视频中找到该项目的完整工作。

poYBAGMDOHOAPJUTAAdBo_c7wLc623.png

DHT11 with PIC MPLABX 代码说明

代码使用 MPLABX IDE 编写,并使用 XC8 编译器编译,两者均由 Microchip 提供,可免费下载和使用。请参考基础教程了解编程基础知识,下面只讨论与 DHT11 传感器通信所需的三个重要功能。功能是 -

无效 dht11_init(); 
无效查找响应();
char read_dht11();

第一个函数用于dht11 的启动信号。如前所述,与 DHT11 的每次通信都以启动信号开始,这里首先更改引脚方向以将数据引脚配置为微控制器的输出。然后数据线被拉低,一直等待18mS。之后,微控制器再次将线路设为高电平,并一直等待长达 30us。等待时间过后,数据引脚设置为微控制器的输入以接收数据。

无效 dht11_init(){ 
DHT11_Data_Pin_Direction= 0; //配置RD0为输出
DHT11_Data_Pin = 0; //RD0向传感器发送0 
__delay_ms(18); 
DHT11_Data_Pin = 1;//RD0向传感器发送1 
__delay_us(30); 
DHT11_Data_Pin_Direction = 1;//配置RD0为输入
}

下一个函数用于根据数据引脚状态设置校验位。它用于检测 DHT11 传感器的响应。

无效 find_response(){ 
Check_bit = 0; 
__delay_us(40); 
if (DHT11_Data_Pin == 0){ 
__delay_us(80); 
if (DHT11_Data_Pin == 1){ 
            Check_bit = 1; 
}           
__delay_us(50);} 
}

最后是dht11读取函数;此处数据被读取为 8 位格式,其中数据通过位移操作返回,具体取决于数据引脚状态。

char read_dht11(){ 
char 数据,for_count; 
for(for_count = 0; for_count < 8; for_count++){ 
            while(!DHT11_Data_Pin); 
            __delay_us(30); 
            if(DHT11_Data_Pin == 0){ 
            data&= ~(1<<(7 - for_count)); //清除位 (7-b) 
            } 
            else{ 
            data|= (1 << (7 - for_count)); //设置位 (7-b) 
            while(DHT11_Data_Pin); 
            } 
            }
返回数据;
}

​​​

之后,一切都在 main 函数中完成。首先,系统初始化在 LCD 被初始化并将 LCD 引脚端口方向设置为输出的地方完成。应用程序在主函数内部运行

无效 main() { 
system_init(); 
while(1){ 
            __delay_ms(800); 
            dht11_init(); 
            查找响应();
            if(Check_bit == 1){ 
            RH_byte_1 = read_dht11(); 
            RH_byte_2 = read_dht11(); 
            Temp_byte_1 = read_dht11(); 
            Temp_byte_2 = read_dht11(); 
            求和 = read_dht11(); 
            if(Summation == ((RH_byte_1+RH_byte_2+Temp_byte_1+Temp_byte_2) & 0XFF)){
            湿度 = Temp_byte_1; 
            RH = RH_byte_1;                                
            lcd_com (0x80);                       
            lcd_puts("温度:");
            //lcd_puts(""); 
            lcd_data(48 + ((湿度/10) % 10)); 
            lcd_data(48 + (湿度 % 10)); 
            液晶数据(0xDF);
            lcd_puts("C"); 
            lcd_com (0xC0);          
            lcd_puts("湿度:"); 
            //lcd_puts(""); 
            lcd_data(48 + ((RH / 10) % 10)); 
            lcd_data(48 + (RH % 10)); 
            lcd_puts("%"); 
            } 
            else{ 
            lcd_puts("校验和错误"); 
            } 
            }
            其他 { 
            clear_screen(); 
            lcd_com (0x80);
            lcd_puts("错误!!!"); 
            lcd_com (0xC0); 
            lcd_puts("没有反应。"); 
            } 
            __delay_ms(1000); 
} 
}

与 DHT11 传感器的通信是在while循环中完成的,在该循环中将启动信号提交给传感器。之后,触发find_response函数。如果Check_bit为 1,则进行进一步的通信,否则 LCD 将显示错误对话框。

根据 40 位数据,read_dht11被调用 5 次(5 次 x 8 位),并按照数据表中提供的数据格式存储数据。校验和状态也被检查,如果发现错误,它也会在 LCD 中通知。最后,数据被转换并传输到 16x2 字符 LCD。

#include

#include


#include "supporting_cfile/lcd.h"


#pragma config FOSC = HS // 振荡器选择位(HS 振荡器)

#pragma config WDTE = OFF // 看门狗定时器使能位(WDT 禁用)

#pragma config PWRTE = ON // 上电定时器使能位(PWRT 使能)

# pragma config BOREN = ON // 欠压复位使能位(BOR 使能)

#pragma config LVP = OFF // 低电压(单电源)在线串行编程使能位(RB3 为数字 I/O,HV 开启MCLR 必须用于编程)

#pragma config CPD = OFF // 数据 EEPROM 存储器代码保护位(数据 EEPROM 代码保护关闭)

#pragma config WRT = OFF // 闪存程序存储器写使能位(写保护关闭;所有程序存储器可由 EECON 控制写入)

#pragma config CP = OFF // Flash 程序存储器代码保护位(代码保护关闭)



/*

程序流程相关定义

*/

#define DHT11_Data_Pin PORTDbits.RD5

#define DHT11_Data_Pin_Direction TRISDbits.TRISD5

#define FIRST_LINE 0x80

#define SECOND_LINE 0xC0



#define _XTAL_FREQ 20000000 //20 Mhz


unsigned char Check_bit, Temp_byte_1, Temp_byte_2, RH_byte_1, RH_byte_2;

unsigned char Himudity, RH, Sumation ;


//dht11相关定义


无效 dht11_init();

无效查找响应();

char read_dht11();


// 系统相关定义


无效系统初始化(无效);

无效介绍屏幕(无效);

无效清除屏幕(无效);


无效 main() {

system_init();



while(1){

__delay_ms(800);

dht11_init();

查找响应();

if(Check_bit == 1){

RH_byte_1 = read_dht11();

RH_byte_2 = read_dht11();

Temp_byte_1 = read_dht11();

Temp_byte_2 = read_dht11();

求和 = read_dht11();

if(Sumation == ((RH_byte_1+RH_byte_2+Temp_byte_1+Temp_byte_2) & 0XFF)){

Himudity = Temp_byte_1;

RH = RH_byte_1;

lcd_com (0x80);

lcd_puts("温度:");

//lcd_puts("");

lcd_data(48 + ((Himudity / 10) % 10));

lcd_data(48 + (湿度 % 10));

液晶数据(0xDF);

lcd_puts("C");

lcd_com (0xC0);

lcd_puts("湿度:");

//lcd_puts("");

lcd_data(48 + ((RH / 10) % 10));

lcd_data(48 + (RH % 10));

lcd_puts("%");

}

else{

lcd_puts("校验和错误");

}

}

其他 {

clear_screen();

lcd_com (0x80);

lcd_puts("错误!!!");


lcd_puts("没有反应。");

}

__delay_ms(1000);

}

}


/*

* 这将初始化 dht22 传感器。

*/


无效 dht11_init(){

DHT11_Data_Pin_Direction= 0; //配置RD0为输出

DHT11_Data_Pin = 0; //RD0向传感器发送0

__delay_ms(18);

DHT11_Data_Pin = 1;//RD0向传感器发送1

__delay_us(30);

DHT11_Data_Pin_Direction = 1;//配置RD0为输入

}


/*

* 这将发现 dht22 传感器是否工作。

*/


无效 find_response(){

Check_bit = 0;

__delay_us(40);

if (DHT11_Data_Pin == 0){

__delay_us(80);

if (DHT11_Data_Pin == 1){

Check_bit = 1;

}

__delay_us(50);}

}



/*

此函数用于读取 dht22。

*/



char read_dht11(){

char data, for_count;

for(for_count = 0; for_count < 8; for_count++){

while(!DHT11_Data_Pin);

__delay_us(30);

if(DHT11_Data_Pin == 0){

data&= ~(1<<(7 - for_count)); //清除位 (7-b)

}

else{

data|= (1 << (7 - for_count)); //设置位 (7-b)

while(DHT11_Data_Pin);

} //等到 PORTD.F0 变低

}

返回数据;

}



void system_init(){

TRISB = 0; // LCD 引脚设置为输出。

液晶初始化();

介绍屏幕();

//dht11_init();

}



/*

这个函数是为了在没有命令的情况下清除屏幕。

*/


void clear_screen(void){

lcd_com(FIRST_LINE);

lcd_puts("");

lcd_com(第二行);

lcd_puts("");

}




/*

此函数用于播放介绍。

*/


void Introduction_screen(void){

lcd_com(FIRST_LINE);

lcd_puts("欢迎来到");

lcd_com(第二行);

lcd_puts("电路文摘");

__delay_ms(1000);

__delay_ms(1000);

清除屏幕();

lcd_com(FIRST_LINE);

lcd_puts("DHT11 传感器");

lcd_com(第二行);

lcd_puts("用 PIC16F877A");

__delay_ms(1000);

__delay_ms(1000);

}

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 微控制器
    +关注

    关注

    48

    文章

    7482

    浏览量

    151012
  • 液晶显示器
    +关注

    关注

    11

    文章

    575

    浏览量

    43605
  • DHT11
    +关注

    关注

    19

    文章

    277

    浏览量

    57539
收藏 人收藏

    评论

    相关推荐

    PIC16F877A在proteus中读写AT24C512

    此时把I2C DEBUGGER的SCL线连接PIC16F877A和AT24C512的SCL线上,这样PIC16F877A可以正常的写AT24C512。当PIC16F877A发送启动信
    发表于 12-30 16:09

    PIC16F887 DHT11湿度程序

    PIC16F877A 单片机 PIC16F887 DHT11湿度 程序
    发表于 11-24 06:25

    使用DHT11和STM32单片机进行湿度温度监控

    测量0°C至50°C的温度,精度为1°C。 它可以测量20%至90%的湿度,精度为1%。我们将把DHT11
    发表于 03-01 06:24

    pic16f877a中文资料pdf

    pic16f877a中文资料
    发表于 07-15 13:20 4548次下载
    <b class='flag-5'>pic16f877a</b>中文资料pdf

    PIC16F877A串口发送查询方式

    PIC16F877A串口发送,查询方式,就为了调出这个费了我一天时间,原来是串口芯片电压问题,现总结如下
    发表于 09-01 11:03 10次下载
    <b class='flag-5'>PIC16F877A</b>串口发送查询方式

    PIC16F877A串口芯片电压问题

    PIC16F877A串口发送,查询方式,就为了调出这个费了我一天时间,原来是串口芯片电压问题,现总结如下
    发表于 09-01 11:15 9次下载
    <b class='flag-5'>PIC16F877A</b>串口芯片电压问题

    PIC16F877A的UART通信和proteus仿真的资料合集免费下载

    本文档的主要内容详细介绍的是PIC16F877A的UART通信和proteus仿真的资料合集免费下载PIC877单片机进行UART测试
    发表于 12-29 08:00 29次下载
    <b class='flag-5'>PIC16F877A</b>的UART通信和proteus仿真的资料合集免费下载

    PIC16F877A 单片机 PIC16F887 DHT11湿度 程序

    电子发烧友网站提供《PIC16F877A 单片机 PIC16F887 DHT11湿度 程序.pdf》资料免费下载
    发表于 11-16 16:51 34次下载
    <b class='flag-5'>PIC16F877A</b> 单片机 <b class='flag-5'>PIC16F</b>887 <b class='flag-5'>DHT11</b> 温<b class='flag-5'>湿度</b> 程序

    PIC16F877A开发板 数码管动态扫描实验

    //****************电子园PIC16F877A开发板 数码管动态扫描实验****************//////mcu: PIC16F877A 4MHz //2010年12月
    发表于 11-16 19:51 13次下载
    <b class='flag-5'>PIC16F877A</b>开发板 数码管动态扫描实验

    PIC16F877A开发板 普通IO驱动74595实验

    //*****************电子园PIC16F877A开发板 普通IO驱动74595实验***************////PIC16F877A 实验板////mcu
    发表于 11-16 19:51 13次下载
    <b class='flag-5'>PIC16F877A</b>开发板 普通IO驱动74595实验

    PIC16F877A 看门狗定时器实验

    //*******************PIC16F877A 看门狗定时器实验******************* // //PORTA,PORTB,PORTC,PORTD,PORTE
    发表于 11-16 20:06 8次下载
    <b class='flag-5'>PIC16F877A</b> 看门狗定时器实验

    PIC16F887 DHT11湿度传感器 单片机

    电子发烧友网站提供《PIC16F887 DHT11湿度传感器 单片机.pdf》资料免费下载
    发表于 11-17 09:06 26次下载
    <b class='flag-5'>PIC16F</b>887 <b class='flag-5'>DHT11</b><b class='flag-5'>湿度</b>传感器 单片机

    MCP4921与PIC16F877A接口进行数模转换的方法

    在本教程中,我们DAC MCP4921 与 Microchip PIC16F877A 接口以进行数模转换。
    发表于 09-06 17:40 1597次阅读
    <b class='flag-5'>将</b>MCP4921与<b class='flag-5'>PIC16F877A</b>接口<b class='flag-5'>进行</b>数模转换的方法

    使用热敏打印机连接PIC16F877A并使用轻触开关实现打印的教程

    在本教程中,我们热敏打印机 CSN A1 与广泛使用的 PIC 微控制器 PIC16F877A 连接。在本项目中,热敏打印机
    的头像 发表于 11-04 15:10 2729次阅读
    使用热敏打印机<b class='flag-5'>连接</b><b class='flag-5'>PIC16F877A</b>并使用轻触开关实现打印的教程

    PIC16F877A开发板原理图

    PIC16F877A开发板原理图免费下载。
    发表于 03-21 15:47 12次下载