STM32F103C8T6最小系统板使用DHT11温湿度模块

本文介绍了使用STM32F103C8T6开发板配合DHT11温湿度传感器,通过I2C连接OLED显示屏实时显示温湿度数据的过程,同时分析了与小米温湿度计的对比结果,指出DHT11湿度测量存在约±5%的误差。
摘要由CSDN通过智能技术生成

目录

1.模块清单

2.功能展示

3.程序实现


1.模块清单

主要用到STM32F103C8T6最小系统板,0.96寸OLED4线IIC屏幕,DHT11温湿度传感器,在某宝上都可以买到。目前我买的这款DHT11温度可以读取到小数部分,湿度并不能读取到小数部分,不知道是啥原因。工程放在文末,免费获取

2.功能展示

我买了一个小米的温湿度计,然后根据温湿度计测出的数据对DHT11测出的数据进行一个对比,总体测量出来的话,DHT11湿度误差比较大,±5%,温度测量误差比较小±2℃。

3.程序实现

原理什么的就不多赘述了,b站和csdn上都有大量的讲解,我就贴出一些主要的代码部分,工程会放在文末。采样周期我是使用的tim定时器,1.5秒采样一次。

main.c部分

/**
  ******************************************************************************
	*
	*
	*			应用平台:STM32F103C8T6最小系统板
	*
	*
	*
	*
	*
	*
  ******************************************************************************
  */ 
	
#include "stm32f10x.h"
#include "OLED_I2C.h"
#include "delay.h"
#include "./led/bsp_led.h"  
#include "./usart/bsp_usart.h"
#include "tim.h"
#include "sys.h"
#include "dht11.h"

extern u8 dat[5];//DHT11数据存放数组
int flag=0;//温湿度采集标志位,1.5s采集一次数据
unsigned int m;//毫秒计算变量
float tempurate,humi;//温度 湿度  变量定义
/*

	温湿度dht11	data   接PB14
	屏幕							SCL接PB6
										SDA接PB7
	


*/




char str[64]={0};//屏幕显示字符串



int main(void)
{
/*初始化LED、串口、OLED、DHT11*/
	delay_init();//初始化延迟函数
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级设置
	USART_Config();//串口初始化函数
	LED_GPIO_Config();//LED初始化函数
	I2C_Configuration();//配置CPU的硬件I2C
	OLED_Init();//初始化OLED
	OLED_CLS();//清屏
	TIM3_Init(1000-1,72-1);     //打开定时器3,周期为500us
	DHT11_GPIO_IN();//温湿度传感器初始化

	while(1)
	{
		//获取数据时让开发板的灯闪一下
		if(flag)
			GPIO_ResetBits(GPIOC, GPIO_Pin_13);
		else 
			GPIO_SetBits(GPIOC, GPIO_Pin_13);
		
			
			if(flag)
			{	
				if(DHT_Read())//读取数据正确情况下进行温湿度计算
				{
					flag=0;//标志位置零进入下一次计时
					humi=dat[0] + dat[1]/10.f+5;//计算湿度
					tempurate=dat[2] + dat[3]/10.f;//计算温度
				}

				OLED_ShowCN(0,2,0);//显示汉字"温"
				OLED_ShowCN(16,2,1);//显示汉字"度"
				sprintf(str,": %.1f 'C   ",tempurate);//显示温度数值
				OLED_ShowStr(32,2,(unsigned char*)str,2);
				OLED_ShowCN(0,5,2);//显示汉字"湿"
				OLED_ShowCN(16,5,3);//显示汉字"度"
					

				sprintf(str,": %.1f  %%  ",humi);//显示湿度数值
				OLED_ShowStr(32,5,(unsigned char*)str,2);
			}
		
	} 
}



/*********************************************END OF FILE**********************/





dht11.c部分

#include "dht11.h"
#include "delay.h"
uint8_t dat[5]={0x00,0x00,0x00,0x00,0x00};
uint8_t sum = 0;

/*
*初始化输出
*/
void DHT11_GPIO_OUT(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); 
		
  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

/*
*初始化输入
*/
void DHT11_GPIO_IN(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
		
  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;	
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
  	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

/*
*读取一个字节
*/
uint8_t DHT_Read_Byte(void)
{
	uint8_t temp;
	uint8_t ReadDat = 0;
	
	uint8_t retry = 0;
	uint8_t i;
	for(i=0; i<8;i++)
	{	
		//读取一位数据时,会先收到低电平信号50us
		while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0 && retry< 100)
		{
			Delay_us(1);
			retry++;
		}
		retry = 0;
		Delay_us(30);
		temp = 0;
		//再接收高电平信号16us-28us(代表数据0)或高电平信号70us(代表数据1)
		if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)==1) temp=1;
		while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 1 && retry<100)
		{
			Delay_us(1);
			retry++;
		}
		retry = 0;
		ReadDat<<=1;
		ReadDat|=temp;
	}
	return ReadDat;
}

