一、参考资料

http://【DHT11温湿度传感器详解(STM32)】https://www.bilibili.com/video/BV182421Z7by?vd_source=70e3aaa6cbfe13f5858272f48dacf336

这个是B站的一个博主讲的基于STM32F103C8T6的标准库DHT11温湿度传感器 

资料在D盘的大二寒假资料里面,这里面的OLED驱动文件和DHT11都是标准库的文件没有转化成hal库

https://blog.csdn.net/lwb450921/article/details/122293440?fromshare=blogdetail&sharetype=blogdetail&sharerId=122293440&sharerefer=PC&sharesource=2301_81764359&sharefrom=from_link

这个是CSDN的一个博主讲的基于STM32F103C8T6的hal库的DHT11温湿度传感器 (这篇文章只用到了串口和DHT11两个外设,没有用到OLED)

资料在D盘的大二寒假资料里面,这里面的DHT11的驱动文件是hal库的

二、基础知识

        硬件供电给3.3V~5V即可

三、CubeMx及Keil的配置

 

注意:

        要是要使用串口的话就一定要勾选这个

        ST_Link下载就一定要勾选这个,不然跑不了程序 

四、DHT11的底层驱动文件

(1)DHT11.c 
#include "dht11.h"
extern UART_HandleTypeDef huart1;
/**
  * @brief  温湿度传感器主函数
  * @param  void
  * @retval None
  */
void DHT11(void)
{
    if(DHT11_READ_DATA() == 1)
    {
        printf("数据校验成功!\r\n");
    }
    else
    {
        printf("DHT11没有应答,请检查传感器!\r\n");
    }
    HAL_Delay(1000);                              
  
}
 
/**
  * @brief  温湿度传感器启动信号发送
  * @param  void
  * @retval None
  */
void DHT11_START(void)
{
    DHT11_GPIO_MODE_SET(0);                         //  主机设置为输出模式
    
    DHT11_PIN_RESET;                                //  主机拉低电平
    
    HAL_Delay(20);                                  //  主机等待 18 < ms > 30
    
    DHT11_GPIO_MODE_SET(1);                         //  主机设置为输入模式,等待DHT11答应
}                                                   //  因为设置了上拉输入,GPIO -> 1
 
/**
  * @brief  读取一位数据 1bit
  * @param  void
  * @retval 0/1
  */
unsigned char DHT11_READ_BIT(void)
{
    while(!DHT11_READ_IO);                          //  过度数据的低电平 
    
    Coarse_delay_us(40);
 
    if(DHT11_READ_IO)                               //  此时如果还为高电平则数据为 1
    {
        while(DHT11_READ_IO);                       //  过度数据的高电平
        return 1;
    }   
    else                                            //  若此时为低则为 0
    {
        return 0;
    }
}
 
/**
  * @brief  读取一个字节数据 1byte / 8bit
  * @param  void
  * @retval temp
  */
unsigned char DHT11_READ_BYTE(void)
{
    uint8_t i,temp = 0;                             //  暂时存储数据
    
    for(i=0; i<8 ;i++)
    {
        temp <<= 1;                                 
        if(DHT11_READ_BIT())                        //  1byte -> 8bit
        {
            temp |= 1;                              //  0000 0001
        }
    }
    return temp;
}
 
/**
  * @brief  读取温湿度传感器数据 5byte / 40bit
  * @param  void
  * @retval 0/1/2
  */
unsigned char DHT11_READ_DATA(void)
{
    uint8_t i;
    uint8_t data[5] = {0};
    
    DHT11_START();                                  //  主机发送启动信号
    
    if(DHT11_Check())                               //  如果DHT11应答     
    {  
        while(!DHT11_READ_IO);                      //  过度DHT11答复信号的低电平
        while(DHT11_READ_IO);                       //  过度DHT11答复信号的高电平
        
        for(i=0; i<5; i++)
        {                        
            data[i] = DHT11_READ_BYTE();            //  读取 5byte
        }
        
        if(data[0] + data[1] + data[2] + data[3] == data[4])
        {
            printf("当前湿度:%d.%d%%RH当前温度:%d.%d°C--",data[0],data[1],data[2],data[3]);
            return 1;                               //  数据校验通过
        }
        else
        {
            return 0;                               //  数据校验失败
        }
    }
    else                                            //  如果DHT11不应答
    {
        return 2;
    }
}
 
/**
  * @brief  检测温湿度传感器是否存在(检测DHT11的应答信号)
  * @param  void
  * @retval 0/1
  */
unsigned char DHT11_Check(void)
{
 
    Coarse_delay_us(40);
    if(DHT11_READ_IO == 0)                          //  检测到DHT11应答
    {
        return 1;
    }
    else                                            //  检测到DHT11不应答
    {
        return 0;
    }
}
 
/**
  * @brief  设置引脚模式
  * @param  mode: 0->out, 1->in
  * @retval None
  */
static void DHT11_GPIO_MODE_SET(uint8_t mode)
{
    if(mode)
    {
        /*  输入  */
        GPIO_InitTypeDef GPIO_InitStruct;
        GPIO_InitStruct.Pin = GPIO_PIN_9;                   //  9号引脚
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;             //  输入模式
        GPIO_InitStruct.Pull = GPIO_PULLUP;                 //  上拉输入
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    }
    else 
    {
        /*  输出  */
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.Pin = GPIO_PIN_9;                //  9号引脚
        GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;      //  Push Pull 推挽输出模式
        GPIO_InitStructure.Pull = GPIO_PULLUP;              //  上拉输出
        GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;    //  高速
        HAL_GPIO_Init(GPIOB,&GPIO_InitStructure);
    }
}
 
/**
  * @brief  程序延时 us , 必须在 72M 主频下使用
  * @param  us: <= 4294967295
  * @retval None
  */
void Coarse_delay_us(uint32_t us)
{
    uint32_t delay = (HAL_RCC_GetHCLKFreq() / 4000000 * us);
    while (delay--)
	{
		;
	}
}
 
 
 
(2)DHT11.h
#ifndef __DHT11_H__
#define __DHT11_H__
 
/* Private includes ----------------------------------------------------------*/
#include "main.h"
#include "gpio.h"
#include "stdio.h"
#include "stm32f1xx.h"
 
/* Private define ------------------------------------------------------------*/
#define DHT11_PIN_SET   HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET)                                            //  设置GPIO为高
#define DHT11_PIN_RESET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET)                                          //  设置GPIO为低
#define DHT11_READ_IO   HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_9)                                                          //  DHT11 GPIO定义
 
 
 
/* Private function prototypes -----------------------------------------------*/
void DHT11(void);
void DHT11_START(void);
unsigned char DHT11_READ_BIT(void);
unsigned char DHT11_READ_BYTE(void);
unsigned char DHT11_READ_DATA(void);
unsigned char DHT11_Check(void);
static void DHT11_GPIO_MODE_SET(uint8_t mode);
 
void Coarse_delay_us(uint32_t us);
    
#endif
 

五、main函数的修改

#include "dht11.h"
HAL_Delay(1000);
DHT11();

六、串口函数的修改

        这个可以放在main函数里面也可以放在usart.c里面,如果是直接在dht11.c文件里面打印的话也可以放在里面

        这个是放在dht11.c里面的

        这个是放在usart.c里面的 

注意:

         要使用串口的话就一定要写这个头文件和函数,不然无法答应

#include "stdio.h"
int fputc(int ch,FILE *f)
{   HAL_UART_Transmit (&huart1 ,(uint8_t *)&ch,1,HAL_MAX_DELAY );
    return ch;
}

七、硬件连接

 八、效果展示

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