STM32
直播中

吴湛

11年用户 968经验值
擅长:电源/新能源
私信 关注
[问答]

DHT11温湿度模块如何将测量的数据显示oled显示屏上面?

DHT11温湿度模块如何将测量的数据显示oled显示屏上面?

回帖(1)

王强

2021-11-26 11:10:53
STM32

一.前言

在实际的项目开发过程中我们会使用到很多模块,今天我们说一下DHT11温湿度模块
这里是将测量的数据显示在0.96寸oled显示屏上面,如果不会oled屏幕驱动的可以看一下之前的文章





二.DHT11驱动原理

步骤一
DHT11上电后(DHT11上电后要等待 1S 以越过不稳定状态在此期间不能发送任何指令),测试环境 温湿度数据,并记录数据,同时 DHT11的 DATA 数据线由上拉电阻拉高一直保持高电平;此时 DHT11的 DATA 引脚处于输入状态,时刻检测外部信号。
步骤二
微处理器的 I/O设置为输出同时输出低电平,且低电平保持时间不能小于 18ms(最大不得超过 30ms), 然后微处理器的 I/O设置为输入状态,由于上拉电阻,微处理器的 I/O即 DHT11的 DATA 数据线也随之变 高,等待 DHT11作出回答信号,发送信号如图所示:





步骤三
DHT11 的 DATA引脚检测到外部信号有低电平时,等待外部信号低电平结束,延迟后 DHT11 的 DATA 引脚处于输出状态,输出 83微秒的低电平作为应答信号,紧接着输出 87 微秒的高电平通知外设准备接 收数据,微处理器的 I/O 此时处于输入状态,检测到 I/O 有低电平(DHT11回应信号)后,等待 87微秒 的高电平后的数据接收,发送信号如图所示:





步骤四
由 DHT11 的 DATA引脚输出 40 位数据,微处理器根据 I/O电平的变化接收 40 位数据,位数据“0” 的格式为: 54 微秒的低电平和 23-27 微秒的高电平,位数据“1”的格式为: 54 微秒的低电平加 68-74 微秒的高电平。位数据“0”、“1”格式信号如图所





三. 代码部分

整个工程代码在此处下载

  STM32F103ZET6驱动DHT11 温湿度显示
1. 蓝秦云下载
2.github 下载

DHT11.h


#ifndef __DHT11_H
#define __DHT11_H         


#include "system.h"


#define BOOL unsigned char

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif




//定义DHT11 GPIOD 0
#define DHT11_PORT_RCC          RCC_APB2Periph_GPIOD
#define DHT11_PIN                          GPIO_Pin_0
#define DHT11_PORT                         GPIOD


static void DHT11_DataPin_Configure_Output(void);
static void DHT11_DataPin_Configure_Input(void);
BOOL DHT11_get_databit(void);
void DHT11_set_databit(BOOL level);
void mdelay(u16 ms);
void udelay(u16 us);
static uint8_t DHT11_read_byte(void);
static uint8_t DHT11_start_sampling(void);
void DHT11_get_data(u32 *buf);


                                             
#endif


DHT11.c


#include "dht11.h"
#include "SysTick.h"


/*数据定义:
---以下变量均为全局变量--------
    //----温度高8位== U8T_data_H------
    //----温度低8位== U8T_data_L------
    //----湿度高8位== U8RH_data_H-----
    //----湿度低8位== U8RH_data_L-----
  //-----校验 8位 == U8checkdata-----
*/


u8 U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
u8 U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;




static void DHT11_DataPin_Configure_Output(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;


  RCC_APB2PeriphClockCmd(DHT11_PORT_RCC, ENABLE); //使能PD端口时钟
  GPIO_InitStructure.GPIO_Pin = DHT11_PIN; //PD.0 端口配置
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
}

static void DHT11_DataPin_Configure_Input(void)
{
        GPIO_InitTypeDef DataPin;
        DataPin.GPIO_Pin = DHT11_PIN;
        DataPin.GPIO_Mode = GPIO_Mode_IN_FLOATING; //悬空 输入   
        DataPin.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(DHT11_PORT, &DataPin);
}


BOOL DHT11_get_databit(void)
{
        uint8_t val;
        val = GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN);
        if(val == Bit_RESET)
        {
                return FALSE;
        }
        else
        {
                return TRUE;
        }
}

void DHT11_set_databit(BOOL level)
{
        if(level == TRUE)
        {
                GPIO_SetBits(DHT11_PORT, DHT11_PIN);
        }
        else
        {
                GPIO_ResetBits(DHT11_PORT, DHT11_PIN);
        }
}

void mdelay(u16 ms)
{
        if(ms != 0)
        {
                delay_ms(ms);
        }
}

void udelay(u16 us)
{
        if(us != 0)
        {
                delay_us(us);
        }
}
static uint8_t DHT11_read_byte(void)
{
        uint8_t i;
        uint8_t data = 0;
        for(i = 0; i < 8; i++)
        {
                data <<= 1;
                while((!DHT11_get_databit()));
                udelay(10);
                udelay(10);
                udelay(10);

                if(DHT11_get_databit())
                {
                        data |= 0x1;
                        while(DHT11_get_databit());
                }
                else
                {
                }
  }
        return data;
}




