第九篇,温湿度传感器(DHT11)编程

1.原理图

DHT11使用单总线通信,使用一根数据线进行传输,再加上VCC,GND,闲置接口(NC),一共四根线。

数据线连接到了CPU的PG9,外接上拉电阻。

2.查看DHT11的说明手册了解其如何工作

 数据格式:

通信时序:

CPU发送起始信号 ===> DTH11响应起始信号 ===> DHT11发回温湿度数据

(1)CPU发送起始信号和模块响应

(2)如何传输1位数据

 

3.代码实现

(1)起始信号和模块响应

说明一下这段代码的写法:

//等待拉低
    while(DQ_IN&&retry<100){
        retry++;
        delay_us(1);
    }
    if(retry>=100)//如果没有拉低,无响应
        return 1;

逻辑或&&:表达式1 || 表达式2 || 表达式3...如果表达式1的运算结果为true,则整个表达式的结果为true,同时不会再执行后面的表达式,如果表达式1的运算结果为false,则根据表达式2的运算结果继续判断。

逻辑与||:表达式1 && 表达式2 && 表达式3...如果表达式1的运算结果为false,则整个表达式的结果为false,同时不会再执行后面的表达式,如果表达式1的运算结果为true,则根据表达式2的运算结果继续判断。
 

(2)读一位数据

(3)读取温湿度

//读1字节数据,高位先出
u8 dht11_read_byte(void)
{
	u8 i,dat = 0;
	
	//连续读取8位
	for(i=0;i<8;i++){
		dat |= dht11_read_bit()<<(7-i);
	}
	
	return dat;
}

//读取温湿度数据
//返回0表示成功,非0表示失败
//temp和humi是输出参数,输出温湿度
u8 dht11_read_data(u8 *temp,u8 *humi)
{
	u8 i,buf[5];
	
	//起始信号
	if(dht11_check()==0){
		//读取40bit数据
		for(i=0;i<5;i++){
			buf[i] = dht11_read_byte();
		}
		//验证校验和
		if(((buf[0]+buf[1]+buf[2]+buf[3])&0xff)==buf[4]){
			*humi = buf[0];
			*temp = buf[2];
			
			return 0;
		}
	}
	
	return 1;
}

//代码实现

#include <stm32f4xx.h>
#include <dht11.h>
#include <delay.h>

//配置DQ 输入模式/输出模式
void dht11_set_io(GPIOMode_TypeDef IO)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	//1.开启GPIOG的时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE);
	
	//2.GPIO初始化 PG9
	GPIO_InitStruct.GPIO_Mode = IO;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//推挽输出
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//高速
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;//无上下拉
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
	GPIO_Init(GPIOG,&GPIO_InitStruct);
}

//测试dht11是否有响应,返回0表示正常,非0表示无响应
u8 dht11_check(void)
{
	u32 retry = 0;
	
	//输出模式
	dht11_set_io(GPIO_Mode_OUT);
	//发送>18ms低电平起始信号
	DQ_OUT = 0;
	//保持20ms
	delay_ms(20);
	DQ_OUT = 1;
	
	//等待20~40us
	delay_us(30);
	
	//输入模式
	dht11_set_io(GPIO_Mode_IN);
	
	//等待拉低
	while(DQ_IN&&retry<100){
		retry++;
		delay_us(1);
	}
	if(retry>=100)//如果没有拉低,无响应
		return 1;
	
	retry = 0;
	//80us后拉高
	while(!DQ_IN&&retry<100){
		retry++;
		delay_us(1);
	}
	if(retry>=100)//如果没有拉高,无响应
		return 1;
	
	return 0;
}

//读1位数据
u8 dht11_read_bit(void)
{
	u32 retry = 0;
	
	//等待变为低电平,80us
	while(DQ_IN&&retry<100){
		retry++;
		delay_us(1);
	}
	if(retry>=100)//如果没有拉低,无响应
		return 100;
	
	retry = 0;
	//等待拉高,50us
	while(!DQ_IN&&retry<100){
		retry++;
		delay_us(1);
	}
	if(retry>=100)//如果没有拉高,无响应
		return 100;
	
	//延时40us,读取电平 低电平 ----- 0  高电平 ----- 1
	delay_us(40);
	return DQ_IN;
}

//读1字节数据,高位先出
u8 dht11_read_byte(void)
{
	u8 i,dat = 0;
	
	//连续读取8位
	for(i=0;i<8;i++){
		dat |= dht11_read_bit()<<(7-i);
	}
	
	return dat;
}

//读取温湿度数据
//返回0表示成功,非0表示失败
//temp和humi是输出参数,输出温湿度
u8 dht11_read_data(u8 *temp,u8 *humi)
{
	u8 i,buf[5];
	
	//起始信号
	if(dht11_check()==0){
		//读取40bit数据
		for(i=0;i<5;i++){
			buf[i] = dht11_read_byte();
		}
		//验证校验和
		if(((buf[0]+buf[1]+buf[2]+buf[3])&0xff)==buf[4]){
			*humi = buf[0];
			*temp = buf[2];
			
			return 0;
		}
	}
	
	return 1;
}

  • 5
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

肖爱Kun

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

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

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

打赏作者

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

抵扣说明:

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

余额充值