12、stm32通过dht11读取温湿度
一、配置
二、代码
dht11.c
/*
* dht11.c
*
* Created on: Aug 19, 2024
* Author: Administrator
*/
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
/*
*TIM3定时器实现us级延时
*/
void Delay_us(uint16_t delay)
{
__HAL_TIM_DISABLE(&htim3);
__HAL_TIM_SET_COUNTER(&htim3,0);
__HAL_TIM_ENABLE(&htim3);
uint16_t curCnt=0;
while(1)
{
curCnt=__HAL_TIM_GET_COUNTER(&htim3);
if(curCnt>=delay)
break;
}
__HAL_TIM_DISABLE(&htim3);
}
/*
* 更改DHT11引脚方向
*/
// 输出output
void Dht11_DATA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/*Configure GPIO pin : PB12 */
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
// 输入input
void Dht11_DATA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/*Configure GPIO pin : PB12 */
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/*
* DHT11驱动
*/
//复位DHT11
void DHT11_Rst(void)
{
Dht11_DATA_OUT(); //设置为输出
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); //拉低引脚
HAL_Delay(20); //延迟20ms
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); //拉高引脚
Delay_us(30); //延迟30us
}
//等待DHT11回应
//返回值:1代表未检测到存在,0代表检测到存在
uint8_t DHT11_Check(void)
{
uint8_t retry=0;
Dht11_DATA_IN(); //设置为输入
while(GPIO_PIN_SET==HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) && retry<100)
{
retry++;
Delay_us(1);
}
if(retry>=100)
return 1;
else
retry=0;
while(GPIO_PIN_RESET==HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) && retry<100)
{
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(GPIO_PIN_SET==HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) && retry<100)
{
retry++;
Delay_us(1);
}
retry=0;
while(GPIO_PIN_RESET==HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) && retry<100)
{
retry++;
Delay_us(1);
}
Delay_us(40);
if(GPIO_PIN_SET==HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12))
return 1;
else
return 0;
}
//从DHT11读取一个字节
//返回值:读取到的字节数据(8位)
uint8_t DHT11_Read_Byte(void)
{
uint8_t dat=0;
for(uint8_t i=0;i<8;i++)
{
dat <<= 1;
dat |= DHT11_Read_Bit();
}
return dat;
}
//从DHT11读取一次数据
//humi:湿度值,temp:温度值
//返回值:0代表正常,1代表读取失败
uint8_t DHT11_Read_Data(uint8_t* humi,uint8_t* temp)
{
uint8_t buf[5];
DHT11_Rst();
if(DHT11_Check() == 0)
{
for(uint8_t i=0;i<5;i++)
buf[i]=DHT11_Read_Byte();
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
*humi=buf[0]; //这里省略小数部分
*temp=buf[2];
}
}
else
return 1;
return 0;
}
dht11.h
/*
* dht11.h
*
* Created on: Aug 19, 2024
* Author: Administrator
*/
#ifndef INC_DHT11_H_
#define INC_DHT11_H_
void Delay_us(uint16_t delay); //通过TIM3定时器微秒级延时
void Dht11_DATA_OUT(void); //设置数据交互口为输出
void Dht11_DATA_IN(void); //设置数据交互口为输入
void DHT11_Rst(void); //复位DHT11
uint8_t DHT11_Check(void); //DHT11状态反馈
uint8_t DHT11_Read_Bit(void); //读DHT11一位数据
uint8_t DHT11_Read_Byte(void); //读DHT11一字节数据
uint8_t DHT11_Read_Data(uint8_t* humi,uint8_t* temp); //DHT11数据显示
#endif /* INC_DHT11_H_ */
main.c
/* USER CODE BEGIN Includes */
#include <stdio.h> //sprintf函数头文件
#include <string.h> //strlen函数头文件
#include "dht11.h"
/* USER CODE END Includes */
/* USER CODE BEGIN 1 */
uint8_t temperature = 1; //温度值
uint8_t humidity = 1; //湿度值
char* CntState = "No Connect!\r\n"; //连接状态
uint8_t aTxBuffer[50]; //打印信息
/* USER CODE END 1 */
/* USER CODE BEGIN 2 */
DHT11_Rst(); //复位DHT11
while(DHT11_Check()) //检测DHT11连接
{
HAL_UART_Transmit(&huart1, (uint8_t *)CntState, strlen(CntState), 200);
CntState = "Fail!\r\n";
HAL_UART_Transmit(&huart1, (uint8_t *)CntState, strlen(CntState), 200);
HAL_Delay(500);
}
CntState = "Success!\r\n";
HAL_UART_Transmit(&huart1, (uint8_t *)CntState, strlen(CntState), 200);
/* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
while (1)
{
DHT11_Read_Data(&humidity,&temperature); //检测出温湿度的值
sprintf(aTxBuffer,"temperature : %d ^C "
"humidity : %d %% \r\n", temperature,humidity); //打印温湿度的值
HAL_UART_Transmit(&huart1,aTxBuffer,strlen((const char*)aTxBuffer),200);
HAL_Delay(500);
/* USER CODE END WHILE */
三、其他
参考教程 http://t.csdnimg.cn/pDPY5