static uint8_t DHT11_start_sampling(void)
{
        DHT11_DataPin_Configure_Output();
        //主机拉低18ms   
        DHT11_set_databit(FALSE);
        mdelay(18);
        DHT11_set_databit(TRUE);
        //总线由上拉电阻拉高 主机延时20us
        udelay(10);
        udelay(10);


        //主机设为输入 判断从机响应信号
        DHT11_set_databit(TRUE);


        DHT11_DataPin_Configure_Input();


        //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行      
        if(!DHT11_get_databit()) //T !      
        {
                //判断从机是否发出 80us 的低电平响应信号是否结束     
                while((!DHT11_get_databit()));
                // printf("DHT11 answers.rn");
                //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
                while((DHT11_get_databit()))
                {}
               
                        return 1;
        }

        return 0;
}

void DHT11_get_data(u32 *buf)
{
        u8 temp;
        if(DHT11_start_sampling())
        {
                //printf("DHT11 is ready to transmit datarn");
                //数据接收状态         
                U8RH_data_H_temp = DHT11_read_byte();
                U8RH_data_L_temp = DHT11_read_byte();
                U8T_data_H_temp  = DHT11_read_byte();
                U8T_data_L_temp  = DHT11_read_byte();
                U8checkdata_temp = DHT11_read_byte();
         
                /* Data transmission finishes, pull the bus high */
                DHT11_DataPin_Configure_Output();
                DHT11_set_databit(TRUE);
                //数据校验
         
                temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
                if(temp==U8checkdata_temp)
                {
                        U8RH_data_H=U8RH_data_H_temp; //湿度
                        U8RH_data_L=U8RH_data_L_temp;
                        U8T_data_H=U8T_data_H_temp;  //温湿
                        U8T_data_L=U8T_data_L_temp;
                        U8checkdata=U8checkdata_temp;
               
                       
                        buf[0] = U8T_data_H; //温度的高低
                        buf[1] = U8T_data_L;
                       
                        buf[2] = U8RH_data_H; //湿度高低
                        buf[3] = U8RH_data_L;
         
                }
        }
}


main


//--------------------------------------------------------------------------------------
//说明: STM32F103Zet6 驱动DHT11 在 0.96 oled屏显示温湿度
//引脚说明
//        DHT11: PD0
//        OLED:        D0   接PC0(SCL)        
//                                D1   接PC1(SDA)
//                                RES  接PC2  
//                                DC   接PC3         CS   接PA0       
//--------------------------------------------------------------------------------------


#include "system.h"
#include "SysTick.h"  //延时  
#include "oled.h"
#include "dht11.h"


void dht11_show(u32 *buf); //oled显示




int main()
{
        //显示温度和湿度的数组 元素0 为温度高 元素1 为温度低
        //                                                                                 元素2 为湿度高 元素3 为湿度的低
        u32 DTH11_data[4]={0};
        //时钟源获取 配置
        SysTick_Init(72); //精确延时
       
        OLED_Init();
        OLED_ColorTurn(0);//0正常显示,1 反色显示
  OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示


        while(1)
        {       
                DHT11_get_data(DTH11_data); //获取到温湿度
                dht11_show(DTH11_data);
                delay_ms(5000);
                OLED_ShowString(70,20,"     ",16,1);
                OLED_ShowString(70,40,"     ",16,1);
                OLED_Refresh();
        }
}






//温湿度显示
void dht11_show(u32 *buf)
{
        u32 pos = 0;
       
        OLED_ShowChinese(20,20,0,16,1);//温
        OLED_ShowChinese(40,20,1,16,1);//度
        OLED_ShowString(60,20,":",16,1);
       
        if(buf[0] < 10)
        {
                OLED_ShowNum(70,20,buf[0],1,16,1);
                pos = 8;
        }
        else if(buf[0] < 100)
        {
                OLED_ShowNum(70,20,buf[0],2,16,1);
                pos = 16;
        }
        else
        {
                OLED_ShowNum(70,20,buf[0],3,16,1);
                pos = 24;
        }
        OLED_ShowString(70+pos,20,".",16,1);
        pos += 8;
        if(buf[1] < 10)
        {
                OLED_ShowNum(70+pos,20,buf[1],1,16,1);
        }
        else if(buf[1] < 100)
        {
                OLED_ShowNum(70+pos,20,buf[1],2,16,1);
        }
        else
        {
                OLED_ShowNum(70+pos,20,buf[1],3,16,1);
        }
       
               
        OLED_ShowChinese(20,40,2,16,1);//湿
        OLED_ShowChinese(40,40,3,16,1);//度
        OLED_ShowString(60,40,":",16,1);
       
        if(buf[2] < 10)
        {
                OLED_ShowNum(70,40,buf[2],1,16,1);
                pos = 8;
        }
        else if(buf[2] < 100)
        {
                OLED_ShowNum(70,40,buf[2],2,16,1);
                pos = 16;
        }
        else
        {
                OLED_ShowNum(70,40,buf[2],3,16,1);
                pos = 24;
        }
        OLED_ShowString(70+pos,40,".",16,1);
        pos += 8;
        if(buf[3] < 10)
        {
                OLED_ShowNum(70+pos,40,buf[3],1,16,1);
        }
        else if(buf[3] < 100)
        {
                OLED_ShowNum(70+pos,40,buf[3],2,16,1);
        }
        else
        {
                OLED_ShowNum(70+pos,40,buf[3],3,16,1);
        }
        OLED_Refresh();


}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分