DHT11温湿度模块驱动程序

DHT11(STM32)驱动

串口助手打印输出**

##本驱动使用STM32F103ZET6开发板亲测可用,DHT11驱动程序如下:

**

dht11.c

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


/*
 * 函数名:DHT11_GPIO_Config
 * 描述  :配置DHT11用到的I/O口
 * 输入  :无
 * 输出  :无
 */
 void DHT11_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;	//GPIO
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOA, ENABLE );	 //使能PORTA口时钟  
 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;  //SPI CS
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	/* Deselect the PA0 Select high */
	GPIO_SetBits(GPIOA,GPIO_Pin_0);
}
/*
 * 函数名:DHT11_Mode_IPU
 * 描述  :使DHT11-DATA引脚变为输入模式
 * 输入  :无
 * 输出  :无
 */
void DHT11_Mode_IPU(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;	//GPIO
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;  //SPI CS
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  //复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);

}
/*
 * 函数名:DHT11_Mode_Out
 * 描述  :使DHT11-DATA引脚变为输出模式
 * 输入  :无
 * 输出  :无
 */
void DHT11_Mode_Out(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;	//GPIO
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;  //SPI CS
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

}



/*
 *主机给从机发送复位脉冲
 */
void DHT11_Rst(void)	   
{        
    /* IO设置为推挽输出*/	
	  DHT11_Mode_Out(); 
	  /*产生至少20ms的低电平复位信号 */
    DHT11_DQ_OUT_Low; 
		DelayMs(20);  
    /* 在产生复位信号后,需将总线拉高 */	
    DHT11_DQ_OUT_High; 
	  DelayUs(30);    	
	  DHT11_Mode_IPU(); 
	
}

/*
 * 检测从机给主机返回的应答脉冲
 *从机接收到主机的复位信号后,会在15~60us后给主机发一个应答脉冲
 * 0:成功
 * 1:失败
 */
u8 DHT11_Answer_Check(void) 	   
{     
	  uint8_t retry = 0;
	  DHT11_Mode_IPU();
	  while(DHT11_DQ_IN && retry < 100)
		{
			retry ++;
			DelayUs(1);
		}
		if(retry >= 100)
		{
			return 1;
		}
		else
		{
			retry = 0;
		}
		while(!DHT11_DQ_IN && retry <100)
		{
			retry ++;
			DelayUs(1);
		}
		if(retry >= 100)
		{
			return 1;
		}
		return 0;
}

//从DHT11读取一个位
//返回值:1/0
u8 DHT11_Read_Bit(void) 			 // read one bit
{
	
	uint8_t retry;
	
	while(DHT11_DQ_IN && retry < 100)
	{
		retry ++;
		DelayUs(1);
	}
	retry = 0;
	while(!DHT11_DQ_IN && retry < 100)
	{
		retry ++;
		DelayUs(1);
	}
	
	DelayUs(40);
	
	if(DHT11_DQ_IN)
	{
		return 1;
	}
	else
  {
		return 0;
	}
	
}



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

//初始化DHT11的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在    	 
u8 DHT11_Init(void)
{
  DHT11_GPIO_Config();
	DHT11_Rst();
	return DHT11_Answer_Check();
}  
//从DHT11得到温度值
//精度:+/-2C
//返回值:温度值 (0~50) 
u8 DHT11_Read_Data(uint8_t *temp,uint8_t *humi)
{

	uint8_t buf[5],i;
	
	DHT11_Rst();
	
	if(DHT11_Answer_Check() == 0 )
  {
		//检测到DHT11响应

		for(i = 0; i < 5 ; i++)
		{
				buf[i] = DHT11_Read_Byte();				
		}
		if((buf[0]+buf[1]+buf[2]+buf[3]) == buf[4])
		{
			*humi = buf[0]+buf[1];
			*temp = buf[2]+buf[3];
		}
	}
  else
	{
		return 1;
	}

	return 0;
} 
 

dht11.h

#ifndef __DHT11_H
#define __DHT11_H 
  
#include "stm32f10x.h"

#define DHT11_DQ_OUT_Low GPIO_ResetBits(GPIOA,GPIO_Pin_0)  //数据端口	PB11 
#define DHT11_DQ_OUT_High GPIO_SetBits(GPIOA,GPIO_Pin_0)  //数据端口	PB11
#define DHT11_DQ_IN GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)   //数据端口	PB11

void DHT11_GPIO_Config(void);

void DHT11_Mode_IPU(void);
void DHT11_Mode_Out(void);


u8 DHT11_Init(void);//初始化DHT11
u8 DHT11_Read_Data(uint8_t *temp,uint8_t *humi);

u8 DHT11_Read_Byte(void);//读出一个字节
u8 DHT11_Read_Bit(void);//读出一个位

u8 DHT11_Answer_Check(void);//检测是否存在DHT11

void DHT11_Rst(void);//复位DHT11


#endif



main函数

int main()
{
	uint8_t dht11_temp = 0;
	uint8_t dht11_humi = 0;
	
	Configuration();
  while(1)
	{
    DHT11_Read_Data(&dht11_temp,&dht11_humi);
     
    printf("temperature=%.0f℃,   humidness=%.0f %c",(double)dht11_temp,(double)dht11_humi,'%');		
	DelayMs(1000);
				
	}	

}

注:温湿度读取间隔不得低于2S,读取过,测量温湿度不准
如有不明之处请在下方评论区留言或加QQ:2980828094

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
驱动DHT11模块需要使用STM32的GPIO接口。以下是一个基本的流程: 1. 配置GPIO口为输出模式,并将数据线拉低至少18ms。 2. 将数据线拉高20-40us,然后将其切换到输入模式。 3. 等待DHT11向主机发送一个低电平,其持续时间约为80us。 4. 等待DHT11发送一个高电平,其持续时间约为80us。 5. 接下来,DHT11将发送40个位的数据。每个位的持续时间为50us。 6. 如果数据线保持低电平超过80us,则表示传输错误。 下面是一个简单的代码示例: ``` #define DHT11_PIN GPIO_Pin_0 #define DHT11_PORT GPIOA //等待一个特定的状态 void wait_status(uint8_t status) { uint32_t timeout = 0; while ((GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == status) && (timeout < 100)) { timeout++; delay_us(1); } } //读取DHT11数据 void read_dht11(uint8_t *data) { uint8_t i, j = 0; uint8_t byte_index = 0; uint8_t byte_value = 0; uint8_t check_sum = 0; //设置GPIO为输出模式 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = DHT11_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DHT11_PORT, &GPIO_InitStructure); //拉低至少18ms GPIO_ResetBits(DHT11_PORT, DHT11_PIN); delay_ms(18); //拉高20-40us GPIO_SetBits(DHT11_PORT, DHT11_PIN); delay_us(30); //切换到输入模式 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(DHT11_PORT, &GPIO_InitStructure); //等待DHT11发送低电平 wait_status(Bit_RESET); //等待DHT11发送高电平 wait_status(Bit_SET); //读取40个位的数据 for (i = 0; i < 40; i++) { //等待低电平结束 wait_status(Bit_RESET); //计算当前位的值 if (i % 8 == 0) { byte_value = 0; } byte_value <<= 1; if (GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == Bit_SET) { byte_value |= 0x01; } if (i % 8 == 7) { data[byte_index] = byte_value; byte_index++; } } //计算校验和 check_sum = data[0] + data[1] + data[2] + data[3]; //判断校验和是否正确 if (check_sum != data[4]) { //校验和错误 } } ``` 注意,这只是一个基本的示例代码。在实际应用中,您可能需要针对您的具体硬件和应用程序进行一些调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值