STM32读取温湿度传感器DHT11和DHT21(AM2301)系列问题

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

1、DHT11和DHT21传感器


    这两种传感器都是奥松公司的产品,具体的传感器说明书在其官网上有(www.aosong.com)。


    DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数 字模块采集技术和温湿度传感技术,确保产品具有枀高的可靠性与卓越的长期稳定性。传感器包括一 个电容式感湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。


    DHT21(AM2301)湿敏电容数字温湿度模块是一款含有己校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电容式感湿元件和一个高精度测温元件,并与一个高性能 8 位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在单片机中,传感器内部在检测信号的处理过程中要调用这些校准系数。标准单总线接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达 20 米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选择。产品为 3 引线(单总线接口)连接方便。特殊封装形式可根据用户需求而提供。


2、温湿度读取方式


    两种传感器均采用简化的单总线通信。单总线即只有一根数据线,系统中的数据交换、控制均由单总线完 成。设备(主机或从机)通过一个漏极开路或三态端口连至该数据线,以允许设备在不发送数据时能够释 放总线,而让其它设备使用总线;单总线通常要求外接一个约 4.7kΩ的上拉电阻,这样,当总线闲置时, 其状态为高电平。由于它们是主从结构,只有主机呼叫从机时,从机才能应答,因此主机访问器件都必须 严格遵循单总线序列,如果出现序列混乱,器件将不响应主机。


3、两种传感器的主要区别


   包括两点,分别是单总线起始信号的数据总线拉低时间和温湿度高低位数据含义。


   DHT11的单总线格式定义:


   DHT21的单总线格式定义:


4、微秒级延时函数


    根据上面的介绍我们现在需要一个微秒级的精确延时函数,否则就不能成功的读取传感器数据。STM32单片机的滴答定时器可以满足。


  (1)保证滴答定时器的时钟频率为72MHz


    STM32F103内部8M的内部震荡,经过倍频后最高可以达到72M。在固件库3.0以上,只需要通过两步就可以完成对时钟频率的选择。


   ①修改system_stm32f10x.c开头的时钟宏定义,如下:


/* #define SYSCLK_FREQ_HSE    HSE_VALUE */

/* #define SYSCLK_FREQ_24MHz  24000000 */ 

/* #define SYSCLK_FREQ_36MHz  36000000 */

/* #define SYSCLK_FREQ_48MHz  48000000 */

/* #define SYSCLK_FREQ_56MHz  56000000 */

#define SYSCLK_FREQ_72MHz  72000000

   ②在主函数main中调用SystemInit()函数。


   ③如果没有成功,需要检查单片机的晶振是否起振。简单的检测方法:


       有示波器的可以查看晶振的输出波形,正常应为正弦波。没有示波器的可以利用万用表分别测量晶振的管脚电平,正常应在1/2*VCC左右。


  (2)程序编写


    ①在main()函数中添加:SysTick_Config(72000000 / 1000000);//除以1000000微秒级(100000十微秒级,1000毫秒级),指进入中断的间隔时间


int main(void)

{      

    SystemInit();

    SysTick_Config(72000000 / 1000000);

}

    ②Delay.c


#include "stm32f10x.h"

#include "Delay.h"


int TimingDelay=0;


void delay_us(u32 n)

{

    TimingDelay=n;

  while(TimingDelay!=0); 

}

void delay_ms(u32 n)

{

    while(n--)

    {

     delay_us(1000);        

    }

}

      Delay.h


#ifndef _DELAY__H_

#define _DELAY__H_


void delay_us(u32 n);

void delay_ms(u32 n);


#endif

    ③stm32f10x_it.c


extern int TimingDelay;

void SysTick_Handler(void)

{

    if(TimingDelay!=0)

    {

        TimingDelay--;    

    }

}

5、编写读传感器数据程序


    ①DHxx.c


#include "stm32f10x.h"

#include "DHxx.h"

#include "Delay.h"

#include "sys.h"

u8 tdata[4]={0x00,0x00,0x00,0x00};

u8 sbuf,check;


//***************************************************************************/

//      //uchar       i;

//      uchar    U8FLAG,k;

//      uchar    U8count,U8temp;

//      uchar    U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;

//      uchar    U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;

//      uchar    U8comdata;

//      uint   ReceiveHighByte;

//      uint   ReceiveLowByte;

//***************Global defination for DHT11 end****// 

void DHT_PortIN(void)

{

    GPIO_InitTypeDef  GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;     

    GPIO_Init(GPIOB,&GPIO_InitStructure);

}

void DHT_PortOUT(void)

{

    GPIO_InitTypeDef  GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     

    GPIO_Init(GPIOB,&GPIO_InitStructure);

}

unsigned char StartDHT11(void)

{

   DHT_PortOUT();

   DHT_Out = 0;

   delay_ms(20);  //DHT11>18ms

  

   DHT_Out = 1;    

     DHT_PortIN();

   delay_us(20);  


   if(!DHT_In)

   {

           while(!DHT_In);

           while(DHT_In);

           return 1;

   }

    return 0;

}


unsigned char StartDHT21(void)

{

   DHT_PortOUT();

   DHT_Out = 0;

   delay_ms(1);  //DHT21>800us

  

   DHT_Out = 1;

     DHT_PortIN();

   delay_us(20);  


   if(!DHT_In)

   {

            while(!DHT_In);

           while(DHT_In);

           return 1;

   }

    return 0;

}

void com(void)

{

    u8 i,tt;

    tt = 0;

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

    {

        sbuf <<= 1;

        delay_us(20);

        while(!DHT_In);

        delay_us(25);

        tt = 100;

        while(tt++);

        if(DHT_In)

        {

             sbuf |= 0x01;

             delay_us(30);

        }

        else

        {

            sbuf &= 0xfe;

        }

    }

}

u8 ReadDHT11(void)

{

    u8 sum;

    if(StartDHT11())    

    {

        com();

        tdata[0]=sbuf;

        com();

        tdata[1]=sbuf;

        com();

        tdata[2]=sbuf;        

        com();

        tdata[3]=sbuf;

        com();

        check = sbuf;

        sum = (tdata[0]+tdata[1]+tdata[2]+tdata[3]);

    }

    if(check == sum)

    return(1);

    else    

    return 0;

}


u8 ReadDHT21(void)

{

    u8 sum;

    if(StartDHT21())    

    {

        com();

        tdata[0]=sbuf;

        com();

        tdata[1]=sbuf;

        com();

        tdata[2]=sbuf;        

        com();

        tdata[3]=sbuf;

        com();

        check = sbuf;

        sum = (tdata[0]+tdata[1]+tdata[2]+tdata[3]);

    }

    if(check == sum)

    return(1);

    else    

    return 0;

}

    DHxx.h                     //(注意:我这边定义的DATA管脚为PB1)


#ifndef _DHXX__H_

#define _DHXX__H

#include "sys.h"

#define DHT_Out PBout(1)

#define DHT_In  PBin(1)


#define uchar unsigned char 

#define uint  unsigned int


unsigned char StartDHT11(void);

unsigned char StartDHT21(void);

void DHT_PortIN(void);

void DHT_PortOUT(void);

u8 ReadDHT11(void);

u8 ReadDHT21(void);

void com(void);

//**********************************


//**********************************


extern u8 tdata[4];

extern u8 sbuf;

extern u8 check;


#endif

    ②sys.h


#include "stm32f10x

[1] [2]

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

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

上一篇:STM32 DTH11温湿度模块读写代码
下一篇:stm32驱动DHT11温湿度模块使用方法和问题小结

关注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