温度和湿度测量通常在许多应用中很有用,例如家庭自动化,环境监控,气象站等。LM35旁边最常用的温度传感器是DHT11,我们之前通过与Arduino和Raspberry进行接口来构建了许多DHT11项目。 Pi和许多其他开发板。在本文中,我们将学习如何将此DHT11与8位PIC单片机PIC16F87A接口。我们将使用该微控制器通过DHT11读取温度和湿度值,并将其显示在LCD显示屏上。如果您是使用PIC微控制器的新手,则可以使用我们的PIC教程系列来学习如何编程和使用PIC微控制器,也就是说,让我们开始吧。
DHT11 –规格和工作
DHT11传感器有模块形式或传感器形式。在本教程中,我们使用传感器,两者之间的唯一区别是,在模块形式中,传感器具有一个滤波电容器和一个上拉电阻,该上拉电阻连接到传感器的输出引脚。因此,如果您使用的是模块,则无需在外部添加它们。传感器形式的DHT11如下所示。
DHT11传感器带有蓝色或白色外壳。 在此外壳内,我们有两个重要组件 ,可帮助我们感测相对湿度和温度。 第一个组件是一对电极;这两个电极之间的电阻由防潮基材决定。因此,测得的电阻与环境的相对湿度成反比。相对湿度越高,电阻值越低,反之亦然。另外,请注意,相对湿度与实际湿度不同。相对湿度测量相对于空气温度的空气中的水含量。
另一个组件是表面安装的NTC热敏电阻。术语NTC代表负温度系数,随着温度的升高,电阻值将减小。传感器的输出在出厂时已校准,因此,作为程序员,我们无需担心传感器的校准。由1-Wire通信给出的传感器输出,让我们看一下该传感器的引脚和连接图。
该产品采用4pin单排封装。第一个引脚跨接VDD,第四个引脚跨接GND。第二引脚是数据引脚,用于通信目的。该数据引脚需要一个5k的上拉电阻。但是,也可以使用其他上拉电阻,例如4.7k至10k。第三针未连接任何东西。因此它被忽略。
数据表提供了技术规格以及接口信息,如下表所示-
上表显示了温度和湿度的测量范围和精度。它可以测量0-50摄氏度的温度,精度为+/- 2摄氏度,测量相对湿度为20-90%RH,精度为+/- 5%RH。详细规格请参见下表。
与DHT11传感器通讯
如前所述,为了使用PIC从DHT11读取数据,我们必须使用PIC单线通信协议。可以从DHT 11的接口图中了解如何执行此操作的详细信息,该接口可以在其数据表中找到,以下也给出相同的说明。
DHT11需要来自MCU的启动信号才能开始通信。因此,每次MCU需要向DHT11传感器发送启动信号以请求其发送温度和湿度值时。完成启动信号后,DHT11发送一个包括温度和湿度信息的 响应信号。数据通信通过单总线数据通信协议完成。完整数据长度为40位,传感器首先发送更高的数据位。
由于具有上拉电阻,因此在空闲模式下数据线始终保持在VCC电平。MCU需要将该电压从高到低下拉至少18ms。在这段时间内,DHT11传感器检测到启动信号,微控制器将数据线拉高20-40us。这20-40us的时间称为DHT11开始响应的等待时间。在此等待时间之后,DHT11将数据发送到微控制器单元。
DHT11传感器数据格式
数据由十进制和整数部分组合在一起组成。传感器遵循以下数据格式–
8位积分RH数据+ 8位十进制RH数据+ 8位积分T数据+ 8位十进制T数据+ 8位校验和。
可以通过检查接收到的数据的校验和值来验证数据。之所以能够这样做是因为,如果一切正常,并且传感器已传输了正确的数据,则校验和应为 “ 8位积分RH数据+8位十进制RHdata + 8位积分T数据+8位十进制T数据”之和。
所需组件
对于此项目,需要满足以下条件-
- PIC单片机(8位)编程设置。
- 面包板
- 5V 500mA电源单元。
- 4.7k电阻2个
- 1K电阻
- PIC16F877A
- 20mHz晶体
- 33pF电容器2个
- 16x2字符LCD
- DHT11传感器
- 跳线
原理图
DHT11与PIC16F877A接口的电路图如下所示。
我们使用了16x2 LCD来显示从DHT11测量的温度和湿度值。LCD以4线模式连接,传感器和LCD均由5V外部电源供电。我使用了面包板来进行所有必需的连接,并使用了外部5V适配器。您还可以使用此面包板电源板为板供电5V。
一旦电路准备就绪,我们所要做的就是上传本页底部给出的代码,我们可以开始读取“温度和湿度”,如下所示。如果您想知道代码是如何编写的以及如何工作,请进一步阅读。您也可以在本页底部的视频中找到该项目的完整工作。
带有PIC MPLABX的DHT11代码说明
该代码是使用MPLABX IDE编写的,并使用XC8编译器进行编译的,二者均由Microchip自己提供,可以免费下载和使用。请参考基本教程以了解编程的基础,下面仅讨论与DHT11传感器通信所需的三个重要功能。这些功能是-
无效dht11_init(); void find_response(); 字符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传感器的响应。
void find_response(){ Check_bit = 0; __delay_us(40); 如果(DHT11_Data_Pin == 0){ __delay_us(80); 如果(DHT11_Data_Pin == 1){ Check_bit = 1; } __delay_us(50);} }
最后是dht11读取功能;此处,数据被读取为8位格式,其中根据数据引脚状态使用位移操作返回数据。
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)); //将 (DHT11_Data_Pin) 设置为(7-b ); } } 返回数据; }
之后,一切都完成到主函数中。首先,在初始化LCD并将LCD引脚端口方向设置为输出的情况下完成系统初始化。该应用程序正在主要功能内运行
void main(){ system_init(); while(1){ __delay_ms(800); dht11_init(); find_response(); 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(“ Temp:”); // lcd_puts(“”); lcd_data(48 +((湿度/ 10)%10)); lcd_data(48 +(湿度%10)); lcd_data(0xDF); lcd_puts(“ C”); lcd_com(0xC0); lcd_puts(“ Humidity:”); // 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(“ Error !!!”); 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。
可以从此处下载该PIC温度和湿度测量的完整代码。另外,请查看下面的演示视频。
希望您理解该项目并喜欢构建有用的东西。如果您有任何疑问,请将其留在下面的评论部分,或将我们的论坛用于其他技术问题。