CubeMX+STM32F4+DHT11模块

本文详细介绍了如何使用CubeMX配置STM32F4系列芯片,通过单总线通信方式读取DHT11温湿度传感器的数据。配置包括时钟设置、IO口选择及延时函数的定时器配置。代码部分展示了从发送开始信号、检测响应到读取和校验数据的完整过程,以及相应的IO口操作和延时函数实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章目录


前言

本文主要介绍利用CubeMX配置STM32F4系列芯片读取DHT11温湿度采集模块,仅作于学习


一、CubeMX配置

1、新建工程,配置相关时钟和时钟树,该例程配置72Mhz的时钟主频,相关配置前面文章已有叙述,这里不再多讲

2、由于DHT11采用单总线时序电路来进行通信,因此我们只需要用到一个IO口就能实现对DHT11温湿度采集模块的数据读取。这里配置了PD6作为通信IO

 3、该模块对时序有要求,需要用到us级别的延时函数,因此我们还需要配置一个定时器来做延时函数。相关配置如下:


二、代码

1、模块.c文件

#include "dht11.h"
/***************************
* 数据发送时序:
* 首先主机发送开始信号,即拉低数据线保持t1(至少18ms)时间,
* 接着拉高数据线t2(20~40us)时间,然后读取DHT11的响应,
* DHT11会拉低数据线并保持t3(40~50us)时间作为响应信号,接
* 着DHT11拉高数据线并保持t4(40~50us)时间后,开始传输数据
*
* 传输协议:
* 数据包由5个字节(40Bit)组成,数据分小数和整数部分
* 一次完整的数据传输为40bit,一位一位传输,高位先出,传输顺序为:
* 8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位
*
* 湿度 = byte4.byte3    byte4整数,byte3小数
* 温度 = byte2.byte1    byte2整数,byte1小数
* 校验 = byte0 = byte4 + byte3 + byte2 + byte1
*
* 采集周期不小于1s
***************************/

//8bit温湿度数据
uint8_t tem_integer;
uint8_t tem_decimal;
uint8_t hum_integer;
uint8_t hum_decimal;

/*****************/
//采集数据处理
void DH11_ReadDate_Handle(void)
{
	uint8_t i;
	uint8_t buf[5]={0};       //数据转存数组
	uint16_t tem=0;
	uint16_t hum=0;
	DHT11_SendOut();         //发送信号等待响应
	if(DHT11_Check()==0){
		for(i=0;i<5;i++){
			buf[i]=DHT11_ReadByte();//获取1Byte数据
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){//校验
			tem=(buf[2]<<8) + buf[3];  //8Bit转存16Bit
			hum=(buf[0]<<8) + buf[1];
			tem_integer = tem>>8;    //右移8Bit,低8位清0
			tem_decimal = tem&0xff;  //按位与(0xff-->0000000011111111),高8位清0
			hum_integer = hum>>8;
			hum_decimal = hum&0xff;
//			printf("当前环境温度: %d.%d 摄氏度\r\n",tem_integer,tem_decimal);
//			printf("当前环境湿度: %d.%d%%\r\r\n",hum_integer,hum_decimal);		
		}
	}
}

/*****************/
//发送数据给DHT11
void DHT11_SendOut(void)
{
	DHT11_IO_OUT();
	DHT11_Date_Low;
	HAL_Delay(18);  //拉低18ms
	DHT11_Date_High;
	delay_us(30);   //拉高30us
}

/*****************/
//检测DHT11是否开始传输数据
uint8_t DHT11_Check(void)
{   
	uint8_t retry=0;
	DHT11_IO_IN();      
	while (DHT11_Date && retry<100){	//拉低40~80us
		retry++;
		delay_us(1);
	}
	if(retry>=100)return 1;
	else retry=0;
	while (!DHT11_Date && retry<100){ //拉高40~80us
		retry++;
		delay_us(1);
	}
	if(retry>=100)return 1;
	return 0;
}

/*****************/
//读取1Bit数据
uint8_t DH11_ReadBit(void)
{
    uint8_t retry=0;     //retry用于防止卡死
    //等待DHT11响应拉低(默认拉高),最大等待时间为100us
	while(DHT11_Date && retry<100){
		delay_us(1);   
		retry++;
	}
	retry=0;
    //等待DHT11响应拉高,最大等待时间为100us
	while(!DHT11_Date && retry<100){
		delay_us(1);  
		retry++;
	}
	delay_us(40);	//高电平等待40us
	if(DHT11_Date)return 1;//获取DHT11数据
	else return 0;
}

/*****************/
//读取1Byte数据
uint8_t DHT11_ReadByte(void)
{
	uint8_t i;
	uint8_t Read_Byte=0;	//用于存放1Byte(8bit)数据
	for(i=0;i<8;i++){
   	Read_Byte<<=1;     //Read_Byte左移一位
	  Read_Byte |= DH11_ReadBit(); //将读取到的二进制数据写入Read_Byte末位
  }
	return Read_Byte;
}

/*****************/
//IO口设置为输入
void DHT11_IO_IN(void)
{	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.Pin = GPIO_PIN_6;
	GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
	HAL_GPIO_Init(GPIOD,&GPIO_InitStructure);
}
/*****************/
//IO口设置为输出
void DHT11_IO_OUT(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.Pin = GPIO_PIN_6;
	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOD,&GPIO_InitStructure);
}
/*****************/
//us延时函数
void delay_us(uint16_t us)
{
	uint16_t differ = 0xffff-us-5;				
	__HAL_TIM_SET_COUNTER(&htim3,differ);	//设定TIM3计数器起始值
	HAL_TIM_Base_Start(&htim3);		//启动定时器	
	
	while(differ < 0xffff-5){	//判断
		differ = __HAL_TIM_GET_COUNTER(&htim3);		//查询计数器的计数值
	}
	HAL_TIM_Base_Stop(&htim3);
}

2、模块.h文件

#ifndef __DHT11_H
#define __DHT11_H
#include "stm32f4xx_hal.h"
#include <stdio.h>

#define   DHT11_Date         HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_6)
#define   DHT11_Date_Low     HAL_GPIO_WritePin(GPIOD,GPIO_PIN_6,GPIO_PIN_RESET)
#define   DHT11_Date_High    HAL_GPIO_WritePin(GPIOD,GPIO_PIN_6,GPIO_PIN_SET)

extern TIM_HandleTypeDef htim3;   //用于写延时函数

void DHT11_IO_IN(void);
void DHT11_IO_OUT(void);
void delay_us(uint16_t us);
void DHT11_SendOut(void);
uint8_t DHT11_Check(void);
uint8_t DH11_ReadBit(void);
uint8_t DHT11_ReadByte(void);
void DH11_ReadDate_Handle(void);


#endif

总结

温湿度读取的主要代码就那些啦,如需和其它项目结合,只要将这两个源码拷贝到相应的工程文件就能实现对温湿度的读取啦。另外,欢迎大家在评论区指出笔者的不足之处

注:该文章仅用于学习,如有侵权,告知必删

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值