5.03 温湿度传感器模块实验
5.03.1 概述
DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8 位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11 传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在OTP 内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20 米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选则。
DHT11 数字温湿度传感器模块为4 针PH2.0 封装。连接方便。如右图所示。
5.03.1.1 性能描述
1. 供电电压:3-5.5V
2. 供电电流:最大2.5mA
3. 温度范围:0-50℃ 误差±2℃
4. 湿度范围:20-90%RH 误差±5%RH
5. 响应时间: 1/e(63%) 6-30s
6. 测量分辨率分别为 8bit(温度)、8bit(湿度)
7. 采样周期间隔不得低于1 秒钟
8. 模块尺寸:30x20mm
注释:建议连接线长度短于20米时使用5K上拉电阻,大于20米时根据实际情况使用合适的上拉电阻。
5.03.1.2 传感器时序
DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于以后扩展,现读出为零.操作流程如下:
一次完整的数据传输为40bit,高位先出。
数据格式:
8bit湿度整数数据+8bit湿度小数数据
+8bi温度整数数据+8bit温度小数数据
+8bit校验和
数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。
用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集,如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。
通讯过程如图
总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。
总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定了数据位是0还是1.格式见下面图示.如果读取响应信号为高电平,则DHT11没有响应,请检查线路是否连接正常.当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。
5.03.2 实验目的
1. 掌握温度采集模块DHT11的工作原理;
2. 掌握单片机实现温度采集模块DHT11数据采集的基本方法,其中包括硬件和软件实现两部分;
3. 熟悉单片机数据采集系统中,温度采集模块DHT11作为传感器对象的系统设计方法。
5.03.3 硬件设计
选用大黄蜂实验板,温度采集模块DHT11是成品模块,直接插接到实验板上即可。硬件设计见“图5.03.5 温度采集模块DHT11连线图”。
5.03.4 软件设计
5.03.4.1 软件设计说明
温度采集模块DHT11是成品模块,直接插接到实验板上即可。按照上一章介绍的工作原理,我们就可以按照工作时序编写出数据采集程序。我们还是采用库函数的方式进行程序设计。
在这节程序设计中,用到了外部中断函数;prinif 重定向打印输出函数; USART串口通讯函数;定时器函数。
5.03.4.2 STM32库函数文件
?
本节实验及以后的实验我们都是用到库文件,其中 stm32f10x_gpio.h头文件包含了GPIO端口的定义。stm32f10x_rcc.h 头文件包含了系统时钟配置函数以及相关的外设时钟使能函数,所以我们要把这两个头文件对应的stm32f10x_gpio.c和stm32f10x_rcc.c加到工程中;Misc.c库函数主要包含了中断优先级的设置,stm32f10x_exti.c 库函数主要包含了外部中断设置参数,tm32f10x_tim.c库函数主要包含定时器设置,tm32f10x_usart.c库函数主要包含串行通讯设置,这些函数也要添加到函数库中。以上库文件包含了本次实验所有要用到的函数使用功能。
5.03.4.3 自定义头文件
我们在每个工程设计中都要创建了两个公共的文件,这两个文件主要存放我们自定义的公共函数和全局变量,以方便以后每个功能模块(函数)之间传递参数。
5.03.4.4 pbdata.h文件里的内容是
语句 #ifndef、#endif是为了防止pbdata.h文件被多个文件调用时出现错误提示。如果不加这两条语句,当两个文件同时调用pbdata文件时,会提示重复调用错误。
5.03.4.5 pbdata.c文件里的内容是
下面是pbdata.c文件详细内容,在文件开始还是引用“pbdata.h”文件。
5.03.5 STM32系统时钟配置SystemInit()
在每个工程中必须在开始时配置并启动STM32系统时钟,这是基础,这次也不例外。
5.03.6 GPIO引脚时钟使能
5.03.7 GPIO管脚电平控制函数
在主程序中采用while(1)循环语句,采用查询方式不停的读取温湿度数据,然后直接通过串口送打印输出到屏幕。
while(1)
{
DHT11_Read_Data(&wd,&sd);//读取温湿度值
printf("当前环境温度: %d ℃rn",wd);
printf("当前环境湿度: %d %%rn",sd);
delay_ms(1000);
delay_ms(1000);
}
5.03.8 stm32f10x_it.c文件里的内容是
在中断处理stm32f10x_it.c文件里中仅串口1子函数非空,进入中断处理函数后,只有串口1有参数输出。
#include "stm32f10x_it.h"
#include "stm32f10x_exti.h"
#include "stm32f10x_rcc.h"
#include "misc.h"
#include "pbdata.h"
void NMI_Handler(void)
{
}
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
{
USART_SendData(USART1,USART_ReceiveData(USART1));
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}
}
5.03.9 dht11.h文件里的内容是
函数dht11.h在这里是为符合温湿度模块功能自定义的专用功能函数,dht11.h的内容如下:
#ifndef __DHT11_H
#define __DHT11_H
#include "pbdata.h"
#define IO_DHT11 GPIO_Pin_4 //引入中间变量,方便移植
#define GPIO_DHT11 GPIOE //引入中间变量,方便移植
#define DHT11_DQ_High GPIO_SetBits(GPIO_DHT11,IO_DHT11)
#define DHT11_DQ_Low GPIO_ResetBits(GPIO_DHT11,IO_DHT11)
void DHT11_IO_OUT(void);//温湿度模块输出函数
void DHT11_IO_IN(void); //温湿度模块输入函数
void DHT11_Init(void); //初始化DHT11
u8 DHT11_Read_Data(u8 *temp,u8 *humi);//读取温湿度
u8 DHT11_Read_Byte(void); //读出一个字节
u8 DHT11_Read_Bit(void); //读出一个位
u8 DHT11_Check(void); //检测是否存在DHT11
void DHT11_Rst(void); //复位DHT11
#endif
5.03.10 dht11.c文件里的内容是
自定义函数dht11.c的内容如下:
#include "pbdata.h"
void DHT11_IO_IN(void)//温湿度模块输入函数
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=IO_DHT11;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIO_DHT11,&GPIO_InitStructure);
}
void DHT11_IO_OUT(void)//温湿度模块输出函数
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=IO_DHT11;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIO_DHT11,&GPIO_InitStructure);
}
//复位DHT11
void DHT11_Rst(void)
{
DHT11_IO_OUT(); //SET OUTPUT
DHT11_DQ_Low; //DQ=0
delay_ms(20); //拉低至少18ms
DHT11_DQ_High; //DQ=1
delay_us(30); //主机拉高20~40us
}
//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
u8 DHT11_Check(void)
{
u8 retry=0;//定义临时变量
DHT11_IO_IN();//SET INPUT
while ((GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==1)&&retry<100)//DHT11会拉低40~80us
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;
else retry=0;
while ((GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==0)&&retry<100)//DHT11拉低后会再次拉高40~80us
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;
return 0;
}
//从DHT11读取一个位
//返回值:1/0
u8 DHT11_Read_Bit(void)
{
u8 retry=0;
while((GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==1)&&retry<100)//等待变为低电平
{
retry++;
delay_us(1);
}
retry=0;
while((GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==0)&&retry<100)//等待变高电平
{
retry++;
delay_us(1);
}
delay_us(40);//等待40us
if(GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==1)
return 1;
else
return 0;
}
//从DHT11读取一个字节
//返回值:读到的数据
u8 DHT11_Read_Byte(void)
{
u8 i,dat;
dat=0;
for (i=0;i<8;i++)
{
dat<<=1;
dat|=DHT11_Read_Bit();
}
return dat;
}
//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
u8 DHT11_Read_Data(u8 *temp,u8 *humi)
{
u8 buf[5];
u8 i;
DHT11_Rst();
if(DHT11_Check()==0)
{
for(i=0;i<5;i++)//读取40位数据
{
buf[i]=DHT11_Read_Byte();
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
*humi=buf[0];
*temp=buf[2];
}
}else return 1;
return 0;
}
//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在
void DHT11_Init(void)
{
DHT11_Rst(); //复位DHT11
DHT11_Check();//等待DHT11的回应
}
5.03.11 main.c文件里的内容是
#include "pbdata.h"
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void USART_Configuration(void);
int fputc(int ch,FILE *f)
{
USART_SendData(USART1,(u8)ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
return ch;
}
int main(void)
{
u8 wd=0;
u8 sd=0;
RCC_Configuration();//系统时钟初始化
GPIO_Configuration();//端口初始化
USART_Configuration();
NVIC_Configuration();
DHT11_Init();
while(1)
{
DHT11_Read_Data(&wd,&sd);//读取温湿度值
printf("当前环境温度: %d ℃rn",wd);
printf("当前环境湿度: %d %%rn",sd);
delay_ms(1000);
delay_ms(1000);
}
}
void RCC_Configuration(void)
{
SystemInit();//72m
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate=9600;
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_InitStructure.USART_StopBits=USART_StopBits_1;
USART_InitStructure.USART_Parity=USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
上一篇:STM32 嵌入式学习入门 —— 窗口看门狗 & 独立看门狗
下一篇:零知开源分享- 温湿度模块DHT11的使用
推荐阅读最新更新时间:2024-11-08 21:34
设计资源 培训 开发板 精华推荐
- PN5180高性能多协议全NFC Forum兼容前端典型应用
- LTC1728ES5-1.8、3.3V 和 5V 三路电源监视器的典型应用
- LTM4641 演示板、38V、10A、具有高级输入和负载保护的降压模块稳压器
- SOC Microprocessor USB Interface for Notebook USB interface
- 二合一IC卡
- LTC2163 的典型应用 - 16 位、80Msps 低功耗 ADC
- STM32F103VCT6核心板
- AKD7756-A-SUB,带有单声道编解码器的 AK7756EN DSP 评估板
- 一套完整的门禁系统(原理图+源程序)
- LTC1515 的典型应用 - 具有 RESET 的升压/降压开关电容器 DC/DC 转换器