stm32读取温湿度传感器dht11和dht21(am2301)系列问题(代码片段)

Dream Dream     2022-11-01     398

关键词:

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.h"

///////////////////////////////////////////////////////////////
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 
//IO地址映射
#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C 
#define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C 
#define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C 
#define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C 
#define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C 
#define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C    
#define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C    

#define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808 
#define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 
#define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008 
#define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408 
#define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808 
#define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08 
#define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08 
 
//IO口操作,只针对单一的IO口//n的值小于16
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) #define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) #define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) #define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) #define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) #define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) #define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) #define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) #define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) /////////////////////////////////////////////////////////////////

    ③main.c

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include <stdio.h>
#include "system.h"
#include "sys.h"
#include "DHxx.h"
#include "Delay.h"
int main(void)
      
    SystemInit();
    SysTick_Config(72000000 / 1000000);
    while(1)
    
        ReadDHT11();// ReadDHT21();//读取的信息在DHxx.c的tdata[]数组中
        delay_ms(1000);
        delay_ms(1000);  //注意读取间隔应该在2秒以上 
        
    

6、参考

【1】单片机stm32时钟频率 http://www.elecfans.com/dianzichangshi/20171113578546.html

【2】https://wenku.baidu.com/view/6306fbf484254b35eefd3428.html

【3】http://www.aosong.com/products-28.html

  

人不曾老去,直至悔恨取代了梦想!---约翰.巴里摩

 转载需说明出处,笔者总结之前的知识,与大家分享,有问题的可以留给我哦~

     

     

    

     

      

 

 

   

 

   

12-开发板接入小五物联实现远程控制(stm32采集温湿度传感器dht11)(代码片段)

采集DHT11温湿度数据,使用stm32f103zet6的GPIOG11引脚读取SHT11数据,通过串口打印采集的温湿度 dht11.c文件:#include"dht11.h"#include"delay.h"//复位DHT11voidDHT11_Rst(void)DHT11_IO_OUT();//SETOUTPUTDHT11_DQ_OUT=0;//拉低DQdelay_ms(20);/ 查看详情

micropythonesp32读取dht11温湿度传感器数据(代码片段)

MicroPythonESP32读取DHT11温湿度传感器数据DHT11温湿度传感器接线说明ESP32-----DHT113.3V-----VCCGND-----GNDGPIO22-----DOUT本示例基于Thonny平台开发所引入的模块,如果没有按照,可以通过pipinstallxxxx命令在命令提示窗中进行安装,或... 查看详情

stm32实例——基于stm32开发板实现传感数据采集-dht11温湿度采集(代码片段)

STM32开发板实现传感数据采集-DHT11温湿度采集一、前言本项目是基于STM32开发板的温湿度采集,传感器采用DHT11温湿度传感器,软件采用keil5等。本项目采用ARM结构中最为代表的Cortex-M4系列的芯片,选用STM32F407ZGT6开发板... 查看详情

《嵌入式-stm32开发指南》第三部分外设篇-第1章温湿度传感器dht11(代码片段)

1.1理论分析1.1.1DHT11介绍DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。DHT11传感器包括一个... 查看详情

micropythonesp32读取dht11温湿度传感器数据+0.96“i2coled显示(代码片段)

【MicroPythonesp32】读取DHT11温湿度传感器数据+0.96“I2Coled显示✨本示例基于Thonny平台开发。相关篇《【MicroPythonRP2040】读取DHT11温湿度传感器数据+0.96“I2Coled显示》-📖ESP32dev引脚功能图🎄DHT11传感器🎄ssd1306I2C0.96... 查看详情

stm32实例——基于stm32开发板实现传感数据采集-dht11温湿度采集(代码片段)

STM32开发板实现传感数据采集-DHT11温湿度采集一、前言本项目是基于STM32开发板的温湿度采集,传感器采用DHT11温湿度传感器,软件采用keil5等。本项目采用ARM结构中最为代表的Cortex-M4系列的芯片,选用STM32F407ZGT6开发板... 查看详情

esp3222.智能家居-dht11温湿度采集(wifi)

上一篇:【ESP32】21.WIFIWebServers继电器实验(ESPAsyncWebServer-异步服务器库)前言:先放电路连接图:ESP32最为核心的就是自带蓝牙和WiFi功能。可以通过简单的设置使esp32模块联网,完成物联网的基础配置,进而完成相关操作。DHT11... 查看详情

esp3222.智能家居-dht11温湿度采集(wifi)

上一篇:【ESP32】21.WIFIWebServers继电器实验(ESPAsyncWebServer-异步服务器库)前言:先放电路连接图:ESP32最为核心的就是自带蓝牙和WiFi功能。可以通过简单的设置使esp32模块联网,完成物联网的基础配置,进而完成相关操作。DHT11... 查看详情

温湿度传感器(代码片段)

温湿度传感器硬件使用STM32F103RCT6DHT11(温湿度传感器)软件使用keil5MDK环境串口调试助手实现说明​根据DHT11温湿度传感器手册1.初始化DHT11复位DHT11,根据时序图写出设置```voiddht_Rst(void) dht_output();//设置dht11为普通推挽输出 dh... 查看详情

stm32+dht11温湿度数据实验-stm32将采集dht11温湿度通过usart1在串口助手打印(代码片段)

...把stm32的两个实验组合起来实现一个简单的室内温度计,温湿度数据显示在oled上,学以致用嘛岂不美哉1#ifndef__DHT11_H2#define__DHT11_H34#include"stm32f10x.h"5#include"delay.h"67#defineHIGH18#defineLOW0910#defineDHT11_CLKRCC_APB2Periph_GPIOC11#defineDHT11_PINGPIO_Pi... 查看详情

arduioesp32将dht11温湿度传感器数据在网页上显示(代码片段)

ArduioESP32将DHT11温湿度传感器数据在网页上显示串口监视数据和网页数据同步显示温湿度传感器ESP32开发板接线说明DHT11----ESP8266Data-----D7(gpio13)-- 查看详情

esp3214.dht11湿度传感器实验(dht操作库)

...言:先放电路连接图:DHT11是一款已校准数字信号输出的温湿度传感器,湿度精度为+-5%RH,温度精度为+-2℃。量程的话湿度为20~90%RH,温度为0~50℃。和上一篇的DS18B20相同,DHT11也是用的单总线协议,单总线对于总线的延时非常严... 查看详情

esp3214.dht11湿度传感器实验(dht操作库)

...言:先放电路连接图:DHT11是一款已校准数字信号输出的温湿度传感器,湿度精度为+-5%RH,温度精度为+-2℃。量程的话湿度为20~90%RH,温度为0~50℃。和上一篇的DS18B20相同,DHT11也是用的单总线协议,单总线对于总线的延时非常严... 查看详情

2.3.1传感器模块之dht11

....1main10.2dht11.c10.3dht11.hDHT11是一款有已校准数字信号输出的温湿度传感器。其精度湿度 查看详情

stm32-dht11温湿度传感器寄存器版本

参考技术A#include<stm32f4xx.h>#include"DHT11.h"#include"TIM6.h"/*函数功能:GPIO输出配置函数参数:返回值:说  明:PC0-DATA*/voidDHT11_OUT1()//时钟使能RCC->AHB1ENR|=(1<<2);//设置GPIO工作模式GPIOC->MODER&=~(3<<0);G... 查看详情

基于stm32温湿度传感器采集报警系统设计(含超声波测距)(代码片段)

...02中显示出来,还有就是可以设置通过按键设置DHT11的温湿度阈值。仿真原理图如下运行结果图:按下K1,K2为加1设置,K3为减1设置  湿度低于88%;警报响,红灯亮 #include<stm32f4xx.h>#include"delay.h"#i... 查看详情

002_stm32程序移植之_dht11

1.测试环境:STM32C8T62.测试模块:DHT11温湿度模块3.测试接口:1.DHT11温湿度模块接口:DS1302引脚---------单片机引脚VCC--------------------3.3VGND-------------------GNDDATA-------------------PA5 2.串口使用串口一,波特率9600单片机引脚---------CH340... 查看详情

树莓派从dht11温度湿度传感器读取数据

时序图参考厂家说明书:DHT11数字湿温度传感器的原理和应用范例四个阵脚连接:VCC接3.3伏电源,Dout接GPIO口,我接的是物理12针脚,NC留空,GND接地。波折1:电阻被错接进了VCC,于是看了无数遍时序图,改了无数遍的驱动无论怎... 查看详情