1.DHT11简介
DHT11是一款性价比极高的温湿度传感器,其温度测量范围:0-50℃,测量误差:±2℃;湿度测量范围:20-90%RH,测量误差:±5%RH。尽管其精度不高,但是可以满足大部分应用场合。为了通过DHT11读取温湿度,我们更关心的是其与单片机的通信问题,DHT11共有三个引脚,其中VCC与GND是电源引脚,DIO是通信引脚,由于其只需要一根线就可以通信,又称为单总线通信。有关DTH11单总线通信的协议,可参考:https://blog.csdn.net/qq_21990661/article/details/81043121。
2.硬件连接
在STM32 MCU和DHT11的通信中,采用任意一个普通I/O口即可,DHT11的VCC接3.3V,GND连接到地,这里采用DHT11模块,模块在某宝可以买到,基本上加邮费都不超过10元。具体的硬件连接原理图如下:
3.软件实现
软件在实现上只需要按照协议进行编写即可,网上参考资料也比较多,dht11的驱动文件由.c和.h共同完成,这里采用的通信I/O为单片机的PA12引脚,其主要内容参考如下:
- dht11.h
/**********************************************************************************************************
author: 芯晟科电子
date : 2020/05/03
copyright : 2020-2030
**********************************************************************************************************/
#ifndef _DTH11_H
#define _DTH11_H
#include "stm32f10x.h"
#include "delay.h"
#include "string.h"
//引脚方向设置
#define DTH11_IO_IN() {GPIOA->CRH&=0XFFF0FFFF;GPIOA->CRH|=0X00080000;GPIOA->ODR|=1<<12;}
#define DTH11_IO_OUT() {GPIOA->CRH&=0XFFF0FFFF;GPIOA->CRH|=0x00030000;}
//位操作-PA12
#define DTH11_DQ_OUT *((volatile uint32_t*)( 0x42000000+ ((0x10000+0x0800+0x0c)<<5) + (12<<2)))
#define DTH11_DQ_IN *((volatile uint32_t*)( 0x42000000+ ((0x10000+0x0800+0x08)<<5) + (12<<2)))
typedef struct
{
uint8_t humi;
uint8_t temp;
} DefType_DTH11;
void dth11_init(void);
void dth11_rst(void);
uint8_t dth11_check(void);
uint8_t dth11_ReadBit(void);
uint8_t dth11_ReadByte(void);
void dth11_ReadData(DefType_DTH11* pTemp);
#endif
- dht11.c
/**********************************************************************************************************
author: 芯晟科电子
date : 2020/05/03
copyright : 2020-2030
**********************************************************************************************************/
#include "dth11.h"
void dth11_init(void)
{
RCC->APB2ENR|=1<<2;
GPIOA->CRH&=0XFFF0FFFF;
GPIOA->CRH|=0X00030000;
DTH11_DQ_OUT=1;
dth11_rst();
dth11_check();
delay_ms(300);
}
void dth11_rst(void)
{
DTH11_IO_OUT();
DTH11_DQ_OUT=0;
delay_ms(20);
DTH11_DQ_OUT=1;
delay_us(30);
}
// if return 0--yes return 1--no no no
uint8_t dth11_check(void)
{
uint8_t retry=0;
DTH11_IO_IN();
while(DTH11_DQ_IN&&retry<100)
{
retry++;
delay_us(1);
}
if(retry>=100) return 1;
else retry=0;
while ((!DTH11_DQ_IN)&&(retry<100))
{
retry++;
delay_us(1);
}
if(retry>=100) return 1;
return 0;
}
uint8_t dth11_ReadBit(void)
{
uint8_t retry=0;
while(DTH11_DQ_IN&&retry<100)
{
retry++;
delay_us(1);
}
retry=0;
while((!DTH11_DQ_IN)&&(retry<100))
{
retry++;
delay_us(1);
}
delay_us(40);
if(DTH11_DQ_IN) return 1;
else return 0;
}
uint8_t dth11_ReadByte(void)
{
uint8_t i,dat=0;
for (i=0;i<8;i++)
{
dat<<=1;
dat|=dth11_ReadBit();
}
return dat;
}
void dth11_ReadData(DefType_DTH11 *pTemp)
{
uint8_t buf[5];
uint8_t i;
dth11_rst();
if(dth11_check()==0)
{
for(i=0;i<5;i++)
{
buf[i]=dth11_ReadByte();
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
pTemp->humi=buf[0];
pTemp->temp=buf[2];
}
}
}
- main.c
/**********************************************************************************************************
author: 芯晟科电子
date : 2020/05/03
copyright : 2020-2030
**********************************************************************************************************/
#include "gui.h"
#include "core_cm3.h"
#include "dth11.h"
#include "delay.h"
int main(void)
{
DefType_DTH11 temp_humi={0};
SystemInit();
delay_init();
gui_init();
dth11_init();
gui_printf(0,0,gb16,white,black," T&H System ");
delay_ms(1000);
gui_printf(6,18,gb24,white,black," Welcome!");
delay_ms(1000);
gui_printf(5,48,gb12,white,black," ---by XISKO");
delay_ms(1000); delay_ms(1000);
gui_clear(black);
gui_printf(24,0,gb16,white,black,"温湿度测量");
gui_draw_bitmap(92,18,th_icon);
while(1)
{
dth11_ReadData(&temp_humi);
gui_printf(0,16,gb24,white,black,"T: %2d",temp_humi.temp);
gui_printf(62,18,gb16,white,black,"℃");
gui_printf(0,40,gb24,white,black,"H: %2d",temp_humi.humi);
gui_printf(65,42,gb16,white,black,"%%");
delay_ms(200);
}
}
4.实验结果
将代码编绎后下载到开发板中,结果如下图所示: