查看: 1113|回复: 0

GD32F207读DHT11传感器的温湿度值

[复制链接]
  • TA的每日心情

    2023-7-25 22:49
  • 签到天数: 385 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2016-2-17 10:48:33 | 显示全部楼层 |阅读模式
    分享到:
    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-&gtDOR,n)#define PBin(n) BITBAND_REG(PTB-&gtDIR,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);               //初始化DHT11uint16_t DHT11_Read_Data(void);        //读取温湿度uint8_t DHT11_Read_Byte(void);  //读出一个字节uint8_t DHT11_Read_Bit(void);   //读出一个位uint8_t DHT11_Check(void);      //检测是否存在DHT11void DHT11_Rst(void);           //复位DHT11  #endifdht11.c
    /** **************************************************************************************** * * @file dht11.c * * @brief dht11传感器操作模块文件 * * Copyright (C) sunsjw 2015 * * $Rev: 1.0 $ * **************************************************************************************** */#include "gd32f20x_gpio.h"              // Keil:evice:StdPeriph Drivers:GPIO#include "dht11.h"#include "delay.h"/*! * @brief 复位DHT11 * * @param None * * @return None */void DHT11_Rst(void){    DHT11_SETOUT;        DelayUs(1);    DHT11_LOW;             //拉低DQ    DelayMs(20);    //拉低至少18ms    DHT11_HIGH;         //DQ=1    DelayUs(30);    //主机拉高20~40us        }/*! * @brief 等待DHT11的回应 * * @param None * * @return 0:未检测到DHT11的存在,(低电平80us,高电平80us),1:存在 */uint8_t DHT11_Check(void){    uint8_t retry=0;    DHT11_SETIN;    //DHT11_IO_IN();//SET INPUT    while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us    {        retry++;        DelayUs(1);    };    if(retry>=100)      return 0;    else       retry=0;    while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us    {        retry++;        DelayUs(1);    };    if(retry>=100)      return 0;    return 1;}/*! * @brief 从DHT11读取一个位 (起始位50us低电平,26-28us高电平代表0,70us高电平代表1) * * @param None * * @return 1/0 */uint8_t DHT11_Read_Bit(void){    uint8_t retry=0;    while(DHT11_DQ_IN&&retry<100)//等待变为低电平    {        retry++;        DelayUs(1);    }    retry=0;    while(!DHT11_DQ_IN&&retry<100)//等待变高电平    {        retry++;        DelayUs(1);    }    DelayUs(35);//等待40us    if(DHT11_DQ_IN)      return 1;    else       return 0;}/*! * @brief 从DHT11读取一个字节 * * @param None * * @return 读到的数据 */uint8_t DHT11_Read_Byte(void){    uint8_t i,dat;    DHT11_SETIN;    dat=0;    for (i=0; i<8; i++)    {        dat<<=1;        dat|=DHT11_Read_Bit();    }    return dat;}/*! * @brief 从DHT11读取一次数据 * * @param None * @param[in,out] temp:温度值(范围:0~50°),humi:湿度值(范围:20%~90%) * @return 0:读取失败,非0值:高8位是温度值,低8位是湿度值 */uint16_t DHT11_Read_Data(){    uint8_t buf[5];        uint16_t result;    uint8_t i;    DHT11_Rst();    if(DHT11_Check())    {        for(i=0; i<5; i++) //读取40位数据        {            buf=DHT11_Read_Byte();        }        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])        {                        result = buf[2];                        result <<= 8;            result |= buf[0];        }    }     else       return 0;    return result;}/*! * @brief 初始化DHT11的IO口 DQ 同时检测DHT11的存在 * * @param None * * @return None */void DHT11_Init(void){        GPIO_InitPara gpio_stru;        /*初始化DHT11使用的GPIO*/        gpio_stru.GPIO_Mode = GPIO_MODE_OUT_PP;        gpio_stru.GPIO_Pin = GPIO_PIN_0;        gpio_stru.GPIO_Speed = GPIO_SPEED_10MHZ;                GPIO_Init(GPIOC,&gpio_stru);        GPIO_SetBits(GPIOC,GPIO_PIN_0);        }主程序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);//显示%}实验效果:

    热门推荐:
    轻轻松松入门GD32F207开发板
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-4-19 08:00 , Processed in 0.111828 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.