DHT11温湿度传感器Linux驱动开发完整流程

一、DHT11传感器概述

基本特性

  • 类型:温湿度复合传感器

  • 通信协议:单总线异步半双工通信

  • 引脚配置:VCC、DATA、GND三线制

  • 通信方式单总线(Single Bus)------仅需1根数据线(除VCC、GND外)

  • 精度指标

    • 温度精度:±2℃

    • 湿度精度:±5%RH

    • 分辨率:1

硬件连接要求

  • 上拉电阻:DATA线需外接4.7K上拉电阻

  • 作用:确保DATA线在空闲状态保持高电平

二、DHT11通信协议详解

  1. 数据格式

    • 40位数据 = 5字节

    • 字节1:湿度整数部分

    • 字节2:湿度小数部分(通常为0)

    • 字节3:温度整数部分

    • 字节4:温度小数部分(通常为0)

    • 字节5:校验和(前4字节和)

数据传输时序


传输bit 1:从机将引脚先拉低50us左右,再拉高70us左右,代表dht11发送了一个****bit1

注意:通过测量高电平持续时间判断 bit 值,而非电压高低。

三、Linux驱动开发核心实现

1. 设备树配置

dts文件

cs 复制代码
mydht11 {
    #address-cells = <1>;
    #size-cells = <1>;
    compatible = "mydht11";
    pinctrl-0 = <&pinctrl_mydht11>;
    gpio-dht11 = <&gpio1 1 1>;  // 使用 GPIO1_1 引脚
    status = "okay";
};

操作命令

cs 复制代码
vim arch/arm/boot/dts/pt.dts        # 编辑设备树
make pt.dtb                         # 编译设备树
cp arch/arm/boot/dts/pt.dtb ~/tftpboot  # 拷贝到TFTP目录

2. 关键驱动函数

起始信号发送
cs 复制代码
static void dht11_start(void)
{
    gpio_direction_output(gpio_dht11, 1);
    msleep(10);
    gpio_set_value(gpio_dht11, 0);
    msleep(20);        // ≥18ms
    gpio_set_value(gpio_dht11, 1);
    udelay(40);        // 20-40μs
    gpio_direction_input(gpio_dht11);
}
响应检测(含超时保护)
cs 复制代码
static int dht11_wait_respon(void)
{
    // 三阶段检测:初始高→80μs低→80μs高
    // 每阶段设置超时,返回对应错误码
}
数据位读取
cs 复制代码
static inline char dht11_get_bit(void)
{
    // 等待50μs低电平结束
    // 延时35μs后采样电平
    // 低电平→bit=0,高电平→bit=1
}

3. 驱动架构设计

文件操作接口
cs 复制代码
static struct file_operations fops = {
    .owner = THIS_MODULE,
    .open = open,
    .read = read,
    .write = write,
    .release = close
};
平台驱动注册
cs 复制代码
static struct platform_driver drv = {
    .probe = probe,
    .remove = remove,
    .driver = {
        .name = DEV_NAME,
        .of_match_table = dht11_table
    }
};

四、用户空间测试程序

cs 复制代码
int main(void)
{
    int fd = open("/dev/dht11", O_RDWR);
    unsigned char data[5];
    
    while(1) {
        read(fd, data, sizeof(data));
        // 解析数据:data[0]-湿度,data[2]-温度
        // 校验:data[4] == data[0]+data[1]+data[2]+data[3]
        sleep(2);  // 采样间隔≥1秒
    }
    
    close(fd);
    return 0;
}

五、关键注意事项

时序要求

  • 采样间隔:≥1秒(建议2秒)

  • 起始信号:低电平≥18ms,高电平20-40μs

  • 响应超时:每阶段设置合理超时防止死锁

GPIO模式管理

  • 发送阶段:输出模式

  • 接收阶段:输入模式

  • 必须正确切换,否则无法接收数据

错误处理机制

  • 响应超时:返回错误码(-1/-2/-3)

  • 位读取失败:返回错误码(-4/-5/-6)

  • 用户层校验:必须验证校验字节

上下文安全

  • 进程上下文:可使用msleep/udelay/copy_to_user

  • 避免在中断上下文使用可能引起休眠的函数

六、调试与问题排查

常见问题

  1. 返回错误码:检查GPIO连接和上拉电阻

  2. 数据全零:确认GPIO模式正确切换

  3. 校验失败:检查电源稳定性和读取间隔

编译部署流程

复制代码
# 编译设备树
make pt.dtb

# 编译驱动模块
make modules

# 目标板加载
insmod dht11_1.ko
./dht11_app

七、核心技术要点总结

  1. 协议理解:严格遵循DHT11单总线时序规范

  2. 驱动架构:采用platform_driver + miscdevice标准框架

  3. 资源管理:通过设备树获取GPIO,确保可移植性

  4. 鲁棒性设计:超时机制+错误码返回+用户层校验

  5. 性能考虑:最小化内核态操作,数据快速传递到用户空间

相关推荐
来鸟 鸣间4 分钟前
Linux下3个so库之间的关系
linux·运维
释怀不想释怀21 分钟前
Linux文件上传(rz)和下载(sz)压缩(tar.gz)和解压(zip)
linux·运维·服务器
IOsetting29 分钟前
金山云主机添加开机路由
运维·服务器·开发语言·网络·php
酉鬼女又兒35 分钟前
零基础入门Linux指南:每天一个Linux命令_sed
linux·运维·服务器
daad77738 分钟前
tcpdump_BPF
linux·测试工具·tcpdump
予枫的编程笔记42 分钟前
【Linux进阶篇】Linux网络配置+端口监听实战:ip/ss/iptables常用命令一次吃透
linux·iptables·网络配置·curl·端口监听·ping·ss命令
礼拜天没时间.1 小时前
深入Docker架构——C/S模式解析
linux·docker·容器·架构·centos
-dcr1 小时前
58.DevOps进阶
运维·devops
猫头虎1 小时前
如何使用Docker部署OpenClaw汉化中文版?
运维·人工智能·docker·容器·langchain·开源·aigc
XiaoMu_0011 小时前
自动化漏洞扫描与预警平台
运维·网络·自动化