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

2019-08-15来源: 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/ic471163.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:stm32驱动DHT11温湿度模块使用方法和问题小结
下一篇:STM32学习笔记一一触摸屏

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

推荐阅读

stm32CAN波特率计算小程序(QT源码)

软件:Qt Creator开发环境:Window7用qt做得一个计算波特率的小程序,在实际的应用中我们设置波特率的时候是通过以下参数来定的:CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;CAN_InitStructure.CAN_BS1=CAN_BS1_9tq;CAN_InitStructure.CAN_BS2=CAN_BS2_6tq;CAN_InitStructure.CAN_Prescaler=5;波特率计算小程序的截图:   根据所需的的采样点、波特率以及错误率得到以上外设初始化所需的参数。据网上资料,采样点的设置有以下规律:75%   
发表于 2019-08-20
stm32CAN波特率计算小程序(QT源码)

stm32之ADC应用实例(单通道、多通道、基于DMA)

硬件:STM32F103VCT6开发工具:Keil uVision4下载调试工具:ARM仿真器网上资料很多,这里做一个详细的整合。(也不是很详细,但很通俗)。所用的芯片内嵌3个12位的模拟/数字转换器(ADC),每个ADC共用多达16个外部通道,2个内部通道。3个:代表ADC1、ADC2、ADC3(下图是芯片固件库的截图)12位:也叫ADC分辨率、采样精度。先来看看二进制的12位可表示0-4095个数,也就是说转换器通过采集转换所得到的最大值是4095,如:“111111111111”=4095,那么我们怎么通过转换器转换出来的值得到实际的电压值呢?如果我们要转换的电压范围是0v-3.3v的话,转换器就会把0v-3.3v平均
发表于 2019-08-20
stm32之ADC应用实例(单通道、多通道、基于DMA)

stm32之TIM-基本定时器应用实例(详细)

开发环境:Window 7开发工具:Keil uVision4硬件:STM32F103VCT6定时器最基本的功能就是定时处理事情。比如定时发送USART数据、定时采集AD数据、定时检测IO口电位、还可以通过IO口输出波形等。可以实现非常丰富的功能。STM32系列的定时器分为基本定时器、通用定时器、高级控制定时器。后者包括前者的全部功能。所以先掌握基本定时器可以更好理解后面功能繁多的定时器。通常地,STM32高级定时器TIM1、TIM8,通用定时器TIM2、TIM3、TIM4、TIM5,基本定时器TIM6、TIM7。有用过STM32的话都知道,STM32所有的外设初始化都是使用标准库里的初始化结构体和初始化函数,下面先说一下
发表于 2019-08-20
stm32之TIM-基本定时器应用实例(详细)

stm32之TIM-高级定时器应用实例一(详细)

硬件:stm32f103c8t6开发工具:Keil uVision4下载调试工具:ARM仿真器        如果第一次接触定时器,可以先看基本定时器。本篇内容较多,如果想直接动手操作,可以跳到后面的实验代码。        stm32标准库对定时器外设建立了4个初始化结构体,定时器分为基本定时器、通用定时器、高级定时器,针对不用的定时器要使用不同初始化结构体。下面是4个初始化结构体的适用分类:TIM_TimeBaseInitTypeDef  (基本定时器、通用定时器、高级定时器)TIM_OCInitTypeDef   
发表于 2019-08-20
stm32之TIM-高级定时器应用实例一(详细)

stm32之iap实现应用(基于串口,上位机,详细源码)

除了用烧录器读写外,还可以在芯片运行时,对自身的内部flash进行读写。如果flash储存了程序后还有剩余的空间,那么可以把它用来保存程序运行时产生需要掉电保存的数据;也可以在芯片运行时将另一个编译后的二进制程序文件写到剩余的flash,然后进行跳转到新的程序上面运行。这也是iap的实现原理。1.先介绍怎么利用stm库对flash进行操作所有flash操作相关的函数接口在stm32f10x_flash.h里面。读flash里面的数据直接根据地址读出来就行了。往写flash里面写数据,需要解锁,擦除,写入数据,上锁;擦除后存储单元都变成1,因为储存单元不能由0变1,所以在写入之前一定要先擦除,不然会写入失败。操作代码如下:#define
发表于 2019-08-20
stm32之iap实现应用(基于串口,上位机,详细源码)

stm32之USB应用实例(官方例程资料下载使用)

开发环境:Window 7开发工具:Keil uVision5硬件:stc32f103c8t6stm32系列芯片很多都拥有一个USB2.0全速的通讯接口,下面介绍怎么使用st官方的usb应用例程。首先从官网下载源码:https://my.st.com/content/my_st_com/en/products/embedded-software/mcu-mpu-embedded-software/stm32-embedded-software/stm32-standard-peripheral-library-expansion/stsw-stm32121.html需要登录才能下载,如果没有账号,注册一个也很快的。下载解压,打开
发表于 2019-08-20
stm32之USB应用实例(官方例程资料下载使用)

小广播

何立民专栏

单片机及嵌入式宝典

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

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