STM32F103ZET6——DHT11温湿度传感器(hal库)

一、CubeMX配置

(1)调试接口配置

        如下图进行调试接口配置,将调试接口设置成SW模式,占用芯片PA13、PA14两个引脚

(2)时钟配置

        如下图分别进行外部高速时钟HSE和时钟树的配置,设置HCLK为72MHz(最高72MHz,也可以配置其他),其配置图如图所示

(3)GPIO配置

        DHT11只有三个引脚VCC——3.3V,GND——GND,数据传输引脚——PA1,这里将PA1设置为输出模式

(4)定时器TIM配置

        这里选择TIM2,设置定时器为内部时钟,由于TIM2的内部时钟CK_INT来自于外设总线APB1提供的定时时钟TIMx_CLK(72MHz),所以经过(72-1)的预分频后刚好是1MHz,也就是1us,后续会在cube中生成的tim.c文件中由程序实现延时函数

(5)USART串口配置

        为了验证程序的可行性,我们利用串口将程序的结果传输到电脑上,这里选择异步模式,串口波特率为115200Bits/s,其USART配置如图所示

(6)

二、程序修改部分

(1)tim.c

/* USER CODE BEGIN 1 */
void delay_us(uint16_t us)
{
    uint16_t differ = 0xffff-us-5;                
    __HAL_TIM_SET_COUNTER(&htim2,differ);    
    HAL_TIM_Base_Start(&htim2);        
    
    while(differ < 0xffff-5)
    {   
        differ = __HAL_TIM_GET_COUNTER(&htim2);     
    }
    HAL_TIM_Base_Stop(&htim2);
}

void Delay_us(uint16_t myus)//基于TIM3定时器的μs延时函数
{
    uint16_t differ = 0xffff-myus-5;         
    HAL_TIM_Base_Start(&htim2);         
    
    while(differ < 0xffff-5)
    {   
        differ = __HAL_TIM_GET_COUNTER(&htim2);   
    }
    HAL_TIM_Base_Stop(&htim2);
}

/* USER CODE END 1 */

 (2)tim.h

/* USER CODE BEGIN Includes */
void delay_us(uint16_t us);
void Delay_us(uint16_t myus);
/* USER CODE END Includes */

(3)DHT11驱动文件

dht11.c

#include "dht11.h"
#include "tim.h"

void DHT11_IO_IN(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	GPIO_InitStructure.Pin = GPIO_PIN_1;
	GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
	HAL_GPIO_Init(GPIOA,&GPIO_InitStructure);
}

void DHT11_IO_OUT(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.Pin = GPIO_PIN_1;
	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOA,&GPIO_InitStructure);
}


//复位DHT11
void DHT11_Rst(void)	   
{                 
	DHT11_IO_OUT(); 	//设置为输出
	DHT11_DQ_OUT_LOW; 	//拉低DQ
	HAL_Delay(20);    	//拉低至少18ms
	DHT11_DQ_OUT_HIGH; 	//DQ=1 
	delay_us(30);     	//主机拉高20~40us
}

//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
uint8_t DHT11_Check(void) 	   
{   
	uint8_t retry=0;
	DHT11_IO_IN();      //设置为输出	 
	while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=100)return 1;
	else retry=0;
	while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us
	{
		retry++;
		delay_us(1);
	};
	if(retry>=100)return 1;	    
	return 0;
}

//从DHT11读取一个位
//返回值:1/0
uint8_t DHT11_Read_Bit(void) 			 
{
 	uint8_t retry=0;
	while(DHT11_DQ_IN&&retry<100)//等待变为低电平
	{
		retry++;
		delay_us(1);
	}
	retry=0;
	while(!DHT11_DQ_IN&&retry<100)//等待变高电平
	{
		retry++;
		delay_us(1);
	}
	delay_us(40);//等待40us
	if(DHT11_DQ_IN)return 1;
	else return 0;		   
}

//从DHT11读取一个字节
//返回值:读到的数据
uint8_t DHT11_Read_Byte(void)    
{        
	uint8_t i,dat;
	dat=0;
	for (i=0;i<8;i++) 
	{
   		dat<<=1; 
	    dat|=DHT11_Read_Bit();
    }						    
    return dat;
}

//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
uint8_t DHT11_Read_Data(uint16_t *temp,uint16_t *humi)    
{        
 	uint8_t buf[5];
	uint8_t i;
	DHT11_Rst();
	if(DHT11_Check()==0)
	{
		for(i=0;i<5;i++)//读取40位数据
		{
			buf[i]=DHT11_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
		{
			*humi=(buf[0]<<8) + buf[1];
			*temp=(buf[2]<<8) + buf[3];
		}
	}else return 1;
	return 0;	    
}

//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在     	 
uint8_t DHT11_Init(void)
{ 
  DHT11_Rst();
	return DHT11_Check();
}

dht11.h

#ifndef __DHT11_H__
#define __DHT11_H__
#include "main.h"
#define DHT11_DQ_OUT_HIGH HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET)
#define DHT11_DQ_OUT_LOW 	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET)
#define DHT11_DQ_IN	 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1)

//IO方向设置
void DS18B20_IO_IN(void);
void DS18B20_IO_OUT(void);
	
uint8_t DHT11_Init(void);//初始化DHT11
uint8_t DHT11_Read_Data(uint16_t *temp,uint16_t *humi);//读取温湿度
uint8_t DHT11_Read_Byte(void);//读出一个字节
uint8_t DHT11_Read_Bit(void);//读出一个位
uint8_t DHT11_Check(void);//检测是否存在DHT11
void DHT11_Rst(void);//复位DHT11  

#endif

(4)在main.c中声明

/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "dht11.h"
/* USER CODE END Includes */

串口重定向函数

/* USER CODE BEGIN PV */
int fputc(int ch,FILE *f)
{
    HAL_UART_Transmit(&huart1,(uint8_t *) &ch,1,HAL_MAX_DELAY);
    return ch;    
}
int fgetc(FILE *f)
{
    uint8_t ch;
    HAL_UART_Receive(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);
    return ch;
}
/* USER CODE END PV */

变量定义

/* USER CODE BEGIN PD */
uint16_t temperature;
uint16_t humidity;
/* USER CODE END PD */

主函数

  /* USER CODE BEGIN 2 */
  while(DHT11_Init())
  {
    printf("DHT11 Checked failed!!!\r\n");
    HAL_Delay(500);
  }
    printf("DHT11 Checked Sucess!!!\r\n");
  /* USER CODE END 2 */

while中

  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
	DHT11_Read_Data(&temperature,&humidity);
    printf("DHT11 Temperature = %d.%d degree\r\n",temperature>>8,temperature&0xff);
    printf("DHT11 Humidity = %d.%d%%\r\n",humidity>>8,humidity&0xff);
    HAL_Delay(1000);
  }

效果展示

打开Use MicroLIB

  • 15
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值