【STM32】DHT11温湿度模块传感器详解&代码

一、DHT11产品介绍

DHT11是数字温湿度传感器,测量范围:湿度20%-95%,温度0-50℃,广泛应用于加湿器、温湿度计、空调、汽车等领域。

二、典型应用电路

在这里插入图片描述
如上图DATA引脚用于MCU与DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右(超时时间的判断)。一次完整的数据传输为40bit,高位先出(MSB最高有效位有线传输)
数据传送正确时校验和数据等于:8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据,所得结果的末8位。
如:
湿度:60.5% 60 05
温度:26.7℃ 26 07
60+5+26+7=98
98&0xFF=98=1001 1000

三、DHT11温湿度模块的通信过程

在这里插入图片描述
四、示例代码
显示室内温度和湿度
效果图:
在这里插入图片描述

1、DHT11初始化

void dht11_init(void)
{
	//打开端口G的硬件时钟,就是供电
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE);


	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9; 	//9号引脚
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;	//输出模式
	GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;	//开漏
	GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;//高速,速度越高,响应越快,但是功耗会更高
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;//不使能上下拉电阻
	GPIO_Init(GPIOG,&GPIO_InitStructure);

	//只要有输出模式,肯定会有初始电平的状态,看连接设备的说明书
	PGout(9)=1;

}

2、

int32_t dht11_read(uint8_t *buf)
{
	uint32_t t=0;
	int32_t i=0,j=0;
	uint8_t d=0;
	uint8_t *p=buf;
	uint8_t check_sum=0;
	
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9; 	//9号引脚
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;	//输出模式
	GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;	//开漏
	GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;//高速,速度越高,响应越快,但是功耗会更高
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;//不使能上下拉电阻
	GPIO_Init(GPIOG,&GPIO_InitStructure);	
	
	PGout(9)=0;
	delay_ms(18);
	
	PGout(9)=1;
	delay_us(30);
	
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9; 	//9号引脚
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN;	//输入模式
	GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;	//开漏
	GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;//高速,速度越高,响应越快,但是功耗会更高
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;//不使能上下拉电阻
	GPIO_Init(GPIOG,&GPIO_InitStructure);
	
	//等待低电平出现
	t=0;
	while(PGin(9))
	{
		t++;
		delay_us(1);
		
		if(t >= 4000)
			return -1;
	}

	//用超时检测的方法测量低电平的合法性
	t=0;
	while(PGin(9)==0)
	{
		t++;
		delay_us(1);
		
		if(t >= 100)
			return -2;
	}	
	
	//用超时检测的方法测量高电平的合法性
	t=0;
	while(PGin(9))
	{
		t++;
		delay_us(1);
		
		if(t >= 100)
			return -3;
	}	
	
	for(j=0; j<5; j++)
	{
		//接收一个字节的数据
		for(d=0,i=7; i>=0; i--)
		{
			//用超时检测的方法测量低电平的合法性
			t=0;
			while(PGin(9)==0)
			{
				t++;
				delay_us(1);
				
				if(t >= 100)
					return -4;
			}

			//延时40us (延时时间在28us ~ 70us)
			delay_us(40);
			
			if(PGin(9))
			{
				d|=1<<i;	//将d变量对应的bit置1
				
				//等待高电平持续完毕
				t=0;
				while(PGin(9))
				{
					t++;
					delay_us(1);
					
					if(t >= 100)
						return -5;
				}			
			}
		}	
		p[j]=d;
	}
	
	//延时50us,可以忽略通讯结束的低电平
	delay_us(50);
	
	//计算校验和,检查接收到的数据是否准确
	check_sum = (p[0]+p[1]+p[2]+p[3])&0xFF;
	
	if(check_sum == p[4])
		return 0;
	
	return -6;
}

3、main函数实现

