温湿度传感器DHT11数据手册详解(Linux内核驱动)

本文详细介绍了如何在树莓派4B上驱动DHT11温湿度传感器,包括通信时序、数据读取方法以及内核驱动和测试代码的实现。通过拉低DHT11的DQ引脚启动通信,读取响应信号和数据位,确保数据校验正确,最终获取温度和湿度值。
摘要由CSDN通过智能技术生成

一、引脚说明

在这里插入图片描述

二、时序解读

2.1、通信过程

在这里插入图片描述

2.2、开始信号

主机发送一个大于18ms的低电平给DHT11作为启动信号。
然后拉高20-40us后读DHT11响应信号。
在这里插入图片描述
发开始信号

	DHT11_IO_OUT(); 	//SET OUTPUT
    DHT11_OUT_LOW(); 	//拉低DQ
    delay_ms(5);    	//拉低至少18ms
    delay_ms(5);
    delay_ms(5);
    delay_ms(5);
    DHT11_OUT_HIGH(); 	//DQ=1 
	delay_us(30);     	//主机拉高20~40us

2.3、响应信号

DHT11检测到开始信号后,会等待开始信号结束,然后发送响应信号
响应信号为一个80us的低电平
响应信号发送后,会拉高80us,然后发送数据。
在这里插入图片描述
读响应信号

	DHT11_IO_IN();//SET INPUT	 
    while (DHT11_IN_LEVEL() == 0 && retry<100)//DHT11会拉低80us
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=100)return 0;
	else retry=0;

2.4、一位数据的表示

一个位数据总是从50us的低电平开始,高电平持续时间不同表示0和1

2.4.1、数字0信号

高电平持续26-28us表示0
在这里插入图片描述

2.4.2、数字1信号

高电平持续70us表示0
在这里插入图片描述

2.4.3、读取一位数据

低电平结束后,延时大于28us(小于28+50us,要在下一个高电平来之前读取数据),主机读取当前电平,读到高电平表示DHT11发送数据1,读到低电平表示DHT11发送数据0

	while(DHT11_IN_LEVEL())//等待变为低电平
	{

	}
 
	while(!DHT11_IN_LEVEL())//等待变高电平
	{

	}
	delay_us(40);//等待40us
	return DHT11_IN_LEVEL();   

三、树莓派4B内核驱动代码(部分代码)

使用GPIO25


#define delay_us(x) udelay(x);
#define delay_ms(x) mdelay(x);

#define DHT11_IO_OUT() *GPFSEL2 &= ~(0x6 << 15);\
                        *GPFSEL2 |= (0x1 << 15);

#define DHT11_IO_IN() *GPFSEL2 &= ~(0x7 << 15);\
                        *GPFSEL2 |= (0x0 << 15); 

#define DHT11_OUT_HIGH() *GPSET0 = 1 << 25; 
#define DHT11_OUT_LOW() *GPCLR0 = 1 << 25;  

#define DHT11_IN_LEVEL() ((*GPLEV0>>25) & 1)


static unsigned char DHT11_Read_Bit(void) 			 
{

	while(DHT11_IN_LEVEL())//等待变为低电平
	{

	}
 
	while(!DHT11_IN_LEVEL())//等待变高电平
	{

	}
	delay_us(40);//等待40us
	return DHT11_IN_LEVEL();   
}

//从DHT11读取一个字节
static unsigned char DHT11_Read_Byte(void)    
{        
    unsigned char i,dat;
    dat=0;
	for (i=0;i<8;i++) 
	{
   		dat<<=1; 
	    dat|=DHT11_Read_Bit();
    }						    
    return dat;
}

static unsigned char DHT11_Read_Data(unsigned char *temp,unsigned char *humi)    
{        
 	unsigned char buf[5];
	unsigned char i;
    unsigned char retry=0;

	DHT11_IO_OUT(); 	//SET OUTPUT
    DHT11_OUT_LOW(); 	//拉低DQ
    delay_ms(5);    	//拉低至少18ms
    delay_ms(5);
    delay_ms(5);
    delay_ms(5);
    DHT11_OUT_HIGH(); 	//DQ=1 
	delay_us(30);     	//主机拉高20~40us

	
	DHT11_IO_IN();//SET INPUT	 
    while (DHT11_IN_LEVEL() == 0 && retry<100)//DHT11会拉低80us
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=100)return 0;
	else retry=0;

	if(retry==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 0;
	return 1;	    
}



四、测试代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
    char data[2];
    int nread = 0;

    int fd = open("/dev/dht11",O_RDWR);
    if(fd == -1){
        perror("open ");
        exit(-1);
    }

    while(1){
        getchar();
        nread = read(fd,data,2);
        printf("nread :%d  temp=%d humi=%d\n",nread,data[0],data[1]);
    }
    


}

DHT11 Linux内核驱动完整代码(树莓派4B)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值