0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Openwrt开发指南 第28章 DHT11 温湿度传感器

嵌入式大杂烩 来源:嵌入式大杂烩 作者:嵌入式大杂烩 2023-07-15 16:18 次阅读

开发环境:

主机:Ubuntu12.04

开发板:RT5350

Openwrt:Openwrt15.05

1 硬件原理

下图是我们温度传感器的接入引脚,3.3V 供电,io 口接 P13 的 GP0( GPIO0 的简称 )。DHT11数字温湿度传感器 是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能 8 位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11 传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式存在OTP内存中,传感器内部在检测型号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,使其成为该类应用中,在苛刻应用场合的最佳选择。

2 DHT11 相关时序

  • 初始化(复位)时序图

1.png

  1. 控制器首先至少拉低 18ms,然后拉高 20-40us 后等待 DHT11 的应答
  2. 当 DHT11 检测到信号后,首先将总线拉低约 80us 然后在拉高 80us 作为应答信号。
  • 读取数据时序图

2.png

  • 表示 0 的时序如下

3.png

  • 表示 1 的时序如下

4.png

  1. DHT11 以低电平应答主机,然后拉高总线准备输出。输出 0 信号和 1 信号都是以低电平开始高电平结束。
  2. DHT11 输出 0、 1 信号的低电平时间相同,而高电平的时间不同,输出 0 信号时高电平约 26-28us,而当输出 1 信号时高电平约为 70us。

3 驱动程序

关于字符设备驱动程序的使用,我们可以参照点亮 led 灯的那个实验,这里只给出跟DHT11 密切相关的驱动程序,详细的程序请查看我们的驱动文件!

//配置连接温度传感器的引脚
#define DHT11_L	   	        *GPIO21_0_DATA &= ~(1< < 0)  //低电平	
#define DHT11_H		        *GPIO21_0_DATA |=  (1< < 0)  //高电平
#define DHT11_OUT	        *GPIO21_0_DIR  |=  (1< < 0)  //输出	
#define DHT11_IN		*GPIO21_0_DIR  &= ~(1< < 0)  //输入	
#define DHT11_STA		*GPIO21_0_DATA & 0x01	

//寄存器定义
volatile unsigned long *GPIO21_0_DIR;
volatile unsigned long *GPIO21_0_DATA;	


/****************  基本定义 **********************/
//初始化函数必要资源定义
//用于初始化函数当中
//device number;
	dev_t dev_num;
//struct dev
	struct cdev dht11_cdev;
//auto "mknode /dev/dht11 c dev_num minor_num"
struct class *dht11_class = NULL;
struct device *dht11_device = NULL;

/********************  dht11有关的函数   ****************************/
//从dht11中读取一个字节
static unsigned char read_byte(void)
{
	unsigned char r_val = 0; 
	unsigned char t_count = 0; //计时器,防止超时;
        unsigned char i;

	for(i = 0 ; i < 8 ; i++)
	{
		t_count = 0;
		
		while(!DHT11_STA)
		{
			udelay(1);
			t_count++;
			if(t_count >250)
			{
				printk("read_byte error1n");
				return 100;
			}
		}
		t_count = 0;

		udelay(32);

		if(DHT11_STA == 1)
		{
			r_val < <= 1;
			r_val |= 1;
		}
		else
		{
			r_val < <= 1;
			continue;
		}

		while( DHT11_STA == 1 )
		{
			udelay(2);
			t_count++;
			if(t_count >250)
			{
				printk("read_byte error2n");
				return 100;
			}
	 	 }
	}

	return r_val;
}

//从dht11中读出数据
static unsigned int read_dht11(void)
{
	 unsigned char t_count = 0; //计时器;
	 unsigned int  dht11 = 0;
	 unsigned char h_i = 0 , h_f = 0;
	 unsigned char t_i = 0 , t_f = 0;
	 unsigned char check_sum = 0;

	 DHT11_OUT;

	 DHT11_L;
	 mdelay(30); // >18ms;
	 DHT11_H;

	 udelay(30);

	 DHT11_IN;
	 while(DHT11_STA == 1)
	 {
	 	udelay(1);
		t_count++;

		if(t_count > 50)
		{
	 		printk("device error: dht11!n");
			return 0;
		}
	 }
	 t_count = 0;

 	 while(!DHT11_STA)
	 {
		udelay(1);
		t_count++;

		if(t_count > 250)
		{
			printk("read_dht11 error1n");
			return 0;
		}
	 }

	 t_count = 0;

	 udelay(50);

	 while(DHT11_STA)
	 {
		udelay(1);
		t_count++;
		if(t_count > 250)
		{
			printk("read_dht11 error2n");
			return 0;
		}
	 }

	 h_i = read_byte();
	 h_f = read_byte();
	 t_i = read_byte();
	 t_f = read_byte();
	 check_sum = read_byte();

	 if(check_sum == (h_i+h_f+t_i+t_f) || (h_i!=100 && t_i != 100))
	 {
		dht11 = t_i;
		dht11 < <= 8;
		dht11 += h_i;
	 }
	 else
	 {
		dht11 = 0;
		printk("read_dht11 error3n");
	 }

	 return dht11;
}


