STM32
直播中

小组店小二

9年用户 899经验值
擅长:可编程逻辑 电源/新能源 MEMS/传感技术 测量仪表 嵌入式技术 制造/封装 模拟技术 连接器 EMC/EMI设计 光电显示 存储技术 EDA/IC设计 处理器/DSP 接口/总线/驱动 控制/MCU RF/无线
私信 关注
[问答]

如何使用STM32 HAL库进行开发并驱动DHT11温湿度传感器呢

DHT11是什么?
如何使STM32 HAL库进行开发并驱动DHT11温湿度传感器呢?

回帖(1)

李祥芝

2021-12-1 10:13:28
1、开发平台




  • 使用野火STM32H750开发板
  • 无RTOS
  • 使用HAL库进行开发

硬件连接:
SDA---->PA12
2、DHT11介绍






起始信号:





从机响应信号:





传输:





贴上代码:
dht11.h

#ifndef __dht11_h
#define __dht11_h


#include "main.h"


/*底层接口*/
#define __DHT11_GPIO_INIT()     dht11_gpio_init()
#define __DHT11_MODE(MODE)      DHT11_MODE(MODE)
#define __DHT11_OUT_H()         HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_SET)   
#define __DHT11_OUT_L()         HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_RESET)
#define __DHT11_READ()          HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN)      
#define __DHT11_DELAY_MS(nms)   delay_ms(nms)
#define __DHT11_DELAY_US(nms)   delay_us(nms)


/*硬件接口*/
#define __DHT11_PIN_CLK()       __HAL_RCC_GPIOA_CLK_ENABLE()
#define DHT11_PIN               GPIO_PIN_12
#define DHT11_PORT              GPIOA


/*延时函数*/
#define  SYSCLK                             400000000/1000000                   //指明CPU工作频率为(SystemCoreClock/1000000)MHz
#define  A                                  6                                   //一次循环所花的周期数
#define  B                                  3                                   //调用、初始化、返回总共所用的周期数
#define  delay_us(nus)                      wait(((nus)*(SYSCLK)-(B))/(A))
#define  delay_ms(nms)                      delay_us((nms)*1000)
#define  delay_s(ns)                        delay_ms((ns)*1000)


/*结构体成员定义*/
typedef struct
{
        uint8_t  humi_int;                //湿度的整数部分
        uint8_t  humi_deci;                 //湿度的小数部分
        uint8_t  temp_int;                 //温度的整数部分
        uint8_t  temp_deci;                 //温度的小数部分
        uint8_t  check_sum;                 //校验和
                                 
}DHT11_Data_TypeDef;




/*函数声明*/
void  wait(unsigned long n);
void dht11_init(void);
uint8_t ReadByte(void);
uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data);
void DHT11_PRINTF(void);
#endif


dht11.c


#include "dht11.h"


GPIO_InitTypeDef DHT11_GPIO_Init;


DHT11_Data_TypeDef DHT11_Data;


/****************************************************************
*@function: dht11_gpio_init
*@input   : none
*@output  : none
*@describe: DHT11的GPIO口初始化
*@author  : sola
****************************************************************/
void dht11_gpio_init(void)
{
    __DHT11_PIN_CLK();               //开启时钟
   
    DHT11_GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
    DHT11_GPIO_Init.Pin = DHT11_PIN;
    DHT11_GPIO_Init.Pull = GPIO_NOPULL;
    DHT11_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(DHT11_PORT, &DHT11_GPIO_Init);
}


/****************************************************************
*@function: DHT11_MODE
*@input   : mode    (0/1)
*@output  : none
*@describe: DHT11 GPIO输入输出模式选择
*@author  : sola
****************************************************************/
void DHT11_MODE(uint8_t mode)
{
    if(mode == 0)
    {
        DHT11_GPIO_Init.Mode = GPIO_MODE_INPUT;
        DHT11_GPIO_Init.Pin = DHT11_PIN;
        DHT11_GPIO_Init.Pull = GPIO_NOPULL;
        DHT11_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        HAL_GPIO_Init(DHT11_PORT, &DHT11_GPIO_Init);
    }
    else if(mode == 1)
    {
        DHT11_GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
        DHT11_GPIO_Init.Pin = DHT11_PIN;
        DHT11_GPIO_Init.Pull = GPIO_NOPULL;
        DHT11_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        HAL_GPIO_Init(DHT11_PORT, &DHT11_GPIO_Init);
    }
}