int main(void)
{
	uint8_t buf[5];
	int32_t rt;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
	
	/* 初始化串口1波特率为115200bps,若发送/接收数据有乱码,请检查PLL */
	usart1_init(115200);
	
	dht11_init();

	printf("this is dht11 test\r\n");
	
	printf("1<<6=%X \r\n",1<<6);	
	printf("1<<3=%X \r\n",1<<3);		
	
	while(1)
	{
		rt = dht11_read(buf);
		
		if( rt == 0)
		{
			printf("T:%d.%d H:%d.%d\r\n",buf[2],buf[3],buf[0],buf[1]);
		
		}
		else
		{
			printf("dht11 read error code is %d\r\n",rt);
		}

		//官方要求,每6秒
		delay_ms(6000);
	}
}
基于温度湿度一体的传感器DHT11 以下是在51单片机上测试成功的代码 #include&lt;at89x52.h&gt; #include&lt;intrins.h&gt;//加上这句下面的 _nop_();就能用 bit xianshiqiehuan; // sbit dht11_dat=P1^6; //开发板用 sbit dht11_dat=P2^0; //使用版用 unsigned char c,count, dht11temp,dht11dat; unsigned char dht11value[5]; unsigned int x,y,z; unsigned char code dat[]={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,}; delay() { unsigned char a; for(a=200;a&gt;0;a--); } display(unsigned char x) //使用版用 { P0=dat[(x0)/10];//十位 P2_3=0; delay(); P2_3=1; P0=dat[(x0)];//个位 P2_2=0; delay(); P2_2=1; } /*display(unsigned char x) //开发板用 { P0=dat[(x0)/10];//十位 P1_2=0; delay(); P1_2=1; P0=dat[(x0)];//个位 P1_3=0; delay(); P1_3=1; } */ delay_1s() { unsigned int i=50000; while(i--); } delay_10us() //10us { _nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); } void delayms(unsigned char x) //1ms单位延时程序 { unsigned char j; while(x--) { for(j=0;j&lt;123;j++){;} } } read_dht11() { unsigned char i; dht11_dat=1; _nop_(); //起始 dht11_dat=0;//拉低总线 delayms(18);//手册要求大于18ms dht11_dat=1;//拉高总线等待dht11回应 while(dht11_dat); // 等待dht11回应 若有回应 dht11_dat=0;往下执行 while(!dht11_dat);//回应后dht11将总线拉低80us,过后又将总线拉高,进入下一步 while(dht11_dat); //拉高80us 又变低,往下执行 进入50us延时 for(i=0;i&lt;24;i++) { while(!dht11_dat);//50us过后...... dht11_dat=1;往下执行 delay_10us();delay_10us();delay_10us();//延时30us,查看总线是高是低, dht11temp=0; //先默认为0处理 if(dht11_dat) dht11temp=1; //1处理 dht11dat=dht11dat&lt;&lt;1; //必须先移动再或 若先或再移本次数据就移动了 dht11dat=dht11dat|dht11temp; dht11value[i/8]=dht11dat; while(dht11_dat);//如果处理的是1,30us过后总线还是1,那就在此等待总线变为0进入下一个50us低电平,不然会重复进行0处理 } } main() { delay_1s(); //要求上电等1秒,让dht11稳定 EA=1;//开放中断 TMOD=0x01;//设T0 为16位计数方式 ET0=1;//定时0中断允许 TR0=1;//开启TR0 while(1) { if(!xianshiqiehuan) //显示温度 display(dht11value[2]) ; else {display(dht11value[0]) ; //显示湿度 P0=0x92&amp;0x7f; //千位显 S.代表湿度 P2_5=0; delay(); P2_5=1; } } } dingshi() interrupt 1 //定时器0服务程序 { TH0=0; TL0=0; count++; if(count==55){count=0;read_dht11();xianshiqiehuan=~xianshiqiehuan; } //在切换显示时采集,以防中断采样带来的显示闪烁 }
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

老K聊技术

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

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

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

打赏作者

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

抵扣说明:

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

余额充值