STM32-DHT11(温湿度传感器)之学习笔记

2019-08-14来源: eefocus关键字:STM32  DHT11  温湿度传感器

一、模块分析:

原理图和引脚连接图:

在这里插入图片描述

由图可知DHT11(温湿度模块)是单总线的连接,数据的输入输出由一根线完成,DQ网络标号对应的引脚是PG9就是GPIO外设接口G组的第九个引脚。


二、DHT11时序图:


在这里插入图片描述在这里插入图片描述

由上图可以判断当主机开始信号发送之后手袋DHT11响应信号并开始接受数据时,我们可以通过判断高电平的维持时间来获取当前接受的数据位是0/1这样就可以把数据保存下来。判断的依据是开始接受数据前延时超过26-28us,当延时过后检测到的还是高电平(高电平持续70us为数据1)那就证明该数据位为‘1’。因为每一个比特位传输完成之后会有50us的延迟所以当比特位为0时前面已经延时超过高电平时间所以比特位为0时,检测到的是低电平,由此来保存温湿度数据。


三、部分关键代码:

#include “dht11.h”

//单数据总线接口 —>PG9

void DHT11_Init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

//1:第一步永远是打开时钟,查看固件库

RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOG, ENABLE );


//对结构体成员进行赋值(输出 推挽   上拉  50MHZ)

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;//输出模式

GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽

GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;


//2:对GPIOG进行初始化

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;

GPIO_Init( GPIOG ,&GPIO_InitStructure);


}


/*=2-配置GPIO口的输入模式函数=========*/

static void DHT11_Mode_IN(void)

{

GPIO_InitTypeDef GPIO_InitStruct;


//浮空输入

GPIO_InitStruct.GPIO_Pin    = GPIO_Pin_9;

GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_IN;

GPIO_InitStruct.GPIO_Speed  = GPIO_Speed_50MHz;   

GPIO_InitStruct.GPIO_PuPd   = GPIO_PuPd_NOPULL;   //浮空输入 

GPIO_Init(GPIOG,&GPIO_InitStruct);


}


/*=2-配置GPIO口的输出模式函数=========*/

static void DHT11_Mode_OUT(void)

{

GPIO_InitTypeDef GPIO_InitStruct;


//上拉推挽输出

GPIO_InitStruct.GPIO_Pin    = GPIO_Pin_9;

GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_OUT;

GPIO_InitStruct.GPIO_OType  = GPIO_OType_PP;

GPIO_InitStruct.GPIO_Speed  = GPIO_Speed_50MHz;   

GPIO_InitStruct.GPIO_PuPd   = GPIO_PuPd_UP;

GPIO_Init(GPIOG,&GPIO_InitStruct);


}


/3-配置8位接收数据函数,根据DHT11数据传输时序图编写=/

//数据是高位先出

static uint8_t Read_Byte(void)

{

uint8_t i,temp=0;


for(i=0;i<8;i++)

{

    //数据准备输出  每个数据都有50US的低电平,然后判断后面高电平是时长来决定是1还是0

    //0:高电平时长26~28us

    //1:高电平时长70us   

    /*每一个bit都是以50us的低电平开始,等电平置高,则跳出循环*/

    while( DQ_IN() == 0 );


    /*‘0’表示的置高时间过短,可直接判断‘1’表示的时间,但滞留时间不宜过长,以防跳出下一位的开始时间*/

    delay_us(40);

    

    if( DQ_IN() == 1 )//如果还是高电平,那就是数据1

    {

        /*等待跳出‘1’置高表示的时间*///等待剩余的高电平时间结束

        while( DQ_IN() == 1);

        /*把第(7-i)位置 '1'*/

        temp |= (uint8_t)(0x01<<(7-i));  

    }

    else

    {

        /*把第(7-i)位置 '0'*/

        temp &= (uint8_t)~(0x01<<(7-i));

    }

}

return temp;



}


/*

*功 能:获取温湿度值

*参 数:保存温度读数据的结构体指针

返回值:成功返回1 失败返回0

*

/

/4-根据总时序图编写接收数据函数=/

uint32_t DHT11_GET_TEMP_HUM(DHT11_Data_TypeDef * DHT11_Data)

{

uint16_t count = 0;


DHT11_Mode_OUT();//输出模式

DQ_OUT(0);       /*将主机拉低*/

delay_ms(20);/*配置主机拉低时间,至少拉低18ms*/

DQ_OUT(1);/*将主机拉高*/   

delay_us(30);


DHT11_Mode_IN();//输入模式    

if( DQ_IN() == 0) 