/**********************************************************************/

/**************** 结构体 file_operations 成员函数 *****************/
//open
static int dht11_open(struct inode *inode, struct file *file)
{
	printk("dht11 drive open...n");

	DHT11_OUT;
	DHT11_H;

	return 0;
}

//close
static int dht11_close(struct inode *inode , struct file *file)
{
	return 0;
}

//read
static ssize_t dht11_read(struct file *file, char __user *buffer,
			size_t len, loff_t *pos)
{
	unsigned int dht11; 
	printk("dht11 drive read...n");

	dht11 = read_dht11();
	copy_to_user(buffer, &dht11, 4);

	return 4;
}



/***************** 结构体: file_operations ************************/
//struct
static const struct file_operations dht11_fops = {
	.owner   = THIS_MODULE,
	.open	 = dht11_open,
	.release = dht11_close,	
	.read	 = dht11_read,
};


/*************  functions: init , exit*******************/
//条件值变量,用于指示资源是否正常使用
unsigned char init_flag = 0;
unsigned char add_code_flag = 0;

//init
static __init int dht11_init(void)
{
	int ret_v = 0;
	printk("dht11 drive init...n");

	//函数alloc_chrdev_region主要参数说明:
	//参数2: 次设备号
	//参数3: 创建多少个设备
	if( ( ret_v = alloc_chrdev_region(&dev_num,0,1,"dht11") ) < 0 )
	{
		goto dev_reg_error;
	}
	init_flag = 1; //标示设备创建成功;

	printk("The drive info of dht11:nmajor: %dnminor: %dn",
		MAJOR(dev_num),MINOR(dev_num));

	cdev_init(&dht11_cdev,&dht11_fops);
	if( (ret_v = cdev_add(&dht11_cdev,dev_num,1)) != 0 )
	{
		goto cdev_add_error;
	}

	dht11_class = class_create(THIS_MODULE,"dht11");
	if( IS_ERR(dht11_class) )
	{
		goto class_c_error;
	}

	dht11_device = device_create(dht11_class,NULL,dev_num,NULL,"dht11");
	if( IS_ERR(dht11_device) )
	{
		goto device_c_error;
	}
	printk("auto mknod success!n");

	//------------   请在此添加您的初始化程序  --------------//
       

	GPIO21_0_DATA = (volatile unsigned long *)ioremap(0x10000620, 4);
	GPIO21_0_DIR =  (volatile unsigned long *)ioremap(0x10000624, 4);

        //如果需要做错误处理,请:goto dht11_error;	

	 add_code_flag = 1;
	//----------------------  END  ---------------------------// 

	goto init_success;

dev_reg_error:
	printk("alloc_chrdev_region failedn");	
	return ret_v;

cdev_add_error:
	printk("cdev_add failedn");
 	unregister_chrdev_region(dev_num, 1);
	init_flag = 0;
	return ret_v;

class_c_error:
	printk("class_create failedn");
	cdev_del(&dht11_cdev);
 	unregister_chrdev_region(dev_num, 1);
	init_flag = 0;
	return PTR_ERR(dht11_class);

device_c_error:
	printk("device_create failedn");
	cdev_del(&dht11_cdev);
 	unregister_chrdev_region(dev_num, 1);
	class_destroy(dht11_class);
	init_flag = 0;
	return PTR_ERR(dht11_device);

//------------------ 请在此添加您的错误处理内容 ----------------//
dht11_error:
	add_code_flag = 0;
	return -1;
//--------------------          END         -------------------//
    
init_success:
	printk("dht11 init success!n");
	return 0;
}

//exit
static __exit void dht11_exit(void)
{
	printk("dht11 drive exit...n");	

	if(add_code_flag == 1)
 	{   
           //----------   请在这里释放您的程序占有的资源   ---------//
	    printk("free your resources...n");	               

		iounmap(GPIO21_0_DATA);
		iounmap(GPIO21_0_DIR);

	    printk("free finishn");		               
	    //----------------------     END      -------------------//
	}					            

	if(init_flag == 1)
	{
		//释放初始化使用到的资源;
		cdev_del(&dht11_cdev);
 		unregister_chrdev_region(dev_num, 1);
		device_unregister(dht11_device);
		class_destroy(dht11_class);
	}
}

/**************** module operations**********************/
//module loading
module_init(dht11_init);
module_exit(dht11_exit);

//some infomation
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("from Jafy");
MODULE_DESCRIPTION("dht11 drive");
/*********************  The End ***************************/

4 应用程序

int main(int argc, char **argv)
{
	int fd;
	unsigned int dht11 = 0;
	unsigned int humi,temp;

	//打开温度传感器驱动模块
	fd = open("/dev/dht11", O_RDWR | O_NONBLOCK);
	if (fd < 0)
	{
		printf("can't open /dev/dht11n");
		return -1;
	}

	read(fd, &dht11, sizeof(dht11));

	temp = dht11 >>8;
	humi = dht11 &0x000000ff;
	printf("the current temperature is: %dn",temp);
	printf("the current humidity is:    %dn",humi);

	close(fd);
	
	return 0;
}

5 实验结果

5.png
审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 传感器
    +关注

    关注

    2545

    文章

    50384

    浏览量

    750658
  • 温湿度传感器

    关注

    5

    文章

    571

    浏览量

    35627
  • 开发板
    +关注

    关注

    25

    文章

    4874

    浏览量

    96972
  • OpenWrt
    +关注

    关注

    10

    文章

    126

    浏览量

    39239
  • DHT11
    +关注

    关注

    19

    文章

    276

    浏览量

    57507
收藏 人收藏

    评论

    相关推荐

    基于arduino的dht11温湿度传感器的使用

    本文介绍了DHT11温湿度传感器电气特性、DHT11封装形式及接口说明与典型应用电路,其次介绍了DHT11
    发表于 01-22 15:50 4.4w次阅读
    基于arduino的<b class='flag-5'>dht11</b><b class='flag-5'>温湿度</b><b class='flag-5'>传感器</b>的使用

    Arduino开发板使用DHT11温湿度传感器的方法 精选资料分享

    在本篇文章中,我们将DHT11温湿度传感器与Arduino开发板和LCD显示屏连接,设计一种能够测量室温和环境湿度的设备。简单地说,我们将使
    发表于 07-13 09:35

    Arduino开发板使用DHT11温湿度传感器的方法 精选资料分享

    在本篇文章中,我们将DHT11温湿度传感器与Arduino开发板和LCD显示屏连接,设计一种能够测量室温和环境湿度的设备。简单地说,我们将使
    发表于 07-13 06:58

    DHT11温湿度传感器介绍

    DHT11温湿度传感器介绍,1.实物原理图2.模块说明2.1 DHT11产品概述DHT11数字温湿度
    发表于 07-21 09:04

    使用DHT11温湿度传感器

    STM32F407ZGT6开发板进行项目开发,选用的传感器为常见通用的DHT11温湿度传感器
    发表于 08-10 06:14

    DHT11温湿度传感器

    DHT11温湿度传感器1. DHT11简介2. 硬件设计3. 软件设计3.1 STM32CubeMX设置3.2 MDK-ARM编程4. 下载验证
    发表于 08-11 06:04

    如何使用nodemcu开发板与DHT11温湿度传感器获取温湿度数值?

    如何使用nodemcu开发板与DHT11温湿度传感器获取温湿度数值?
    发表于 10-28 06:12

    dht11温湿度传感器有什么特点?怎么使用?

    dht11温湿度传感器特点及使用介绍前言一、dht11温湿度传感器外观二、原理图三、相关参数讲解
    发表于 01-10 06:27

    如何使用STM32F4来读取DHT11数字温湿度传感器

    数字温湿度传感器实验上一,我们介绍了数字温度传感器 DS18B20 的使用,本章我们将介绍数字温湿度
    发表于 02-09 07:50

    DHT11温湿度传感器简介

    DHT11温湿度传感器1、DHT11简介DHT11数字温湿度
    发表于 02-16 06:55

    DHT11数字温湿度传感器产品介绍

    DHT11数字温湿度传感器产品介绍 DHT11数字温湿度传感器是一款含有已校准数字信号输出的
    发表于 02-26 17:19 256次下载

    DHT11数字式温湿度传感器的应用性研究

    基于DHT11温湿度传感器具有测量精度高、响应速度快、抗干扰能力强等优点。通过介绍DHT11数字式温湿度
    发表于 07-25 17:03 216次下载
    <b class='flag-5'>DHT11</b>数字式<b class='flag-5'>温湿度</b><b class='flag-5'>传感器</b>的应用性研究

    温湿度DHT11资料

    温湿度DHT11资料汇总 DHT11是一款有已校准数字信号输出的温湿度传感器。 其精度湿度+-5
    发表于 11-29 17:28 27次下载

    数字温湿度传感器 DHT11

    数字温湿度传感器 DHT11 ►相对湿度和温度测量 ►全部校准,数字输出 ►卓越的长期稳定性 ►无需额外部件 ►超长的信号传输距离 ►超低能耗 ►4 引脚安装 ►完全互换
    发表于 12-02 11:06 4次下载

    使用ESP8266驱动DHT11温湿度传感器

    DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度综合传感器,在Arduino提高篇中已对其进行了介绍,本篇使用ESP8266来
    的头像 发表于 05-19 14:20 6109次阅读
    使用ESP8266驱动<b class='flag-5'>DHT11</b><b class='flag-5'>温湿度</b><b class='flag-5'>传感器</b>