STM8 DHT11温湿度传感器

  DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上。

型号温度范围温度精度湿度范围湿度精度
DHT110~50°C±2°C20~90%RH±5%RH

一.接口说明

在这里插入图片描述  建议连接线长度短于20米时用5K上拉电阻,大于20米时根据实际情况使用合适的上拉电阻,供电电压3~5.5V.

二.通信协议

单总线通信,数据获取间隔建议大于1s.

通信总过程

通信总过程如下图1:
图1 通信总过程

图1 通信总过程

  总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。

起始信号

图2 起始信号

图2 起始信号

  总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定了数据位是0还是1.格式见下面图示.如果读取响应信号为高电平,则DHT11没有响应,请检查线路是否连接正常.当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。

数据信号

数字0信号表示方法如图3所示:
图3 信号0

图3 信号0

数字1信号表示方法.如图4所示:
图4 信号1
图4 信号1

数据解析

一次完整的数据传输为40bit,高位先出。
数据格式:
  8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据 +8bit校验和
  数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。

三. 封装与引脚对应

图5 封装

图5 封装

引脚说明

Pin名称注释
1VDD供电3~5.5V
2DATA数据
3NC空脚
4GND

四. 代码

时钟初始化(重要):单总线有us级时序要求,延时与主频相关

/*** @brief  系统时钟初始化* @param  None* @retval None*/
static void System_Timer_Init(void)
{CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);    /*时钟   初始化时钟为1分频 16M   2分频8M*/
}

DHT11数据读取程序:ms级延时来自于一个定时器,us级延时由逻辑分析仪测试加实验调整获得。

#include 
#include 
#include 
#include "bsp_task.h"
#include "hw_DHT11_driver.h"#define DHT11_PORT  GPIOC
#define DHT11_PIN   GPIO_PIN_6#define DHT11_OUT   GPIO_Init(DHT11_PORT, DHT11_PIN, GPIO_MODE_OUT_PP_HIGH_FAST)   //输出模式
#define DHT11_IN    GPIO_Init(DHT11_PORT, DHT11_PIN, GPIO_MODE_IN_PU_NO_IT)        //输入模式
#define DHT11_H     GPIO_WriteHigh(DHT11_PORT,DHT11_PIN)                           //输出高
#define DHT11_L     GPIO_WriteLow(DHT11_PORT,DHT11_PIN)                            //输出低
#define DHT11_READ  GPIO_ReadInputPin(DHT11_PORT,DHT11_PIN)                        //数据读出static bool hw_dht11_data_get(uint8_t *data);
static uint8_t debug[5] = {0};/*** @brief  us级延时--非精准* @param  us  延时计数  24==100us 12==52.5us* @retval None*/
static void hw_dht11_delay_us(uint32_t us)
{while(us--);
}/*** @brief  获得DHT11 1 bit数据* @param  None* @retval 数据*/
static uint8_t hw_dht11_bit_get(void)
{uint8_t temp = 0;for(int j = 0; j < 8; j++)      //获取一个字节{while(DHT11_READ == RESET); //等待字节起始低电平结束hw_dht11_delay_us(8);      	//大于40us (要求大于30us,小于70us)temp <<= 1;if(DHT11_READ != RESET){temp |= 0x01;}while(DHT11_READ != RESET); //等待高电平结束}return temp;
}/*** @brief  获得DHT11温湿度数据* @param  data  数据接收缓存(5字节)* @retval true 获取成功   false 获取失败* @note   采样间隔必须大于1s,采样过程禁止打断*/
static bool hw_dht11_data_get(uint8_t *data)
{DHT11_OUT;DHT11_H;                //准备--总线空闲Task_Delay_Ms_Time(2);  //延时2msDHT11_L;                //总线拉低--主机开始信号Task_Delay_Ms_Time(25); //保持25ms --大于18msDHT11_H;                //结束开始信号hw_dht11_delay_us(10);  //延时 20us~40usDHT11_IN;               //切换输入模式 准备读响应if(DHT11_READ != RESET)     //未检测到应答{return false;}while(DHT11_READ == RESET); //等待应答结束while(DHT11_READ != RESET); //等待DHT11发送起始高电平结束for(int i = 0; i < 5; i++)  //共5字节{data[i] = hw_dht11_bit_get();}DHT11_OUT;DHT11_H;                	//准备--总线空闲return true;
}/*** @brief  获得DHT11温湿度数据* @param  temp 温度     hum 湿度* @retval false 数据错误  true 数据正常*/
bool hw_dht11_th_count(uint16_t *temp,uint16_t *hum)
{uint8_t dht11_data[5] = {0};if(!hw_dht11_data_get(dht11_data))return false;memcpy(debug,dht11_data,5);if(dht11_data[0] + dht11_data[1] + dht11_data[2] + dht11_data[3] != dht11_data[4])return false;*hum = 0xf0 | dht11_data[0];*hum <<= 8;*hum |= dht11_data[1];*temp = 0xf0 | dht11_data[2];*temp <<= 8;*temp |= dht11_data[3];return true;
}

五.文章引用

https://blog.csdn.net/u013151320/article/details/50389624
https://wenku.baidu.com/view/29bc6e8fb4daa58da1114a3a.html
https://blog.csdn.net/qq_27508477/article/details/83661672


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部