DTH11 温湿度模块

文章目录

  • 前言
  • 一、DTH11 模块介绍
  • 二、设备树设置
  • 三、驱动程序
  • 四、测试程序
  • 五、上机测试及效果
  • 总结


前言

DHT11 是一款可测量 温度 和 湿度 的传感器。比如市面上一些空气加湿器,会测量空气中湿度,再根据测量结果决定是否继续加湿。


一、DTH11 模块介绍

在这里插入图片描述

  1. DHT11通信过程:
    主机通过一条数据线与DH11连接,主机通过这条线发命令给DHT11,DHT11再通过这条线把数据发送给主机。
    当主机没有与DHT11通信时,总线处于空闲状态,此时总线电平由于上拉电阻的作用处于高电平。
  • 主机将对应的GPIO管脚配置为输出,准备向DHT11发送数据;
  • 主机发送一个开始信号:
    开始信号 = 一个低脉冲 + 一个高脉冲。低脉冲至少持续18ms,高脉冲持续20-40us。
  • 主机将对应的GPIO管脚配置为输入,准备接受DHT11传来的数据,这时信号由上拉电阻拉高;
  • DHT11发出响应信号:
    响应信号 = 一个低脉冲 + 一个高脉冲。低脉冲持续80us,高脉冲持续80us。
  • DHT11发出数据信号:
    数据为0的一位信号 = 一个低脉冲 + 一个高脉冲。低脉冲持续50us,高脉冲持续26~28us。
    数据为1的一位信号 = 一个低脉冲 + 一个高脉冲。低脉冲持续50us,高脉冲持续70us。
    DHT11发出结束信号:
  • 最后1bit数据传送完毕后,DHT11拉低总线50us,然后释放总线,总线由上拉电阻拉高进入空闲状态。
    在这里插入图片描述
  1. 数据格式:
    8 bit 湿度整数数据 + 8 bit 湿度小数数据 + 8 bit 温度整数数据 + 8 bit 温度小数数据 + 8 bit 校验和。(5 字节数据,共 40 位 )
    数据传送正确时,校验和等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。

二、设备树设置

设备树 中 compatible 与 驱动程序 进行匹配。
将模块分别接到 开发板的 gpio4-19引脚。每一组 GPIO 有 32 个引脚。

配置设备树需要对 GPIO 引脚 以及相关的 pincontrol 配置。由于本实验是使用 DTH11 模块,所以不需要配置 pincontrol 。
在这里插入图片描述

三、驱动程序

  1. 根据框架编写基本驱动程序:

首先要 定义一个file_operations 结构体,在入口函数里对其 注册,在 出口函数里卸载。 实现辅助信息,使用 class_create 创建类 , device_create 创建设备节点。

定义一个 platform_driver。也是在入口函数里对其 注册,在 出口函数里卸载。
这些基本代码的详细实现可以参考我之前的文章 :SR501人体红外模块

  1. 实现 probe 函数。
    总线处于空闲状态,此时总线电平由于上拉电阻的作用处于高电平。
static int dht11_probe(struct platform_device *pdev)
{/* 获取引脚信息,将其设置为输出引脚高电平 */dht11_data_pin = gpiod_get(&pdev->dev, NULL, GPIOD_OUT_HIGH);if (IS_ERR(dht11_data_pin)){printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);}/* 创建设备节点 */device_create(dht11_class, NULL, MKDEV(major, 0), NULL, "mydht11");return 0;
}
  1. 首先将 gpio 引脚设置为 输出引脚,准备向 DTH11 发送数据。
static void dht11_reset(void)
{gpiod_direction_output(dht11_data_pin, 1);
}
  1. 然后主机发送一个开始信号。
    发送开始 信号完毕,将 引脚设置为 输入引脚,等待 DHT11 发送数据,准备接收数据。
static void dht11_start(void)
{mdelay(30);gpiod_set_value(dht11_data_pin, 0);mdelay(20);gpiod_set_value(dht11_data_pin, 1);udelay(40);	gpiod_direction_input(dht11_data_pin);		udelay(2);	
}
  1. DHT11 发出响应信号,之后发送数据。
static int dht11_wait_for_ready(void)
{int timeout_us = 20000;					//设置超时时间/* 等待低电平 */while (gpiod_get_value(dht11_data_pin) && --timeout_us){udelay(1);}if (!timeout_us){printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return -1;}/* 现在是低电平,等待高电平 */timeout_us = 200;while (!gpiod_get_value(dht11_data_pin) && --timeout_us){udelay(1);}if (!timeout_us){printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return -1;}/*  现在是高电平,等待低电平 */timeout_us = 200;while (gpiod_get_value(dht11_data_pin) && --timeout_us){udelay(1);}if (!timeout_us){printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return -1;}return 0;	
}
  1. 读一字节的数据。
    每字节八位数据,按位读取。
    怎么判断读出的数据是 0 还是 1 呢?
    通过判断高电平的持续时间可 得出写入的数据。当 高电平 持续26~28us,表示输出 0 。高脉冲持续70us,表明数据是 1 .
    在这里插入图片描述
static int dht11_read_byte(unsigned char *buf)
{int i;unsigned char data = 0;int timeout_us = 200;for (i = 0; i <8; i++){/* 现在是低电平 *//* 等待高电平 */timeout_us = 400;while (!gpiod_get_value(dht11_data_pin) && --timeout_us){udelay(1);}if (!timeout_us){printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return -1;}/* 现在是高电平 *//* 等待低电平,累加高电平的时间 */timeout_us = 20000000;udelay(40);if (gpiod_get_value(dht11_data_pin)){/* get bit 1 */data = (data << 1) | 1;/* 当前位的高电平未结束, 等待 */timeout_us = 400;while (gpiod_get_value(dht11_data_pin) && --timeout_us){udelay(1);}if (!timeout_us){printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return -1;}}else{/* get bit 0 */data = (data << 1) | 0;}}*buf = data;return 0;
}
  1. 读五字节数据。
    将 读出的数据放入数组中,传递给应用程序。
static ssize_t dht11_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{unsigned long flags;int i,err;unsigned char data[5];if (size != 4)return -EINVAL;local_irq_save(flags);	  // 关中断/* 1. 发送高脉冲启动DHT11 */dht11_reset();dht11_start();/* 2. 等待DHT11就绪 */if (dht11_wait_for_ready()){local_irq_restore(flags); // 恢复中断printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return -EAGAIN;}/* 3. 读5字节数据 */for (i = 0; i < 5; i++){if (dht11_read_byte(&data[i])){local_irq_restore(flags); // 恢复中断printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);return -EAGAIN;}}dht11_reset();local_irq_restore(flags); // 恢复中断/* 4. 根据校验码验证数据 */if (data[4] != (data[0] + data[1] + data[2] + data[3])){printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);//return -1;}/* 5. copy_to_user */	/* data[0]/data[1] : 湿度 *//* data[2]/data[3] : 温度 */err = copy_to_user(buf, data, 4);return 4;
}

四、测试程序

判断参数,打开文件,read 函数读出 测出的温度,湿度。

	if (argc != 2) {printf("Usage: %s <dev>\n", argv[0]);return -1;}fd = open(argv[1], O_RDWR);			if (fd == -1){printf("can not open file %s\n", argv[1]);return -1;}while (1){if (read(fd, data, 4) == 4){printf("get humidity  : %d.%d\n", data[0], data[1]);printf("get temprature: %d.%d\n", data[2], data[3]);}else {printf("get humidity/temprature: -1\n");}sleep(5);				// 等待 5 秒}close(fd);

五、上机测试及效果

执行 insmod 命令可以将 .ko 文件加载到内核中,再 执行测试程序。(rmmod命令可以卸载已加载的模块,lsmod 命令 可以观察已加载到内核的文件。)
在这里插入图片描述
/dev/mydht11 是 驱动程序中创建的设备节点( device_create )。在这里插入图片描述


总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/8200.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iOS 单元测试之常用框架 OCMock 详解

目录 前言&#xff1a; 一、单元测试 1.1 单元测试的必要性 1.2 单元测试的目的 - 约束条件是否通过形式参数来传送。 1.3 单元测试依赖的两个主要框架 二、OCMock 的集成与使用 2.1 OCMock 的集成方式 2.2 OCMock 的使用方法 2.3 mock 使用限制 前言&#xff1a; OC…

【unity】ShaderGraph学习笔记

【unity】ShaderGraph学习笔记 创建ShaderGraph 创建URP的shaderGraph文件 在Project面板里Create→ShaderGraph→URP→这里主要有几个选项 Lit Shader Graph&#xff1a;有光照三维着色器 Unlit Shader Graph&#xff1a;无光照三维着色器 Sprite Custom Lit Shader Gra…

CNN(卷积神经网络)的实现过程详解

概要 在图像处理领域&#xff0c;CNN(卷积神经网络)处于绝对统治地位&#xff0c;但对于CNN具体是如何用神经网络实现的&#xff0c;能找到的介绍要么是一大堆数学公式&#xff0c;要么是大段晦涩的文字说明&#xff0c;读起来很是辛苦&#xff0c;想写好一片完整的而且有深度的…

【开源项目】低代码数据可视化开发平台-Datav

Datav 基本介绍 Datav是一个Vue3搭建的低代码数据可视化开发平台&#xff0c;将图表或页面元素封装为基础组件&#xff0c;无需编写代码即可完成业务需求。 它的技术栈为&#xff1a;Vue3 TypeScript4 Vite2 ECharts5 Axios Pinia2 在线预览 账号: admin 密码: 123123预…

Spring Cloud+Spring Boot+Mybatis+uniapp+前后端分离实现知识付费平台免费搭建

Java版知识付费-轻松拥有知识付费平台 多种直播形式&#xff0c;全面满足直播场景需求 公开课、小班课、独立直播间等类型&#xff0c;满足讲师个性化直播场景需求&#xff1b;低延迟、双向视频&#xff0c;亲密互动&#xff0c;无论是互动、答疑&#xff0c;还是打赏、带货、…

RocketMq 事务消息原理

Rocketmq 事务消息API使用 使用TransactionMQProducer类。 实现TransactionListener 接口覆盖其方法executeLocalTransaction和checkLocalTransaction 即可。 其中executeLocalTransaction 执行本地方法和checkLocalTransaction 事务状态回查。 玩法 简历一张本地事务表&…

回归预测 | MATLAB实现TCN-BiGRU时间卷积双向门控循环单元多输入单输出回归预测

回归预测 | MATLAB实现TCN-BiGRU时间卷积双向门控循环单元多输入单输出回归预测 目录 回归预测 | MATLAB实现TCN-BiGRU时间卷积双向门控循环单元多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 ![6 基本介绍 1.MATLAB实现TCN-BiGRU时间卷积双向门控循…

实现基于UDP简易的英汉词典

文章目录 实现目标认识相关接口socketbzerobindrecvfromsendto 实现思路和注意事项完整代码Server.hppServer.ccClient.hppClient.cc 运行效果END 实现目标 实现一个服务端和一个客户端&#xff0c;客户端负责发送一个单词&#xff0c;服务端接收到后将翻译后的结果返回发送到…

Android 之 动画合集之帧动画

本节引言&#xff1a; 从本节开始我们来探究Android中的动画&#xff0c;毕竟在APP中添加上一些动画&#xff0c;会让我们的应用变得 很炫&#xff0c;比如最简单的关开Activity&#xff0c;当然自定义控件动画肯定必不可少啦~而Android中的动画 分为三大类&#xff0c;逐帧动画…

了解uuid

目录 一.认识 UUID 二.UUID 会耗尽吗 三.UUID 会重复吗 四.UUID 的版本 五.UUID的应用 六.java 如何生成UUID 一.认识 UUID uuid是经过特定的算法得到的. UUID 是 16 字节 128 位长的数字&#xff0c;通常以 36 字节的字符串表示&#xff0c;示例如下&#xff1a; 3F2…

boardmix AI:让工作效率翻倍的AI智能在线白板软件!

随着ChatGPT热度的飙升&#xff0c;AI逐步深入到各个领域&#xff0c;尤其在技术领域&#xff0c;引发了一场AI的新浪潮&#xff0c;人们谈论的焦点都与AI有关。 AI工具不仅帮助企业节约了成本&#xff0c;还极大提高了生产力。那些尚未融入AI的行业和产品&#xff0c;有着被AI…

OSI 和 TCP/IP 网络分层模型详解(基础)

OSI模型: 即开放式通信系统互联参考模型&#xff08;Open System Interconnection Reference Model&#xff09;&#xff0c;是国际标准化组织&#xff08;ISO&#xff09;提出的一个试图使各种计算机在世界范围内互连为网络的标准框架&#xff0c;简称OSI。 OSI 七层模型 OS…

Windows环境部署安装Chatglm2-6B-int4

chatglm2-6B是最近比较火爆的大模型&#xff0c;可以在消费级显卡上部署使用&#xff0c;适合学习。但是一般人也不一定有那么高的硬件配置&#xff0c;所以部署个int4版本应该是大多数人的最好选择。我就在家里部署起了int4版本的chatglm2-6B&#xff0c;记录一下免得忘了。 …

【AST抽象语法树】结构分析及特性

什么是AST? AST译名抽象语法树&#xff08;Abstract Syntax Tree&#xff09;&#xff0c;是一种用于表示源代码结构的数据结构。 它在编译器、解析器和静态代码分析等领域中被广泛使用。 AST结构分析 我们利用成熟的astexplorer来进行结构化的比较和分析。可以尝试登录以下网…

树 - 前缀树(Trie Tree)

树 - 前缀树(Trie Tree&#xff09; 什么是前缀树前缀树的实现节点数据结构定义插入方法●非递归方式●递归方式 查询单词方法●非递归方式●递归方式 查询前缀方法●非递归方式●递归方式 前缀树的复杂度前缀树有哪些应用前缀树的压缩&#xff1a;基数树双数组Trie树(DoubleAr…

探讨ChatGPT的强化学习:AI学习与交互的未来

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

ES6基础知识八:你是怎么理解ES6中Proxy的?使用场景?

一、介绍 定义&#xff1a; 用于定义基本操作的自定义行为 本质&#xff1a; 修改的是程序默认形为&#xff0c;就形同于在编程语言层面上做修改&#xff0c;属于元编程(meta programming) 元编程&#xff08;Metaprogramming&#xff0c;又译超编程&#xff0c;是指某类计算…

ChatGPT和搜索引擎哪个更好用

目录 ChatGPT和搜索引擎的概念 ChatGPT和搜索引擎的作用 ChatGPT的作用 搜索引擎的作用 ChatGPT和搜索引擎哪个更好用 总结 ChatGPT和搜索引擎的概念 ChatGPT是一种基于对话的人工智能技术&#xff0c;而搜索引擎则是一种用于在互联网上查找和检索信息的工具。它们各自具…

kaggle新赛:Bengali.AI 语音识别大赛赛题解析

赛题名称&#xff1a;Bengali.AI Speech Recognition 赛题链接&#xff1a;https://www.kaggle.com/competitions/bengaliai-speech 赛题背景 竞赛主办方 Bengali.AI 致力于加速孟加拉语&#xff08;当地称为孟加拉语&#xff09;的语言技术研究。Bengali.AI 通过社区驱动的…

7p透明屏的制造过程复杂琐屑吗?

7p透明屏是一种新型的显示技术&#xff0c;它可以使屏幕变得透明&#xff0c;让用户可以透过屏幕看到背后的物体。这种技术在科幻电影中经常出现&#xff0c;但现在已经成为现实。 7p透明屏的工作原理是利用液晶显示技术和透明材料。液晶显示技术是一种通过控制液晶分子的排列…