《电子DIY》之基于STM32驱动温湿度传感器DHT11、DHT12
作者:互联网
一,DHT11(12)传感器简介
DHT11 是一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,通过单片机等微处理器简单的电路连接就能够实时的采集本地湿度和温度。DHT11 与单片机之间能采用简单的单总线进行通信,仅仅需要一个I/O 口。传感器内部湿度和温度数据 40Bit 的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。DHT11 功耗很低,5V 电源电压下,工作平均最大电流 0.5mA。
湿度:
湿度,表示大气干燥程度的物理量。在一定的温度下在一定体积的空气里含有的水汽越少,则空气越干燥;水汽越多,则空气越潮湿。空气的干湿程度叫做“湿度”。在此意义下,常用绝对湿度、相对湿度、比较湿度、混合比、饱和差以及露点等物理量来表示;若表示在湿蒸汽中水蒸气的重量占蒸汽总重量(体积)的百分比,则称之为蒸汽的湿度。人体感觉舒适的湿度是:相对湿度低于70%(摘自百度)
工作特性:
工作电压范围:3.5V-5.5V
工作电流 :平均 0.5mA
湿度测量范围:20-90%RH
温度测量范围:0-50℃
湿度分辨率 :1%RH 8 位
温度分辨率 :1℃ 8 位
采样周期 :1S
单总线结构
与 TTL 兼容(5V)
(摘自芯片手册)
二、引脚定义
三、典型连接电路
DHT11 数字湿温度传感器连接方法简单。第一脚接电源正,第四脚接电源地端。数据端为第二脚。可直接接主机(单片机)的 I/O 口。为提高稳定性,通常在数据端和电源正之间接一只 4.7K左右 的上拉电阻。第三脚为空脚,此管脚悬空不用。
四、DHT11内部数据结构
DHT11数字湿温度传感器采用单总线数据格式。即,单个数据引脚端口完成输入输出双向传输。其数据包由5Byte(40Bit)组成。数据分小数部分和整数部分。
一次完整的数据传输为40bit,高位先出
数据格式:
8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验和
注:
1,校验和数据为前四个字节相加
2,传感器数据输出的是未编码的二进制数据,即数据(湿度、温度、整数、小数)之间应该分开处理
采集数据后的处理方式举例:
(设某时刻采集的数据如下:)
byte4 byte3 byte2 byte1 byte0
00101101 00000010 00011100 00000001 01001001 (二进制)
2DH 02H 1CH 01H 49H (十进制)
45 2 28 1 76
整数 小数 整数 小数 校验和
湿度 温度 校验和
由以上数据就可得到湿度和温度的值,计算方法:
humi (湿度)= byte4 . byte3=45.2 (%RH)
temp (温度)= byte2 . byte1=28.1 ( ℃)
(校验和)= byte4+ byte3+ byte2+ byte1=76(=humi+temp)(校验正确)
注意:DHT11一次通讯时间最大3ms,主机连续采样间隔建议不小于100ms。
五、DHT11采样时序
DHT11 开始发送数据流程:
分析:
主机发送开始信号后,延时等待 20us-40us 后读取 DHT11 的应答信号,读取总线为低电平,说明 DHT11 发送响应信号,DHT11 发送响应信号后,再把总线拉高,准备发送数据,每一 bit 数据都以低电平开始,格式见如果读取响应信号为高电平,则 DHT11 没有响应,请检查线路是否连接正常。
主机复位信号和 DHT11 响应信号
数字‘0’信号表示方法
数字‘1’信号表示方法
六、DHT11程序源码
程序源码:
注:使用串口打印采集的温湿度数据(1秒采集一次数据)
DHT11 h文件
//Author: Liu Xianfei 0810
#ifndef __DHT11_H
#define __DHT11_H
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
typedef struct __DHT11_2
{
u8 temperature[2]; //temperature
u8 humidity[2]; //humidity
u16 checksum; //checksum
}DHT11;
extern DHT11 dht11;
#define DHT11PORT GPIOA
#define DHT11PIN GPIO_Pin_11
#define DHT11CLK RCC_APB2Periph_GPIOA
//IO direction setting
#define DHT11_2_IO_IN() {GPIOA->CRH&=0XFFFF0FFF;GPIOA->CRH|=8<<12;}
#define DHT11_2_IO_OUT() {GPIOA->CRH&=0XFFFF0FFF;GPIOA->CRH|=3<<12;}
//IO operation function
#define DHT11_2_DQ_OUT PAout(11)
#define DHT11_2_DQ_IN PAin(11)
//Function declaration
void DHT11_2_Init(void);
u8 DHT11_2_Read_Data(void);
u8 DHT11_2_Read_Byte(void);
u8 DHT11_2_Read_Bit(void);
u8 DHT11_2_Check(void);
void DHT11_2_Rst(void);
#endif
DHT11 C文件
#include "DHT11.h"
DHT11 dht11={0,0,0,0,0};
/*
* Function name: initialize DHT11
* Parameter: None
* Return value: None
* Author: Liu Xianfei 0810
*/
void DHT11_2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(DHT11CLK,ENABLE);//Turn on the clock
//Initialization pin
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin=DHT11PIN;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(DHT11PORT,&GPIO_InitStruct);
GPIO_SetBits(DHT11PORT,DHT11PIN);//Pull up pin
}
/*
* Function name: reset DHT11
* Parameter: None
* Return value: None
*/
void DHT11_2_Rst(void)
{
DHT11_2_IO_OUT(); //SET OUTPUT
DHT11_2_DQ_OUT=0; //pull downDQ
delay_ms(20); //Pull down for at least 18ms
DHT11_2_DQ_OUT=1; //DQ=1
delay_us(30); //Main engine pull-up 20 ~ 40us
}
/*
* Function name: waiting for DHT11 to respond
* Parameter: None
* Return value: 1: DHT11 not detected 0: DHT11 detected
*/
u8 DHT11_2_Check(void)
{
u8 retry=0;
DHT11_2_IO_IN();//SET INPUT
while (DHT11_2_DQ_IN&&retry<100)//DHT11 will pull down 40~80us
{
retry++;
delay_us(1);
};
if(retry>=100)
return 1;
else
retry=0;
//When DHT11 is pulled down, it will be pulled up again by 40-80us
while (!DHT11_2_DQ_IN&&retry<100)
{
retry++;
delay_us(1);
};
if(retry>=100)
return 1;
return 0;
}
/*
* Function name: read a bit from DHT11
* Parameter: None
* Return value: 1 or 0
*/
static u8 DHT11_2_Read_Bit(void)
{
u8 retry=0;
while(DHT11_2_DQ_IN&&retry<100)//Waiting for low level
{
retry++;
delay_us(1);
}
retry=0;
while(!DHT11_2_DQ_IN&&retry<100)//Waiting for high level
{
retry++;
delay_us(1);
}
delay_us(40);
if(DHT11_2_DQ_IN)
return 1;
else
return 0;
}
/*
* Function name: read a byte from DHT11
* Parameter: None
* Return value: data of 1B
* Author: Liu Xianfei 0810
*/
static u8 DHT11_2_Read_Byte(void)
{
u8 i,dat;
dat=0;
for (i=0;i<8;i++)
{
dat<<=1;
dat|=DHT11_2_Read_Bit();
}
return dat;
}
/*
* Function name: read data once from DHT11
* Parameter: temp: temperature value (range: 0 ~ 50 °) humi: humidity value (range: 20% ~ 90%)
* Return value: 0, normal; 1, read failed
*/
u8 DHT11_2_Read_Data(void)
{
u8 buf[5];
u8 i;
DHT11_2_Rst();
if(DHT11_2_Check()==0)
{
for(i=0;i<5;i++)//Read 40 bit data
{
buf[i]=DHT11_2_Read_Byte();
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
//Assignment
dht11.humidity[0]=buf[0];
dht11.humidity[1]=buf[1];
dht11.temperature[0]=buf[2];
dht11.temperature[1]=buf[3];
dht11.checksum=buf[4];
}
}
else
return 1;
return 0;
}
延时函数 h文件
/*
Filename: delay function
Author: Liu Xianfei 0810
Related note: use the system tick counter to realize the delay function
*/
#ifndef _delay_H
#define _delay_H
#include "sys.h"
void delay_init_liuxianfei0810(void);
void delay_ms(u16 nms);
void delay_us(u32 nus);
#endif
延时函数 c文件
#include "delay.h"
static u8 fac_us=0; //us delay multiplier
static u16 fac_ms=0; //ms delay multiplier
/*
Function name: initialization delay function
Author: Liu Xianfei 0810
Description:
Systick clock is fixed to 1/8 of HCLK clock
Sysclk: system clock
*/
void delay_init_liuxianfei0810(void)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
//Select external clock HCLK/8
fac_us=SystemCoreClock/8000000;
//1/8 of the system clock
fac_ms=(u16)fac_us*1000;
//Represents the number of systick clocks required per ms
}
/*
Function name: delay NUS function
Author: Liu Xianfei 0810
Description:
nus is the number of us to delay MAXnus=2^24(LOAD)/fac_us
=2^24(LOAD)/(SystemCoreClock/8000000)=2^24(LOAD)/9
*/
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //Time loading
SysTick->VAL=0x00; //Clear counter
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //Start countdown
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //Waiting time arrives
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //Turn off counter
SysTick->VAL =0X00; //Clear counter
}
/*
Function name: delay NMS function
Author: Liu Xianfei 0810
Description: Delay nms
Note the range of nms
Systick -> load is a 24 bit register, so the maximum delay is:
nms<=0xffffff*8*1000/SYSCLK
Sysclk in Hz, nms in nms
For 72MHz clock, nms <= 1864
*/
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms;
//Time loading (systick ->LOAD is 24bit)
SysTick->VAL =0x00;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16)));
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL =0X00;
}
七、效果图
标签:delay,湿度,温湿度,void,STM32,DIY,SysTick,GPIO,DHT11 来源: https://blog.csdn.net/liuxianfei0810/article/details/105886238