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. 性能考虑:最小化内核态操作,数据快速传递到用户空间

相关推荐
船长㉿12 小时前
vim常用命令
linux·编辑器·vim
大聪明-PLUS13 小时前
Linux 系统中的 CPU。文章 2:平均负载
linux·嵌入式·arm·smarc
listhi52013 小时前
使用SCP命令在CentOS 7上向目标服务器传输文件
linux·服务器·centos
Jason_Orton13 小时前
笔记本电脑触摸板失灵另类解决办法(I2C HID设备黄色感叹号)
运维·服务器·计算机网络·网络安全·电脑
艾德金的溪13 小时前
内网限制最大5G该如何传输30G的资源包
运维
Linux运维技术栈14 小时前
从Docker到宝塔:Magento2 2.3.5 安装全流程踩坑与成功实践
运维·adobe·docker·容器·magento2
天一生水water14 小时前
什么是调压器的P2s
linux·服务器·网络
拾忆,想起14 小时前
Dubbo负载均衡全解析:五种策略详解与实战指南
java·运维·微服务·架构·负载均衡·dubbo·哈希算法
ttthe_MOon14 小时前
Nginx实战:状态码、反向代理原理与负载均衡实战详解
运维·nginx·负载均衡
风中凌乱14 小时前
ftp服务的安装与部署
linux·服务器