|
本帖最后由 bigfanofloT 于 2017-5-16 19:44 编辑
一、DHT11介绍
DHT11是一款有已校准数字信号输出的温湿度传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,使其成为该类应用中,在苛刻应用场合的最佳选择。产品为4针单排引脚封装,连接方便。
主要性能指标如下:
测量范围:湿度20-90%RH, 温度0~50℃
分辨率:湿度1%RH, 温度1℃
精度:湿度+/-5%RH, 温度+/-2℃
量程:湿度20-90%RH, 温度0~50℃
供电电压 :3.3~5.5V DC
输 出:单总线数字信号
长期稳定性: <±1%RH/年
图1 DHT11实物图
DHT11输出单总线数字信号,可以十分方便的与MCU连接,典型使用方法如图2所示:
图2 DHT11典型应用电路
二、硬件连线
对于gokit V2.3扩展板,板载DHT11的数字输出IO连接到了arduino UNO接口的D3,如图3所示:
图3 Gokit V2.3扩展板DHT11原理图
根据Nucleo-F767ZI的原理图,图4可以知道,STM32F767ZIT6的GPIO PE13连接到了Arduino UNO接口的D3,因此在后面我们将配置PE13与DHT11通信,根据DHT11时序编写驱动。
图4 Nucleo-F767ZI的Arduino UNO接口原理图
三、DHT11时序
DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于以后扩展,现读出为零。
操作流程如下:
一次完整的数据传输为40bit,高位先出。
数据格式:8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和
数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。
用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集,如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。
通讯过程如下图:
总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。
总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定了数据位是0还是1.格式见下面图示.如果读取响应信号为高电平,则DHT11没有响应,请检查线路是否连接正常.当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。
数字0信号表示方法如下图:
数字1信号表示方法.如下图:
四、完整程序
如下是DHT11驱动的完整代码,用户可以十分方便的移植到其它型号STM32或者MCU,只需修改GPIO定义、GPIO读写即可。Hal_temp_hum.h文件如下:
- #ifndef _HAL_HEMP_HUM_H
- #define _HAL_HEMP_HUM_H
- #include <stdio.h>
- #include "stm32f7xx_hal.h"<font color="#008000">//若用户使用了其它MCU,需要修改此处MCU相关头文件</font>
- <font color="#008000">//Set GPIO Direction,若用户使用不同的GPIO请修改此处</font>
- #define DHT11_DIN_Pin GPIO_PIN_13
- #define DHT11_DIN_GPIO_Port GPIOE
- <font color="#008000">//控制GPIO输出高低电平宏</font>
- #define DHT11_DQ_OUT_1 HAL_GPIO_WritePin(DHT11_DIN_GPIO_Port, DHT11_DIN_Pin, GPIO_PIN_SET)
- #define DHT11_DQ_OUT_0 HAL_GPIO_WritePin(DHT11_DIN_GPIO_Port, DHT11_DIN_Pin, GPIO_PIN_RESET)
- <font color="#008000">//读取GPIO电平</font>
- #define DHT11_DQ_IN HAL_GPIO_ReadPin(DHT11_DIN_GPIO_Port, DHT11_DIN_Pin)
- #define MEAN_NUM 10
- typedef struct
- {
- uint8_t curI;
- uint8_t thAmount;
- uint8_t thBufs[10][2];
- }thTypedef_t;
- /* Function declaration */
- uint8_t dht11Init(void); //Init DHT11
- uint8_t dht11Read(uint8_t *temperature, uint8_t *humidity); //Read DHT11 Value
- static uint8_t dht11ReadData(uint8_t *temperature, uint8_t *humidity);
- static uint8_t dht11ReadByte(void);//Read One Byte
- static uint8_t dht11ReadBit(void);//Read One Bit
- static uint8_t dht11Check(void);//Chack DHT11
- static void dht11Rst(void);//Reset DHT11
- void dht11SensorTest(void);
- #endif /*_HAL_HEMP_HUM_H*/
复制代码
Hal_temp_hum.c文件如下:
- /**
- ******************
- *
- * @file Hal_temp_hum.c
- * @author Gizwtis
- * @version V03010100
- * @date 2016-07-05
- *
- * @brief 机智云.只为智能硬件而生
- * Gizwits Smart Cloud for Smart Products
- * 链接|增值ֵ|开放|中立|安全|自有|自由|生态
- * www.gizwits.com
- *
- ******************/
- #include "hal_temp_hum.h"
- #include <string.h>
- thTypedef_t temphumTypedef;
- void delayUs(uint32_t nus)
- {
- uint8_t i=0;
- while(nus--)
- {
- i=100; <font color="#008000">//自己定义,需根据系统时钟调整</font>
- while(i--) ;
- }
- }
- void DHT11_IO_OUT(void)
- {
- GPIO_InitTypeDef myGPIO_InitStruct;
- myGPIO_InitStruct.Pin = DHT11_DIN_Pin;
- myGPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- myGPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
- HAL_GPIO_Init(DHT11_DIN_GPIO_Port, &myGPIO_InitStruct);
- }
- void DHT11_IO_IN(void)
- {
- GPIO_InitTypeDef myGPIO_InitStruct;
- myGPIO_InitStruct.Pin = DHT11_DIN_Pin;
- myGPIO_InitStruct.Pull = GPIO_PULLUP;
- myGPIO_InitStruct.Mode = GPIO_MODE_INPUT;
- myGPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
- HAL_GPIO_Init(DHT11_DIN_GPIO_Port, &myGPIO_InitStruct);
- }
- //Reset DHT11
- static void dht11Rst(void)
- {
- DHT11_IO_OUT(); //SET OUTPUT
- DHT11_DQ_OUT_0; //GPIOA.0=0
- HAL_Delay(20); //Pull down Least 18ms
- DHT11_DQ_OUT_1; //GPIOA.0=1
- delayUs(30); //Pull up 20~40us
- }
- static uint8_t dht11Check(void)
- {
- uint8_t retry=0;
- DHT11_IO_IN(); //SET INPUT
- while (DHT11_DQ_IN && (retry<100)) //DHT11 Pull down 40~80us
- {
- retry++;
- delayUs(1);
- }
- if(retry >= 100)
- {
- return 1;
- }
- else
- {
- retry=0;
- }
- while (!DHT11_DQ_IN&& (retry < 100)) //DHT11 Pull up 40~80us
- {
- retry++;
- delayUs(1);
- }
- if(retry >= 100)
- {
- return 1; //check error
- }
- return 0;
- }
- static uint8_t dht11ReadBit(void)
- {
- uint8_t retry=0;
- while(DHT11_DQ_IN && (retry<100)) //wait become Low level
- {
- retry++;
- delayUs(1);
- }
- retry = 0;
- while(!DHT11_DQ_IN && (retry < 100)) //wait become High level
- {
- retry++;
- delayUs(1);
- }
- delayUs(30);//wait 40us
- if(DHT11_DQ_IN)
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- static uint8_t dht11ReadByte(void)
- {
- uint8_t i,dat;
- dat=0;
- for (i=0; i<8; i++)
- {
- dat<<=1;
- dat |= dht11ReadBit();
- }
- return dat;
- }
- static uint8_t dht11ReadData(uint8_t *temperature, uint8_t *humidity)
- {
- uint8_t buf[5];
- uint8_t i;
- dht11Rst();
- if(0 == dht11Check())
- {
- for(i=0; i<5; i++)
- {
- buf[i] = dht11ReadByte();
- }
- if(buf[4] == (buf[0]+buf[1]+buf[2]+buf[3]))
- {
- *humidity = buf[0];
- *temperature = buf[2];
- }
- }
- else
- {
- return 1;
- }
- return 0;
- }
- uint8_t dht11Read(uint8_t *temperature, uint8_t *humidity)
- {
- uint8_t curTem = 0, curHum = 0;
- uint16_t temMeans = 0, humMeans = 0;
- uint8_t curI = 0;
- uint8_t ret = 0;
- ret = dht11ReadData(&curTem, &curHum);
- if(1 != ret)
- {
- //Cycle store ten times stronghold
- if(MEAN_NUM > temphumTypedef.curI)
- {
- temphumTypedef.thBufs[temphumTypedef.curI][0] = curTem;
- temphumTypedef.thBufs[temphumTypedef.curI][1] = curHum;
- temphumTypedef.curI++;
- }
- else
- {
- temphumTypedef.curI = 0;
- temphumTypedef.thBufs[temphumTypedef.curI][0] = curTem;
- temphumTypedef.thBufs[temphumTypedef.curI][1] = curHum;
- temphumTypedef.curI++;
- }
- }
- else
- {
- return (1);
- }
-
- if(MEAN_NUM <= temphumTypedef.curI)
- {
- temphumTypedef.thAmount = MEAN_NUM;
- }
- if(0 == temphumTypedef.thAmount)
- {
- //Calculate Before ten the mean
- for(curI = 0; curI < temphumTypedef.curI; curI++)
- {
- temMeans += temphumTypedef.thBufs[curI][0];
- humMeans += temphumTypedef.thBufs[curI][1];
- }
- temMeans = temMeans / temphumTypedef.curI;
- humMeans = humMeans / temphumTypedef.curI;
-
- *temperature = temMeans;
- *humidity = humMeans;
- }
- else if(MEAN_NUM == temphumTypedef.thAmount)
- {
- //Calculate After ten times the mean
- for(curI = 0; curI < temphumTypedef.thAmount; curI++)
- {
- temMeans += temphumTypedef.thBufs[curI][0];
- humMeans += temphumTypedef.thBufs[curI][1];
- }
- temMeans = temMeans / temphumTypedef.thAmount;
- humMeans = humMeans / temphumTypedef.thAmount;
-
- *temperature = (uint8_t)temMeans;
- *humidity = (uint8_t)humMeans;
- }
- return (0);
- }
- uint8_t dht11Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- /* Migrate your driver code */
- __HAL_RCC_GPIOE_CLK_ENABLE();
- /*Configure GPIO pin Output Level */
- HAL_GPIO_WritePin(GPIOE, DHT11_DIN_Pin, GPIO_PIN_RESET);
- /*Configure GPIO pins : PBPin PBPin PBPin */
- GPIO_InitStruct.Pin = DHT11_DIN_Pin;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
- dht11Rst();
-
- memset((uint8_t *)&temphumTypedef, 0, sizeof(thTypedef_t));
-
- printf("dh11Init \r\n");
-
- return dht11Check();
- }
复制代码
本系列帖子目录:
http://club.gizwits.com/thread-6544-1-1.html
|
|