0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

CW32模块使用 DHT11温湿度传感器

CW32生态社区 来源:CW32生态社区 作者:CW32生态社区 2024-09-09 18:21 次阅读

DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。其成本低、长期稳定、可以测量相对湿度和温度测量,并可以只使用一根数据线进行温湿度采集。

1.模块来源

模块实物展示:

wKgaombezC-ATQpGAAA0kOxx5xk49.webp


资料下载链接:https://pan.baidu.com/s/1HQEL699-Yl5Jh3Hp87_FlQ
资料提取码:2sgq

2. 规格参数

模块的厂家资料下载见百度网盘链接

工作电压:3-5.5V

工作电流:1MA

测量分辨率:8 bit

湿度量程: 20 - 90 %RH

湿度精度:±5 %RH

温度量程: 0 - 50 ℃

温度精度:±2 ℃

通信协议:单总线

管脚数量:3 Pin(2.54mm间距排针

3.移植过程

我们的目标是在立创·地文星·CW32F030C8T6开发板上实现读取温湿度的功能。首先要获取资料,查看数据手册应如何实现读取数据,再移植至我们的工程。

3.1查看资料

DHT11使用的是单总线通信,即发送数据与接收数据都在一根数据线上,通过规定的时序进行控制。

wKgZombezC-AaNzgAAAkKCtjzHs08.webp

从左向右看,时序一开始,主机信号就保持着高电平,所以引脚初始化完毕时,及时给引脚输出高电平。因为 模块的数据线要求空闲时,要保持高电平状态。(其实模块上已经接了上拉电阻,使数据线一直保持高电平)

根据时序图可以知道,主机(开发板)发送一次开始信号,待主机开始信号结束后,DHT11 发送响应信号,送出 温湿度数据,并触发一次数据采集给下一次数据读取作准备。因此完成一次数据读取需要进行起始信号、响应信号、数据接收、结束信号。

读取数据步骤:

起始信号:主机(开发板)接入数据线的I/O输出低电平,且低电平保持时间不能小于 18ms

wKgaombezC-AHdIlAAAMLItOYqE92.webp

DATA_GPIO_OUT(0);  //数据线输出低电平
delay_1ms(19);     //起始信号保持时间19ms
DATA_GPIO_OUT(1);  //主机释放总线
delay_uus( 20 );   //拉高等待

2.响应信号:等待模块的响应信号到来。将数据线改为输入模式,如果接入到低电平,说明接收到模块的响应。

wKgZombezDCAXjF3AAAKakNLMTM75.webp

    DHT11_GPIO_Mode_IN();//数据线转为输入模式
    //如果前面没有错误,则模块会发出低电平的应答信号,
    //所以直接等待DHT11拉高,83us
    timeout = 5000;
    while( (! DATA_GPIO_IN ) && ( timeout >0 ) )
    {
        timeout--;         //等待高电平的到来
    }
    //模块当前处于拉高准备输出数据,
    //所以直接等待DHT11拉低,87us
    timeout = 5000;//设置超时时间
    while( DATA_GPIO_IN && ( timeout >0 ) )
    {
        timeout-- ;         //等待低电平的到来
    }

3.数据传输:主机接收模块发送的40位数据,其中,位数据 ‘0’ 表示54us的低电平,27us的高电平;位数据 ‘1’ 表示54us的低电平,74us的高电平。两个格式的分辨主要是高电平的输出时长不同。

wKgaombezDCAPKz1AAAOIPxofP859.webp

#define CHECK_TIME 28 //超过0值的高电平时间
    for(i=0;i< 40;i++)//循环接收40位数据
    {
        timeout = 5000;
        //等待低电平过去
        while( ( !DATA_GPIO_IN ) && (timeout > 0) ) timeout--; //54us
        delay_uus(CHECK_TIME);//等待超过位数据0值的高电平时间
        if ( DATA_GPIO_IN )//如果还是高电平,说明是1值
        {
            val=(val< <1)+1;
        }
        else //如果是低电平,说明是0值
        {
            val< <=1;
        }
        timeout = 5000;
        //如果当前还是高电平,等待高电平过去,准备接收下一位数据
        while( DATA_GPIO_IN && (timeout > 0) ) timeout-- ;
    }

4.结束信号:模块的数据线输出 40 位数据后,是以低电平结束,它会继续输出低电平 54 微秒后转为输入状态,主机需要转为输出状态,输出高电平释放总线。

wKgaombezDGAWixvAAAD0rhXYR424.webp

DHT11_GPIO_Mode_OUT();//转为输出模式
DATA_GPIO_OUT(1);//主机释放总线

数据接收完成,但是这40位数据要如何转化为温湿度数据?并如何保证传输的数据没有错误?

DHT11模块一次完整的数据传输为40bit,高位先出。数据格式:

8bit湿度整数数据 + 8bit湿度小数数据 + 8bi温度整数数据 + 8bit温度小数数据 + 8bit校验和

注意

湿度小数部分数据一直为0。

数据传送正确时,校验和数据等于“8bit湿度整数数据+8bit湿度小数数据 +8bi温度整数数据+8bit温度小数数据”所得结果的末8位。举几个例子。

示例一:接收的40位数据分别为:

0011 0101 0000 0000 0001 1000 0000 0100 0101 0001
湿度高8位 湿度低8位 温度高8位 温度低8位 校验位

校验和为 0011 0101 + 0000 0000 + 0001 1000 + 0000 0100 = 0101 0001,与接收的数据一致

湿度为 0011 0101 + 0000 0000 = 35 + 0 = 35%RH

温度为 0001 1000 0000 0100 = 24 + 4 = 24.4℃

示例二:接收的40位数据分别为:

0011 0101 0000 0000 0001 1000 0000 0100 0100 1001
湿度高8位 湿度低8位 温度高8位 温度低8位 校验位

校验和为 0011 0101 + 0000 0000 + 0001 1000 + 0000 0100 = 0101 0001,与接收的数据不一致 计算的数据为0101 0001,接收的数据为0100 1001,两者不一致说明数据不准确,丢弃这次数据,重新接收。

以下为数据处理的实现代码:

 //val为接收到的40位数据。
    //           湿高8     + 湿低8      + 温高8     + 温低8
    verify_num = (val>>32) + (val>>24) + (val>>16) + (val>>8);
    //计算的校验和 与 接收的校验和 的差为0说明一致,不为0说明不一致
    //(val&0xff)是因为val的大小为64位,我们只需要val的最后8位校验和
    verify_num = verify_num - (val&0xff);
    //进行校验
    if( verify_num )//如果不为0,说明校验失败
    {
//      校验错误
        return 0;
    }
    else //校验成功
    {
        //数据处理
        humidity = (val>>32)&0xff;         //湿度前8位(小数点前数据)
        small_point = (val>>24)&0x00ff;    //湿度后8位(小数点后数据)
        small_point = small_point * 0.1;   //换算为小数点
        humidity = humidity + small_point; //小数前+小数后
        printf("湿度:%.2frn",humidity);

        temperature = (val>>16)&0x0000ff;  //温度前8位(小数点前数据)
        small_point = (val>>8)&0x000000ff; //温度后8位(小数点后数据)
        small_point = small_point * 0.1;   //换算为小数点
        temperature = temperature + small_point;//小数前+小数后
        printf("温度:%.2frn",temperature);

        return val>>8; //返回未处理的数据
    }

3.2引脚选择

该模块有3个引脚,具体引脚连接见 表 各引脚连接。

wKgZombezDGAJce8AACplAyhAOg73.webp

3.3移植至工程

工程模板下载请查看入门手册百度链接

然后我们打开空白工程,新建两个文件dht11.c和dht11.h

wKgaombezDGAK9jqAAB4ujdWyJY289.jpg

在文件dht11.c中,编写如下代码。

/*
 * Change Logs:
 * Date           Author       Notes
 * 2024-06-19     LCKFB-LP    first version
 */

#include "dht11.h"
#include "stdio.h"

float temperature = 0;
float humidity = 0;

/******************************************************************
 * 函 数 名 称:DHT11_GPIO_Init
 * 函 数 说 明:DHT11温湿度传感器初始化
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void DHT11_GPIO_Init(void)
{
    GPIO_InitTypeDef        GPIO_InitStruct; // GPIO初始化结构体

    RCC_DHT11_GPIO_ENABLE();        // 使能GPIO时钟

    GPIO_InitStruct.Pins = GPIO_DHT11;                                // GPIO引脚
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;                // 推挽输出
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;                // 输出速度高
    GPIO_Init(PORT_DHT11, &GPIO_InitStruct);                // 初始化

    DATA_GPIO_OUT(1);
}

/******************************************************************
 * 函 数 名 称:DHT11_GPIO_Mode_OUT
 * 函 数 说 明:配置DHT11的数据引脚为输出模式
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void DHT11_GPIO_Mode_OUT(void)
{
    GPIO_InitTypeDef        GPIO_InitStruct; // GPIO初始化结构体

    GPIO_InitStruct.Pins = GPIO_DHT11;                                // GPIO引脚
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;                // 推挽输出
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;                // 输出速度高

    GPIO_Init(PORT_DHT11, &GPIO_InitStruct);                // 初始化
}

/******************************************************************
 * 函 数 名 称:DHT11_GPIO_Mode_IN
 * 函 数 说 明:配置DHT11的数据引脚为输入模式
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void DHT11_GPIO_Mode_IN(void)
{
    GPIO_InitTypeDef        GPIO_InitStruct; // GPIO初始化结构体

    GPIO_InitStruct.Pins = GPIO_DHT11;                                // GPIO引脚
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLUP;        // 上拉输入
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;                // 输出速度高

    GPIO_Init(PORT_DHT11, &GPIO_InitStruct);                // 初始化
}

/******************************************************************
 * 函 数 名 称:DHT11_Read_Data
 * 函 数 说 明:根据时序读取温湿度数据
 * 函 数 形 参:无
 * 函 数 返 回:0=数据校验失败  其他=温湿度未处理的数据
 * 作       者:LC
 * 备       注:无
******************************************************************/
unsigned int DHT11_Read_Data(void)
{
    int i;
    long long val=0;
    int timeout=0;
    float small_point=0;
    unsigned char verify_num = 0;//验证值

    DATA_GPIO_OUT(0);//数据线输出低电平
    delay_ms(19);  //起始信号保持时间19ms
    DATA_GPIO_OUT(1);//主机释放总线
    delay_us( 20 );//拉高等待


    DHT11_GPIO_Mode_IN();//数据线转为输入模式
    //如果前面没有错误,则模块会发出低电平的应答信号,所以直接等待DHT11拉高,80us
    timeout = 5000;
    while( (! DATA_GPIO_IN ) && ( timeout >0 ) )timeout--;         //等待高电平的到来


    //模块当前处于拉高准备输出数据,所以直接等待DHT11拉低,80us
    timeout = 5000;//设置超时时间
    //DATA_GPIO_IN=0时,while条件不成立退出while 说明接收到响应信号
    //当timeout<=0时,while条件不成立退出while  说明超时
    while( DATA_GPIO_IN && ( timeout >0 ) )timeout-- ;         //等待低电平的到来


    #define CHECK_TIME 28 //实测发现超过0值的高电平时间
    for(i=0;i< 40;i++)//循环接收40位数据
    {
        timeout = 5000;
        while( ( !DATA_GPIO_IN ) && (timeout > 0) ) timeout--;         //等待低电平过去

        delay_us(CHECK_TIME);//超过0值的高电平时间
        if ( DATA_GPIO_IN )//如果还是高电平,说明是1值
        {
            val=(val< <1)+1;
        }
        else //如果是低电平,说明是0值
        {
            val< <=1;
        }

        timeout = 5000;
        while( DATA_GPIO_IN && (timeout > 0) ) timeout-- ;         //如果还是高电平
    }

    DHT11_GPIO_Mode_OUT();//转为输出模式
    DATA_GPIO_OUT(1);//主机释放总线


    //           湿高8     + 湿低8      + 温高8     + 温低8
    verify_num = (val>>32) + (val>>24) + (val>>16) + (val>>8);
    //计算的校验和 与 接收的校验和 的差为0说明一致,不为0说明不一致
    verify_num = verify_num - (val&0xff);
    //进行校验
    if( verify_num  )
    {
//      校验错误
        return 0;
    }
    else //校验成功
    {
        //数据处理
        humidity = (val>>32)&0xff;//湿度前8位(小数点前数据)
        small_point = (val>>24)&0x00ff;//湿度后8位(小数点后数据)
        small_point = small_point * 0.1;//换算为小数点
        humidity = humidity + small_point;//小数前+小数后
//        printf("湿度:%.2frn",humidity);

        temperature = (val>>16)&0x0000ff;//温度前8位(小数点前数据)
        small_point = (val>>8)&0x000000ff;//温度后8位(小数点后数据)
        small_point = small_point * 0.1;//换算为小数点
        temperature = temperature + small_point;//小数前+小数后
//        printf("温度:%.2frn",temperature);

        return val>>8; //返回未处理的数据
    }
}

/******************************************************************
 * 函 数 名 称:Get_temperature
 * 函 数 说 明:获取温度数据
 * 函 数 形 参:无
 * 函 数 返 回:温度值
 * 作       者:LC
 * 备       注:使用前必须先调用 DHT11_Read_Data 读取有数据
******************************************************************/
float Get_temperature(void)
{
    return temperature;
}

/******************************************************************
 * 函 数 名 称:Get_humidity
 * 函 数 说 明:获取湿度数据
 * 函 数 形 参:无
 * 函 数 返 回:湿度值
 * 作       者:LC
 * 备       注:使用前必须先调用 DHT11_Read_Data 读取有数据
******************************************************************/
float Get_humidity(void)
{
    return humidity;
}

在文件dht11.h中,编写如下代码。

/*
 * Change Logs:
 * Date           Author       Notes
 * 2024-06-19     LCKFB-LP    first version
 */
#ifndef _BSP_DHT11_H_
#define _BSP_DHT11_H_

#include "board.h"

 /**************引脚修改此处****************/
#define RCC_DHT11_GPIO_ENABLE()       __RCC_GPIOB_CLK_ENABLE()
#define PORT_DHT11                    CW_GPIOB
#define GPIO_DHT11                    GPIO_PIN_0


//设置DHT11输出高或低电平
#define DATA_GPIO_OUT(x)    GPIO_WritePin(PORT_DHT11, GPIO_DHT11, x ? GPIO_Pin_SET : GPIO_Pin_RESET)
//获取DHT11数据引脚高低电平状态
#define DATA_GPIO_IN        GPIO_ReadPin(PORT_DHT11, GPIO_DHT11)

extern float temperature;
extern float humidity;


void DHT11_GPIO_Init(void);//引脚初始化
unsigned int DHT11_Read_Data(void);//读取模块数据
float Get_temperature(void);//返回读取模块后的温度数据
float Get_humidity(void);//返回读取模块后的湿度数据

#endif

4.移植验证

在自己工程中的main主函数中,编写如下。

/*
 * Change Logs:
 * Date           Author       Notes
 * 2024-06-19     LCKFB-LP    first version
 */
#include "board.h"
#include "stdio.h"
#include "bsp_uart.h"
#include "dht11.h"

int32_t main(void)
{
    board_init();        // 开发板初始化

    uart1_init(115200);        // 串口1波特率115200

    DHT11_GPIO_Init();          //DHT11引脚初始化
    delay_ms(1000);
    printf("DHT11 demo startrn");
    while(1)
    {
        //读取模块数据
        DHT11_Read_Data();
        //显示读取后的温度数据
        printf("temperature = %.2frn", Get_temperature() );
        //显示读取后的湿度数据
        printf("humidity = %.2frn", Get_humidity() );
        delay_ms(1000);
    }
}

上电效果:

wKgZombezDKAWLOdAAB9Ttw6dfQ30.webp

模块移植成功案例代码:

链接:https://pan.baidu.com/s/10WX784WnNQeMiwbLH8Yt7g?pwd=LCKF

提取码:LCKF

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数字信号
    +关注

    关注

    2

    文章

    916

    浏览量

    47423
  • 温湿度传感器

    关注

    5

    文章

    560

    浏览量

    35548
  • DHT11
    +关注

    关注

    19

    文章

    274

    浏览量

    57404
  • CW32
    +关注

    关注

    1

    文章

    161

    浏览量

    494
收藏 人收藏

    评论

    相关推荐

    基于arduino的dht11温湿度传感器的使用

    本文介绍了DHT11温湿度传感器电气特性、DHT11封装形式及接口说明与典型应用电路,其次介绍了DHT11
    发表于 01-22 15:50 4.4w次阅读
    基于arduino的<b class='flag-5'>dht11</b><b class='flag-5'>温湿度</b><b class='flag-5'>传感器</b>的使用

    Arduino开发板使用DHT11温湿度传感器的方法 精选资料分享

    在本篇文章中,我们将DHT11温湿度传感器与Arduino开发板和LCD显示屏连接,设计一种能够测量室温和环境湿度的设备。简单地说,我们将使用Arduino和
    发表于 07-13 06:58

    DHT11温湿度传感器介绍

    DHT11温湿度传感器介绍,1.实物原理图2.模块说明2.1 DHT11产品概述DHT11数字
    发表于 07-21 09:04

    DHT11温湿度传感器

    DHT11温湿度传感器1. DHT11简介2. 硬件设计3. 软件设计3.1 STM32CubeMX设置3.2 MDK-ARM编程4. 下载验证
    发表于 08-11 06:04

    DHT11数字温湿度传感器的相关资料推荐

    main.clcd1602.clcd1602.hdelay.cdelay.h项目展示DHT11温湿度相关介绍DHT11产品概述DHT11数字温湿度
    发表于 11-19 07:33

    dht11温湿度传感器有什么特点?怎么使用?

    dht11温湿度传感器特点及使用介绍前言一、dht11温湿度传感器外观二、原理图三、相关参数讲解
    发表于 01-10 06:27

    DHT11温湿度传感器简介

    DHT11温湿度传感器1、DHT11简介DHT11数字温湿度
    发表于 02-16 06:55

    DHT11数字温湿度传感器的相关资料推荐

    STM32采集DHT11温湿度关于DHT11相关参数代码篇接线和实验结果总结关于DHT11DHT11是一款数字温湿度
    发表于 02-21 07:34

    DHT11数字温湿度传感器产品介绍

    DHT11数字温湿度传感器产品介绍 DHT11数字温湿度传感器是一款含有已校准数字信号输出的
    发表于 02-26 17:19 256次下载

    数字温湿度传感器DHT11的主要特点及引脚说明

      DHT11的主要特点及引脚说明   广州奥松电子有限公司新近推出的DHT11数字温湿度传感器,是一款含有已校准数字信号输出的温湿度复合
    发表于 09-07 11:44 4.2w次阅读
    数字<b class='flag-5'>温湿度</b><b class='flag-5'>传感器</b><b class='flag-5'>DHT11</b>的主要特点及引脚说明

    DHT11数字式温湿度传感器的应用性研究

    基于DHT11温湿度传感器具有测量精度高、响应速度快、抗干扰能力强等优点。通过介绍DHT11数字式温湿度
    发表于 07-25 17:03 216次下载
    <b class='flag-5'>DHT11</b>数字式<b class='flag-5'>温湿度</b><b class='flag-5'>传感器</b>的应用性研究

    温湿度DHT11资料

    温湿度DHT11资料汇总 DHT11是一款有已校准数字信号输出的温湿度传感器。 其精度湿度+-5
    发表于 11-29 17:28 27次下载

    数字温湿度传感器 DHT11

    DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块
    发表于 12-02 11:06 4次下载

    DHT11温湿度传感器模块产品手册免费下载

     DHT11温湿度传感器模块是以DHT11温湿度传感器
    发表于 07-22 08:00 6次下载
    <b class='flag-5'>DHT11</b><b class='flag-5'>温湿度</b><b class='flag-5'>传感器</b><b class='flag-5'>模块</b>产品手册免费下载

    使用ESP8266驱动DHT11温湿度传感器

    DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度综合传感器,在Arduino提高篇中已对其进行了介绍,本篇使用ESP8266来
    的头像 发表于 05-19 14:20 5713次阅读
    使用ESP8266驱动<b class='flag-5'>DHT11</b><b class='flag-5'>温湿度</b><b class='flag-5'>传感器</b>