/*---------------------------应用层----------------------------*/


/****************************************************************
*@function: dht11_delay
*@input   : n (MHz)  
*@output  : none
*@describe: 延时
*@author  : sola
****************************************************************/
void  wait(unsigned long n)
{   
        do{
        n--;
        }while(n);
}


/****************************************************************
*@function: dht11_init
*@input   : none
*@output  : none
*@describe: DHT11 起始信号
*@author  : sola
****************************************************************/
void dht11_init(void)
{
    __DHT11_GPIO_INIT();
}


/****************************************************************
*@function: ReadByte
*@input   : none
*@output  : temp
*@describe: 读一个字节
*@author  : sola
****************************************************************/
uint8_t ReadByte(void) {


        uint8_t i, temp = 0;


        for(i=0;i<8;i++) {


                while(__DHT11_READ() == 0);
               
                __DHT11_DELAY_US(40);               //40us
       
                if(__DHT11_READ() == 1) {


                        while(__DHT11_READ() == 1);


                        temp |= (uint8_t)(0x01<<(7-i));
                }
                else {
                       
                        temp &= (uint8_t)~(0x01<<(7-i));
                }
        }       
        return temp;
}


/****************************************************************
*@function: Read_DHT11
*@input   : *DHT11_Data
*@output  : temp
*@describe: DHT11 读数据
*@author  : sola
****************************************************************/
uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data) {
   
   
        __DHT11_MODE(1);            //配置为输出
       
        __DHT11_OUT_L();            //拉低
       
        __DHT11_DELAY_MS(18);       //18ms


        __DHT11_OUT_H();            //拉高
   
    __DHT11_DELAY_US(13);       //13us


        __DHT11_MODE(0);            //配置为输入


        if(__DHT11_READ() == 0) {


                while(__DHT11_READ() == 0);


                while(__DHT11_READ() == 1);


                DHT11_Data->humi_int= ReadByte();   //读取湿度整数


                DHT11_Data->humi_deci= ReadByte();  //读取湿度小数


                DHT11_Data->temp_int= ReadByte();   //读取温度整数


                DHT11_Data->temp_deci= ReadByte();  //读取温度整数


                DHT11_Data->check_sum= ReadByte();  //应答读取


                __DHT11_MODE(1);                    //配置为输出


                __DHT11_OUT_H();


                if(DHT11_Data->check_sum ==
                                    DHT11_Data->humi_int +
                                        DHT11_Data->humi_deci +
                                            DHT11_Data->temp_int+
                                                DHT11_Data->temp_deci) {
                        return SUCCESS;
                }
                else {               
                        return ERROR;       
                }
        }
    return 0;
}




/****************************************************************
*@function: DHT11_PRINTF
*@input   : none
*@output  : none
*@describe: DHT11 打印数据
*@author  : sola
****************************************************************/
#if 1
void DHT11_PRINTF(void) {


    if(Read_DHT11(&DHT11_Data) == SUCCESS) {
              
            printf("rnrn湿度为%d.%d %RH ,温度为 %d.%d℃ rn",
                                                                DHT11_Data.humi_int,
                                                                DHT11_Data.humi_deci,
                                                                DHT11_Data.temp_int,
                                                                DHT11_Data.temp_deci);
  }
}
#endif


移植也方便,就修改几个地方就好了。
注意:如果移植后通讯不成功,请修改delay_us和delay_ms,也可以调节参数A,这个在不同MCU上需要执行的周期时间是不一样的。
举报

更多回帖

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