/*
*读取一次数据
*/
uint8_t DHT_Read(void)
{
	uint8_t i;
	uint8_t retry = 0;
	//总线设置为输出并拉低18ms
	DHT11_GPIO_OUT();
	GPIO_ResetBits(GPIOB, GPIO_Pin_14);
	Delay_ms(18);
	//总线再拉高40ms
	GPIO_SetBits(GPIOB, GPIO_Pin_14);
	Delay_us(40);
	//总线设置为输入
	DHT11_GPIO_IN();
	Delay_us(20);
	//等待响应信号为低电平
	if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)
	{	
		//等待响应信号为高电平,超时等待100us
		while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)==0&&retry<100)
		{
			Delay_us(1);
			retry++;
		}
		retry=0;
		//等待数据传送,超时等待100us
		while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)==1&&retry<100)
		{
			Delay_us(1);
			retry++;
		}
		retry=0;
		//循环读取数据,dat[0]为湿度整数数据,dat[1]为湿度小数数据,dat[2]为温度整数数据,dat[3]为温度小数数据,dat[4]为校验和数据
		for(i=0;i<5;i++)
		{
			dat[i] = DHT_Read_Byte();
		}
		Delay_us(50);
	}
	//当校验和数据=湿度整数数据+湿度小数数据+温度整数数据+温度小数数据,说明正确传送。
	sum = dat[0] + dat[1] + dat[2] + dat[3];
	if(dat[4]  == sum)
	{
		return 1;
	}
	else
		return 0;
}

dht11.h

#ifndef __DHT11_H
#define __DHT11_H
#include "stm32f10x.h"
void DHT11_GPIO_OUT(void);
void DHT11_GPIO_IN(void);
uint8_t DHT_Read_Byte(void);
uint8_t DHT_Read(void);
#endif

工程链接:https://download.csdn.net/download/weixin_53801451/88787956

  • 16
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
以下是用STM32C8T6驱动DHT11的代码: ```c #include "stm32c8t6.h" #define DHT11_PIN 0x01 //使用PA1引脚 #define DHT11_OUT GPIOA->MODER |= (1 << (DHT11_PIN * 2)); //输出模式 #define DHT11_IN GPIOA->MODER &= ~(1 << (DHT11_PIN * 2)); //输入模式 #define DHT11_HIGH GPIOA->ODR |= (1 << DHT11_PIN); //输出高电平 #define DHT11_LOW GPIOA->ODR &= ~(1 << DHT11_PIN); //输出低电平 #define DHT11_READ ((GPIOA->IDR & (1 << DHT11_PIN)) != 0) //读取引脚状态 void delay_us(uint32_t us) { uint32_t count = us * (SystemCoreClock / 1000000U); while (count--) { __NOP(); } } void DHT11_init(void) { RCC->AHBENR |= RCC_AHBENR_GPIOAEN; //使能GPIOA时钟 DHT11_OUT; //设置引脚为输出模式 DHT11_HIGH; //设置为高电平 delay_us(1000); //等待1ms } uint8_t DHT11_read_byte(void) { uint8_t byte = 0; for (int i = 0; i < 8; i++) { byte <<= 1; while (!DHT11_READ); //等待引脚为高电平 delay_us(30); //等待30us if (DHT11_READ) { byte |= 1; //如果引脚仍为高电平,则为1 } while (DHT11_READ); //等待引脚为低电平 } return byte; } void DHT11_read(uint8_t *temp, uint8_t *humidity) { uint8_t data[5] = {0}; DHT11_OUT; DHT11_LOW; delay_us(18000); //拉低引脚18ms DHT11_HIGH; delay_us(40); //拉高引脚40us DHT11_IN; while (DHT11_READ); //等待DHT11响应 while (!DHT11_READ); //等待DHT11开始发送数据 for (int i = 0; i < 5; i++) { data[i] = DHT11_read_byte(); } DHT11_OUT; DHT11_HIGH; if ((data[0] + data[1] + data[2] + data[3]) == data[4]) { *humidity = data[0]; *temp = data[2]; } } int main(void) { uint8_t temp, humidity; DHT11_init(); while (1) { DHT11_read(&temp, &humidity); //在这里处理温湿度数据 } return 0; } ``` 该代码使用STM32C8T6的GPIO模块来驱动DHT11传感器。在主函数中,使用DHT11_init函数初始化DHT11引脚,然后使用DHT11_read函数读取温湿度数据。请注意,DHT11_read函数返回的温湿度数据是以指针的形式传递的,因此需要声明一个指向uint8_t类型的变量来存储数据。在读取温湿度数据之后,您可以在主函数中使用这些数据来执行任何适当的操作。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寻梦旅程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值