STM32 模块篇-温湿度传感器模块(DHT11)实验

目     录

5.03.1 概述3

5.03.1.1 性能描述4

5.03.1.2 传感器时序4

5.03.2 实验目的6

5.03.3 硬件设计7

5.03.4 软件设计7

5.03.4.1 软件设计说明8

5.03.4.2 STM32库函数文件8

5.03.4.3 自定义头文件8

5.03.4.4 pbdata.h文件里的内容是9

5.03.4.5 pbdata.c文件里的内容是9

5.03.5  STM32系统时钟配置SystemInit()12

5.03.6  GPIO引脚时钟使能12

5.03.7  GPIO管脚电平控制函数12

5.03.8  stm32f10x_it.c文件里的内容是13

5.03.9  dht11.h文件里的内容是13

5.03.10  dht11.c文件里的内容是14

5.03.11  main.c文件里的内容是17

5.03.12 程序下载19

5.03.13 实验效果图20

 

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 ℃\r\n",wd);    
  printf("当前环境湿度: %d %%\r\n",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 ℃\r\n",wd);    
  printf("当前环境湿度: %d %%\r\n",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;
 
USART_Init(USART1,&USART_InitStructure);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
USART_Cmd(USART1,ENABLE);
USART_ClearFlag(USART1,USART_FLAG_TC);
}



5.03.12 程序下载

在这一章节中要掌握DHT11温湿度传感器工作时序,了解常用的温湿度传感器功能和原理。

请根据下图所指向的7个重点区域配置。其中(1)号区域根据自己机器的实际情况选择,我的机器虚拟出来的串口号是COM3。(2)号区域请自己选择程序代码所在的文件夹。(7)号区域当程序下载完后,进度条会到达最右边,并且提示一切正常。(4、5、6)号区域一定要按照上图显示的设置。当都设置好以后就可以直接点击(3)号区域的开始编程按钮下传程序了。

 

本节实验的源代码在光盘中:(LY-STM32 光盘资料\1.课程\2,外设篇\模块篇 03.温湿度传感器模块(DHT11)\程序)

5.03.13 实验效果图

打开众想科技多功能监控软件,接着打开串口,我们在接收区可以观察到实测采集到周围环境的温湿度数据,周围环境的温度大约     摄氏度左右、湿度是   左右,说明我们温湿度模块工作正常,程序编写和设计思路吻合。

  • 54
    点赞
  • 497
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值