STM32驱动——DHT11温湿度传感器

本文档详细介绍了DHT11传感器的C语言驱动程序,包括初始化、IO操作函数、数据读取以及检测传感器存在的方法,适用于嵌入式系统开发。

头文件

#ifndef __DHT11_H__
#define __DHT11_H__

#include "sys.h"
//IO方向设置
//#define DHT11_IO_IN()  {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=8<<12;}
//#define DHT11_IO_OUT() {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=3<<12;}
////IO操作函数											   
#define	DHT11_DQ_OUT PBout(1) //数据端口	Pc14 
#define	DHT11_DQ_IN  PBin(1)  //数据端口	PC14


u8 DHT11_Init(void);//初始化DHT11
u8 DHT11_Read_Data(u8 *temp,u8 *humi);//读取温湿度
u8 DHT11_Read_Byte(void);//读出一个字节
u8 DHT11_Read_Bit(void);//读出一个位
u8 DHT11_Check(void);//检测是否存在DHT11
void DHT11_Rst(void);//复位DHT11    

#endif

源文件

#include "dht11.h"
#include "delay.h"


void DHT11_IO_OUT(void)
{
    GPIO_InitTypeDef GPIO_InitStructer;
    GPIO_InitStructer.GPIO_Pin= GPIO_Pin_1;
    GPIO_InitStructer.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_InitStructer.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructer);
}



void DHT11_IO_IN(void)
{
    GPIO_InitTypeDef GPIO_InitStructer;
    GPIO_InitStructer.GPIO_Pin= GPIO_Pin_1;
    GPIO_InitStructer.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_InitStructer.GPIO_Mode=GPIO_Mode_IPU;//上拉输入
    GPIO_Init(GPIOB, &GPIO_InitStructer);
}     
//复位DHT11
void DHT11_Rst(void)	   
{                 
	DHT11_IO_OUT(); 	//SET OUTPUT
    DHT11_DQ_OUT=0; 	//拉低DQ
    delay_ms(20);    	//拉低至少18ms
    DHT11_DQ_OUT=1; 	//DQ=1 
	delay_us(30);     	//主机拉高20~40us
}

//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
u8 DHT11_Check(void) 	   
{   
	u8 retry=0;
	DHT11_IO_IN();//SET INPUT	 
    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
u8 DHT11_Read_Bit(void) 			 
{
 	u8 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读取一个字节
//返回值:读到的数据
u8 DHT11_Read_Byte(void)    
{        
    u8 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,读取失败
u8 DHT11_Read_Data(u8 *temp,u8 *humi)    
{        
 	u8 buf[5];
	u8 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];
			*temp=buf[2];
		}
	}else return 1;
	return 0;	    
}

//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在    	 
u8 DHT11_Init(void)
{	 
 	GPIO_InitTypeDef  GPIO_InitStructure;
 	
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);	 //使能PC端口时钟
	
 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;				 //P端口配置
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOC, &GPIO_InitStructure);				 //初始化IO口
 
	GPIO_SetBits(GPIOC,GPIO_Pin_14);						 //P输出高
			    
	DHT11_Rst();  //复位DHT11
	return DHT11_Check();//等待DHT11的回应
} 








### STM32 使用 DHT11 温湿度传感器教程 #### 一、硬件介绍 DHT11 是一种数字信号输出的温湿度传感器,具备高可靠性与长期稳定性。其内部集成了感湿元件和测温元件,并通过高性能单片机进行信号处理[^1]。这种设计使得 DHT11 能够提供准确的温度和湿度数据。 #### 二、软件配置 为了在 STM32 上使用 DHT11,需要定义相应的 GPIO 引脚并编写驱动函数。以下是实现的关键部分: - **GPIO 配置**: 将指定引脚设置为输入/输出模式。 - **延时功能**: 实现微秒级延迟以便于通信协议同步。 - **读取数据**: 解析来自 DHT11 的数据帧。 #### 三、代码示例 ##### 头文件 `dht11.h` ```c #ifndef __DHT11_H__ #define __DHT11_H__ #include "stm32f10x.h" #include "delay.h" // 定义 DHT11 连接的 IO 口 #define DHT11_OUT PAout(11) #define DHT11_IN PAin(11) void vDHT11Init(void); u8 xDHT11Get(u8* temp, u8* humi); #endif ``` ##### 源文件 `dht11.c` ```c #include "dht11.h" // 初始化 DHT11 所需的 GPIO 和其他外设 void vDHT11Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 启用 GPIOA 时钟 // 设置 PA11 为推挽输出模式 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); } // 获取温湿度数据 u8 xDHT11Get(u8* temp, u8* humi) { u8 i, j, dat[5]; u8 checksum; // 主机发送开始信号 DHT11_OUT(0); // 下拉至少 18ms delay_ms(20); DHT11_OUT(1); // 上拉等待 DHT11 响应 delay_us(30); // 等待 DHT11 响应 (下降沿) while (!DHT11_IN()); while (DHT11_IN()); // 等待上升沿 // 接收 40bit 数据 for (i = 0; i < 5; i++) { // 每次接收一字节 dat[i] = 0; for (j = 0; j < 8; j++) { // 每字节有 8bit while (!DHT11_IN()); // 等待上升沿 delay_us(40); // 判断电平时间 if (DHT11_IN()) // 如果此时仍为高电平,则表示 bit=1 dat[i] |= (1 << (7 - j)); while (DHT11_IN()); // 等待下降沿 } } // 校验数据有效性 checksum = dat[0] + dat[1] + dat[2] + dat[3]; if (checksum != dat[4]) return 1; // 校验失败返回错误码 *humi = dat[0]; // 返回湿度整数部分 *temp = dat[2]; // 返回温度整数部分 return 0; // 成功返回 0 } ``` #### 四、主程序调用 以下是一个简单的主循环示例,展示如何定期获取温湿度数据并打印到串口或其他设备。 ```c #include "stm32f10x.h" #include "usart.h" // 假设有 USART 发送函数 #include "dht11.h" int main() { u8 humidity, temperature; vDHT11Init(); // 初始化 DHT11 UART_Configuration(); // 初始化串口 while (1) { if (xDHT11Get(&temperature, &humidity) == 0) { printf("Humidity: %d%%\r\n", humidity); printf("Temperature: %dC\r\n", temperature); } else { printf("Error reading sensor!\r\n"); } delay_ms(2000); // 每隔两秒采集一次数据 } } ``` --- #### 注意事项 1. 在实际开发中,可能需要调整延时时间和具体寄存器操作以适配不同的 MCU 或编译环境。 2. 若遇到数据不稳定的情况,可以尝试优化电源供电质量或缩短信号线长度。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值