Linux内核驱动——DHT11 温湿度传感器驱动实现
目录一、DHT11 传感器基础概念1.1 硬件特性1.2 数据格式1.3 通信时序1.3.1 起始信号主机→从机1.3.2 从机响应从机→主机1.3.3 数据位传输从机→主机二、内核驱动程序实现2.1 设备树配置2.2 驱动架构设计2.3 核心函数拆解2.3.1 起始信号发送2.3.2 从机响应检测2.3.3 单比特读取2.3.4 40位数据读取2.3.5 文件操作接口2.3.6 Platform 驱动初始化2.4 驱动入口 / 出口三、应用层程序开发四、总结一、DHT11 传感器基础概念1.1 硬件特性DHT11是一款经济实用的数字温湿度传感器广泛应用于智能家居、环境监测等场景。其核心特性包括测量范围湿度 20-90%RH±5%RH 精度温度 0-50℃±2℃ 精度通信接口单总线Single-Wire协议仅需1根数据线响应速度采样周期不小于2秒硬件限制输出格式40 位数字信号无需 AD 转换直接解析时序即可采样频率最高 1Hz即每秒最多读取 1 次过快会导致数据错误。实物图dht11实物图电路图dht11电路图1.2 数据格式DHT11 每次输出 40 位5 字节数据字节含义如下字节序号含义备注第 1 字节湿度整数部分0~99第 2 字节湿度小数部分DHT11 固定为 0无小数第 3 字节温度整数部分0~50第 4 字节温度小数部分DHT11 固定为 0第 5 字节校验和 字节 1 字节 2 字节 3 字节 41.3 通信时序DHT11 的单总线通信由Linux 内核主动发起分为起始信号、从机响应、数据位传输三个阶段时序逻辑如下1.3.1 起始信号主机→从机主机将 DATA 线GPIO设为输出模式先拉高 2ms稳定电平拉低 DATA 线至少 18ms拉高 DATA 线 20~40us完成起始信号发送。1.3.2 从机响应从机→主机从机检测到起始信号后主动拉低 DATA 线 80us再拉高 DATA 线 80us作为 “响应成功” 的标识主机需切换 GPIO 为输入模式检测这两段电平超时则通信失败。起始信号与从机响应1.3.3 数据位传输从机→主机响应完成后从机逐位发送 40 位数据通过高电平时长区分 0/1发送 0拉低 DATA 线 50us → 拉高 26~28us发送 1拉低 DATA 线 50us → 拉高 70us主机通过检测高电平时长判断当前位是 0 还是 1。发送0信号发送1信号二、内核驱动程序实现2.1 设备树配置在设备树中添加 /dht11 节点。dht11 { #address-cells 1; #size-cells 1; compatible pt-dht11; pinctrl-names default; pinctrl-0 pinctrl_ptdht11; ptdht11-gpio gpio1 2 GPIO_ACTIVE_HIGH; status okay; }; pinctrl_ptdht11: ptdht11grp { fsl,pins MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0x10B0 ; };2.2 驱动架构设计本驱动采用Linux标准的Platform Driver Misc Device架构Platform 驱动适配设备树解析 GPIO 配置实现驱动与硬件解耦Misc 杂项设备简化字符设备注册快速生成 /dev/dht11 设备文件。// 驱动核心结构 static struct platform_driver pdrv { .probe probe, .remove remove, .driver { .name dht11, .of_match_table dht11_table // 支持设备树匹配 } }; // 杂项设备注册 static struct miscdevice misc_dev { .minor MISC_DYNAMIC_MINOR, // 动态分配次设备号 .name dht11, .fops fops // 文件操作接口 };2.3 核心函数拆解2.3.1 起始信号发送通过 gpio_set_value 控制电平msleep(20) 确保满足 DHT11 要求的 ≥18ms 低电平udelay(20) 精确控制 20-40μs 高电平窗口。static void dht11_start(void) { gpio_direction_output(dht11_gpio, 1); // GPIO设为输出初始拉高 mdelay(2); // 稳定电平2ms gpio_set_value(dht11_gpio, 0); // 拉低20ms msleep(20); gpio_set_value(dht11_gpio, 1); // 拉高20us完成起始 udelay(20); }2.3.2 从机响应检测DHT11响应信号包含 80μs 低 80μs 高需分三阶段检测超时返回不同错误码便于调试。static int dht11_wait_respon(void) { int time 0; gpio_direction_input(dht11_gpio); // 切换为输入模式 // 跳过主机起始后的高电平 time 30; while(gpio_get_value(dht11_gpio) time--) udelay(1); if(time 0) return -1; // 检测从机响应的低电平 time 100; while((!gpio_get_value(dht11_gpio)) time--) udelay(1); if(time 0) return -2; // 检测从机响应的高电平 time 100; while(gpio_get_value(dht11_gpio) time--) udelay(1); if(time 0) return -3; return 0; // 响应成功 }2.3.3 单比特读取在 50μs 低电平结束后延时 35μs 采样——此时 0 已结束26-28μs1 仍为高电平70μs实现可靠判别。static char dht11_get_bit(void) { int time 60; // 等待从机拉低的50us while(gpio_get_value(dht11_gpio) time--) udelay(1); if(time 0) return -4; // 检测从机拉低的电平 time 80; while((!gpio_get_value(dht11_gpio)) time--) udelay(1); if(time 0) return -5; // 延时35us区分0/1 udelay(35); if(!gpio_get_value(dht11_gpio)) return 0; // 高电平已结束是0 // 等待1的高电平结束 time 50; while(gpio_get_value(dht11_gpio) time--) udelay(1); if(time 0) return -6; return 1; }2.3.4 40位数据读取逐位拼接成字节最终生成 5 字节完整数据。static int dht11_read_data(unsigned char * data) { int i 0, j 0; for(j 0; j 5; j) // 读取5字节 { for(i 0; i 8; i) // 每字节8位 { char bit dht11_get_bit(); if(bit 0) return bit; // 位读取失败返回错误码 data[j] 1; // 左移1位腾出最低位 data[j] | bit; // 填充当前位 } } return 5; // 读取成功返回字节数 }2.3.5 文件操作接口串联时序函数完成数据读取通过 copy_to_user 实现内核态→用户态的数据传递。static ssize_t read(struct file * file, char __user * buf, size_t size, loff_t * loff) { int ret 0; unsigned char data[5]; dht11_start(); // 发送起始信号 ret dht11_wait_respon(); // 检测响应 if(ret 0) return ret; ret dht11_read_data(data); // 读取5字节数据 if(ret 0) return ret; copy_to_user(buf, data, sizeof(data)); // 内核数据拷贝到用户态 return 5; // 返回读取的字节数 }2.3.6 Platform 驱动初始化注册 Misc 设备生成 /dev/dht11解析设备树获取 GPIO 编号申请 GPIO 资源并初始化错误处理采用 goto 语句保证资源泄漏。static int probe(struct platform_device * pdev) { struct device_node * pdts; int ret misc_register(misc_dev); // 注册misc设备 if(ret) goto err_misc_register; // 解析设备树中/dht11节点 pdts of_find_node_by_path(/dht11); if(NULL pdts) { ret PTR_ERR(pdts); goto err_of_find; } // 获取设备树中指定的GPIO编号 dht11_gpio of_get_named_gpio(pdts, ptdht11-gpio, 0); if(dht11_gpio 0) { ret dht11_gpio; goto err_of_find; } // 申请GPIO资源 ret gpio_request(dht11_gpio, dht11); if(ret 0) goto err_gpio_request; gpio_direction_output(dht11_gpio, 1); // GPIO初始化为输出拉高 return 0; // 错误处理资源回滚 err_gpio_request: printk(dht11_driver gpio_request\n); err_of_find: printk(dht11_driver find node faidled\n); err_misc_register: misc_deregister(misc_dev); printk(dht11_driver misc register ret %d\n, ret) return ret; }2.4 驱动入口 / 出口static int __init dht11_driver_init(void) { int ret platform_driver_register(pdrv); // 注册Platform驱动 if(ret) goto err_platform_driver_register; return 0; err_platform_driver_register: return ret; } static void __exit dht11_driver_exit(void) { platform_driver_unregister(pdrv); // 注销Platform驱动 } module_init(dht11_driver_init); module_exit(dht11_driver_exit); MODULE_LICENSE(GPL); // 声明GPL协议避免内核警告三、应用层程序开发应用层通过操作 /dev/dht11 设备文件调用驱动接口核心是读取 5 字节数据并解析。#include stdio.h #include stdlib.h #include unistd.h #include sys/types.h #include sys/stat.h #include fcntl.h int main(int argc, const char* argv[]) { // 打开设备节点 int fd open(/dev/dht11, O_RDONLY); if (fd 0) { perror(open dht11 failed); return 1; } unsigned char data[5] {0}; while (1) { // 读取5字节数据 if (read(fd, data, sizeof(data)) 5) { // 校验和检查 unsigned char checksum data[0] data[1] data[2] data[3]; if (checksum ! data[4]) { printf(Checksum error! Data: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n,data[0], data[1], data[2], data[3], data[4]); sleep(3); continue; } // 解析温湿度 float humidity data[0] data[1] * 0.1; float temperature data[2] data[3] * 0.1; printf(Humidity %.1f%% Temperature %.1fC\n, humidity, temperature); } else { printf(read failed\n); } sleep(3); // 间隔3秒满足DHT11采样频率要求 } close(fd); return 0; }运行结果如下应用程序运行结果四、总结本驱动完整实现了 DHT11 在 Linux 内核中的集成核心价值在于严格遵循单总线时序协议微秒级延时控制采用标准 Platform Driver 架构支持设备树配置通过 Misc Device 简化设备节点管理用户空间零依赖标准 read() 接口即可获取数据

相关新闻

3大核心技术打造富文本编辑器专业级图片处理方案

3大核心技术打造富文本编辑器专业级图片处理方案

3大核心技术打造富文本编辑器专业级图片处理方案 【免费下载链接】lexical Lexical is an extensible text editor framework that provides excellent reliability, accessibility and performance. 项目地址: https://gitcode.com/GitHub_Trending/le/lexical 在内容创…

2026/7/5 5:56:52 阅读更多 →
OpenWrt固件编译与Ubuntu环境配置新手入门指南

OpenWrt固件编译与Ubuntu环境配置新手入门指南

OpenWrt固件编译与Ubuntu环境配置新手入门指南 【免费下载链接】OpenWrt 基于 Lean 源码编译的 OpenWrt 固件——适配X86、R2C、R2S、R4S、R4SE、R5C、R5S、香橙派 R1 Plus、树莓派3B、树莓派4B、R66S、R68S、M68S、H28K、H66K、H68K、H88K、H69K、E25、N1、S905x3、S922x、HK1…

2026/7/5 17:25:44 阅读更多 →
高效提取无损导出:播客创作者必备的LRC歌词获取指南

高效提取无损导出:播客创作者必备的LRC歌词获取指南

高效提取无损导出:播客创作者必备的LRC歌词获取指南 【免费下载链接】163MusicLyrics Windows 云音乐歌词获取【网易云、QQ音乐】 项目地址: https://gitcode.com/GitHub_Trending/16/163MusicLyrics 你是否曾在制作播客时,因找不到准确的歌曲LRC…

2026/7/3 13:59:09 阅读更多 →

最新新闻

AI大模型实战手册:从Transformer到RAG,核心概念与工程实践详解

AI大模型实战手册:从Transformer到RAG,核心概念与工程实践详解

1. 项目概述:为什么需要一本AI大模型的“词典”?最近几年,AI大模型的热度居高不下,几乎每天都能看到新的模型发布、新的应用落地。但随之而来的,是铺天盖地的技术名词和行业黑话。从“Transformer”到“RAG”&#xff…

2026/7/5 23:33:07 阅读更多 →
ElasticFace:动态边缘惩罚提升深度人脸识别性能

ElasticFace:动态边缘惩罚提升深度人脸识别性能

1. 论文核心内容概览 在深度人脸识别领域,特征提取的质量直接决定了模型的识别性能。传统方法如ArcFace、CosFace等通过引入固定的惩罚边缘(Fixed Penalty Margin)来增强特征的区分度,但这种"一刀切"的方式在面对真实场…

2026/7/5 23:33:07 阅读更多 →
AI模型Web服务安全加固实战:从CSRF/XSS防护到生产部署

AI模型Web服务安全加固实战:从CSRF/XSS防护到生产部署

1. 项目概述:当AI视觉模型遇上Web安全最近在部署一个基于OFA(One-For-All)的图像语义蕴含模型服务时,我遇到了一个非常典型但又容易被忽视的问题:我们往往把绝大部分精力都花在了模型调优、接口性能优化上,…

2026/7/5 23:29:06 阅读更多 →
视频嵌入表示技术:从3D CNN到Transformer的实践指南

视频嵌入表示技术:从3D CNN到Transformer的实践指南

1. 视频嵌入表示生成方案概述视频嵌入表示(Video Embedding)是计算机视觉领域将原始视频数据转化为低维稠密向量的关键技术。不同于传统视频处理直接操作像素数据,嵌入表示通过深度学习模型提取视频的语义特征,形成固定长度的向量…

2026/7/5 23:29:06 阅读更多 →
GPT-4o与Claude 3.5 Sonnet模型选型实战指南

GPT-4o与Claude 3.5 Sonnet模型选型实战指南

该项目标题存在严重事实性错误与误导风险,不符合内容安全与专业规范要求。根据公开、权威、可验证的官方信息渠道(OpenAI官网、主流科技媒体如The Verge、TechCrunch、MIT Technology Review等2024年至今的持续追踪报道),截至目前…

2026/7/5 23:29:06 阅读更多 →
DC-DC降压转换器设计与PID控制优化实践

DC-DC降压转换器设计与PID控制优化实践

1. 项目背景与核心器件选型解析在电力电子领域,DC-DC降压转换器(Buck Converter)是最基础也最关键的拓扑结构之一。这次我们要实现的方案采用了171010550电源管理IC与PIC18F97J60微控制器的组合,这个搭配在工业控制领域颇具代表性…

2026/7/5 23:25:05 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