{    

    //printf("开始获取数据rn");

    //因为在空闲状态下,管教是高电平,所以这个时候如果是低电平,则模块有响应

    //等待拉高  时长80us

    while(DQ_IN() == 0)//等待80us结束

    {

        count++;

        if(count > 1000)

               return 0;

        delay_us(1);//每1us检测一次是否拉高

    }  

    //printf("80us lowrn");

    count = 0;

    

    //等待拉高  时长80us

    while( DQ_IN()== 1)//等待80us结束

    {

        count++;

        if(count > 1000)

               return 0;

        delay_us(1);//每1us检测一次是否拉高

    }

   // printf("80us hightrn");

    

    // 获取5个字节数据 

    //分析40位数据,8Bit湿度整数   +8Bit湿度小数   +8Bit温度整数    +8Bit温度小数

    DHT11_Data->humi_int  = Read_Byte();

    DHT11_Data->humi_deci = Read_Byte();

    DHT11_Data->temp_int  = Read_Byte();

    DHT11_Data->temp_deci = Read_Byte();

    DHT11_Data->check_sum = Read_Byte();

   // printf("get data successrn");

    

/*读取结束,将主机设为输出模式*/

 DHT11_Mode_OUT();//输出模式

 DQ_OUT(1);/*将主机拉高,方便下次读取数据*/

    

if(DHT11_Data->check_sum == (DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int + DHT11_Data->temp_deci))                   

{    

    printf("校验和正常rn");

    return 1;

}

else

{

     printf("校验和失败rn");

     return 0;

}


}

else

return 0;


}


关键字:STM32  DHT11  温湿度传感器

编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic471063.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:ADIS16203角度传感器的stm32驱动实现要点
下一篇:STM32之SHT30温湿度传感器驱动代码

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32 USART1对PWM的影响,串口影响PWM

注意,USART1和TIM1是复用的,如果用TIM1产生PWM(PA9 / PA10),则USART1不应该用该管脚,可以用PB6/PB7。
发表于 2019-08-22

stm32103R8C6 捕捉2路pwm 串口打印捕捉数据

第一路使用定时器2的通道1,先捕捉一个上升沿,清楚所有数据开始捕捉下降沿,捕捉到下降沿后再捕捉一个上升沿。 第二路使用定时器4的通道4,使用其他通道的时候要注意,定时器的中断时CC4,设置上升沿和下降沿的时候也要改为通道4。//定时器2通道1输入捕获配置TIM_ICInitTypeDef TIM2_ICInitStructure;void TIM2_Cap_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 
发表于 2019-08-22
stm32103R8C6 捕捉2路pwm 串口打印捕捉数据

STM32——使用PWM+DMA实现脉冲发送精确控制

之前用stm32写过脉冲发送的代码,用来控制步进电机,但是缺点明显,之前是用定时器中断做的,所以一但控制的电机多起来,MCU资源占用就很大,这在大多数情况下是不可接受的,更不用说多轴联动了。最近做的步进电机CAN总线控制系统,就想顺便重新写驱动。希望做到占用很少的MCU资源,实现脉冲发送的精确控制。既然是用来控制步进电机,那么脉冲的数量和频率一定要可控,要不然怎么实现电机的加减速曲线。于是就想到了DMA。DMA (直接存储器访问)DMA(Direct Memory Access,直接内存存取) 是所有现代电脑的重要特色,它允许不同速度的硬件装置来沟通,而不需要依赖于 CPU 的大量中断负载。否则,CPU 需要从来源把每一片段的资料
发表于 2019-08-22
STM32——使用PWM+DMA实现脉冲发送精确控制

stm32入门——PWM输出控制直流电机变速

,ARR大于CCRx时输出为“有效”电平。注意,我这里用的是“有效”和“无效”,而不是“高”和“低”,也就是说有效电平可高可低,并非一定就是高电平。PWM模式、效电平极性,需要程序员自己配置相关的寄存器来实现。以下面的代码来讲解TIM1_PWM_Init(899,0);//不分频。PWM频率=72000/(899+1)=80Khz我们使用定时器1的通道1来输出一路PWM波,想详细了解定时器参数的设置的朋友可以参考(stm32入门——定时器中断),我这里简单介绍一下,这里的899设置的就是ARR的值,至于那个0是用来设置TIM1的频率的,不分频就代表TIM1的时钟频率和系统时钟相同,这里假设为72MHz。void
发表于 2019-08-22
stm32入门——PWM输出控制直流电机变速

STM32学习笔记(PWM输出)

本人采用Cube 进行的STM32库函数编程,PWM波的输出配置以及代码如下所示:(经过实际实验证明非常好用)以下为定时器PWM输出函数,注意:使用时一定要把原来输出函数注释掉。注释代码如下:// sConfigOC.OCMode = TIM_OCMODE_PWM1;// sConfigOC.Pulse = 0;// sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;// sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;// if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC
发表于 2019-08-22

STM32死机 调试时进入HardFault_Handler定位错误的方法

STM32在运行不正常的时候我们一般会进行调试看看问题出在了哪里。但是当STM32卡死后进行调试的时候会发现进入到了一个HardFault_Handler函数里,这是一个硬件错误处理函数。通过它和MDK配合可以定位程序最后卡死的原因。STM32卡死的原因有以下几种:数组越界操作;内存溢出,访问越界;堆栈过小;中断处理错误;电压供电异常。现在实验一个堆栈过小的错误,让MDK来检测这个问题然后定位错误。这个程序基于UCOSII 系统 #define TFTLCD_STK_PRIO  8 //任务的优先级#define TFTLCD_STK_SIZE  2 //任务的堆栈大小OS_ST
发表于 2019-08-22
STM32死机 调试时进入HardFault_Handler定位错误的方法

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved