本帖最后由 党国特派员 于 2016-2-5 00:25 编辑
1、DHT11介绍
DHT11是一款比较便宜的温湿度传感器模块。读取数据只需要占用一个IO口。能够同时测量温度和相对湿度。
2、接口说明
建议连接线长度短于20米时用5K上拉电阻,大于20米时根据实际情况使用合适的上拉电阻
3、电源引脚
DHT11的供电电压为 3-5.5V。传感器上电后,要等待 1s 以越过不稳定状态在此期间无需发送任何指令。电源引脚(VDD,GND)之间可增加一个100nF 的电容,用以去耦滤波。
4、串行接口(单纯双向)
DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于以后扩展,现读出为零.操作流程如下: 一次完整的数据传输为40bit,高位先出。 数据格式:8bit湿度整数数据+8bit湿度小数数据 +8bi温度整数数据+8bit温度小数数据 +8bit校验和 数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。 用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集,如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。 5、驱动代码
dht11.h- /**
- ****************************************************************************************
- *
- * @file dht11.h
- *
- * @brief dht11传感器操作模块头文件
- *
- * Copyright (C) sunsjw 2015
- *
- * $Rev: 1.0 $
- *
- ****************************************************************************************
- */
- #ifndef __DHT11_H
- #define __DHT11_H
- #include <stdint.h>
- //IO操作函数
- #define PBout(n) BITBAND_REG(PTB->PDOR,n)
- #define PBin(n) BITBAND_REG(PTB->PDIR,n)
- #define DHT11_DQ_OUT PBout(0) //数据端口 PB0
- #define DHT11_DQ_IN GPIO_ReadInputBit(GPIOC,GPIO_PIN_0) //数据端口 PB0
- #define DHT11_SETOUT GPIOC->CTLR1 = (GPIOC->CTLR1 & 0xFFFFFFF0 | 0x01)
- #define DHT11_SETIN GPIOC->CTLR1 = (GPIOC->CTLR1 & 0xFFFFFFF0 | 0x08)
- #define DHT11_HIGH GPIO_SetBits(GPIOC,GPIO_PIN_0)
- #define DHT11_LOW GPIO_ResetBits(GPIOC,GPIO_PIN_0)
- void DHT11_Init(void); //初始化DHT11
- uint16_t DHT11_Read_Data(void); //读取温湿度
- uint8_t DHT11_Read_Byte(void); //读出一个字节
- uint8_t DHT11_Read_Bit(void); //读出一个位
- uint8_t DHT11_Check(void); //检测是否存在DHT11
- void DHT11_Rst(void); //复位DHT11
- #endif
复制代码 dht11.c主程序main.c- #include <stdio.h>
- #include "gd32f20x.h" // Device header
- #include "cmsis_os.h" // ARM::CMSIS:RTOS:Keil RTX
- #include "delay.h"
- #include "dht11.h"
- #include "oled.h"
- uint8_t showBuffer[32];
- void RCC_config(void);
- void GPIO_config(void);
- void SPI_config(void);
- void ShowDHT11(void);
- void thread_led(const void *arg)
- {
- uint16_t pin = (uint16_t)arg;
- for(;;)
- {
- if(GPIO_ReadOutputBit(GPIOD,pin))
- GPIO_ResetBits(GPIOD,pin);
- else
- GPIO_SetBits(GPIOD,pin);
-
- osDelay(pin);
- }
- }
- void task_dht11(const void* arg)
- {
- for(;;)
- {
- ShowDHT11();
- osDelay(1000);
- }
- }
- osThreadDef(thread_led,osPriorityNormal,3,0);
- osThreadDef(task_dht11,osPriorityHigh,1,0);
- int main()
- {
- osKernelInitialize();
-
- RCC_config();
- GPIO_config();
- SPI_config();
-
- DelayInit();
- DHT11_Init();
- OLED_Init();
- OLED_Clear();
- GP2Y_init();
-
- osThreadCreate(osThread(thread_led),(void*)GPIO_PIN_11);
-
- osThreadCreate(osThread(task_dht11),NULL);
-
- osKernelStart();
- while(1)
- {
- osDelay(1000);
- }
- }
- void RCC_config(void)
- {
- RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_GPIOA|RCC_APB2PERIPH_GPIOD|RCC_APB2PERIPH_GPIOC,ENABLE);
- RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_SPI1,ENABLE);
- RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_ADC1,ENABLE);
-
- RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_USART2,ENABLE);
- RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_TIMER6,ENABLE);
- RCC_ADCCLKConfig(RCC_ADCCLK_APB2_DIV6);
- }
- void GPIO_config(void)
- {
- /*初始化LED灯的GPIO*/
- GPIO_InitPara gpio_stru;
- gpio_stru.GPIO_Mode = GPIO_MODE_OUT_PP;
- gpio_stru.GPIO_Speed = GPIO_SPEED_10MHZ;
- gpio_stru.GPIO_Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13;
-
- GPIO_Init(GPIOD,&gpio_stru);
- }
- void SPI_config(void)
- {
- SPI_InitPara spi_stru;
-
- spi_stru.SPI_FirstBit = SPI_FIRSTBIT_MSB;
- spi_stru.SPI_FrameFormat = SPI_FRAMEFORMAT_8BIT;
- spi_stru.SPI_Mode = SPI_MODE_MASTER;
- spi_stru.SPI_PSC = SPI_PSC_64;
- spi_stru.SPI_SCKPH = SPI_SCKPH_1EDGE;
- spi_stru.SPI_SCKPL = SPI_SCKPL_LOW;
- spi_stru.SPI_SWNSSEN = SPI_SWNSS_SOFT;
- spi_stru.SPI_TransType = SPI_TRANSTYPE_BDMTX;
- spi_stru.SPI_CRCPOL = 7;
-
- SPI_Init(SPI1,&spi_stru);
- SPI_CRC_Enable(SPI1,DISABLE);
- SPI_Enable(SPI1,ENABLE);
- }
- void ShowDHT11(void)
- {
- uint16_t data = DHT11_Read_Data();
- sprintf((char*)showBuffer,":%3d",data>>8);
- OLED_ShowCHinese(0,2,6);//显示汉字温
- OLED_ShowCHinese(16,2,8);//显示汉字度
- OLED_ShowString(32,2,showBuffer);
- OLED_ShowCHinese(64,2,9);//显示℃
- sprintf((char*)showBuffer,":%3d",data & 0xFF);
- OLED_ShowCHinese(0,4,7);//显示汉字温
- OLED_ShowCHinese(16,4,8);//显示汉字度
- OLED_ShowString(32,4,showBuffer);
- OLED_ShowCHinese(64,4,11);//显示%
- }
复制代码 实验效果:
|