STM32驱动DHT11

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("\r\n\r\n湿度为%d.%d %RH ,温度为 %d.%d℃ \r\n",
                                                                DHT11_Data.humi_int,
                                                                DHT11_Data.humi_deci,
                                                                DHT11_Data.temp_int,
                                                                DHT11_Data.temp_deci);
  } 
}
#endif

移植也方便,就修改几个地方就好了。

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

发布了45 篇原创文章 · 获赞 52 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_42312125/article/details/98831968