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

相关推荐
Yyyy4823 小时前
Ubuntu部署 Kubernetes1.23
linux·运维·ubuntu
人工智能训练3 小时前
在 Ubuntu 系统中利用 conda 创建虚拟环境安装 sglang 大模型引擎的完整步骤、版本查看方法、启动指令及验证方式
linux·运维·服务器·人工智能·ubuntu·conda·sglang
☆璇4 小时前
【Linux】网络层协议IP
linux·服务器·tcp/ip
王道长服务器 | 亚马逊云4 小时前
AWS Auto Scaling:自动扩容,让服务器像呼吸一样灵活
运维·网络·自动化·云计算·aws
小蜗牛爱远行4 小时前
服务器和docker容器时间不一致相关问题
运维·服务器·docker
Xの哲學4 小时前
Linux ioctl 深度剖析:从原理到实践
linux·网络·算法·架构·边缘计算
孙同学要努力4 小时前
《Linux篇》进程控制——进程创建(写时拷贝)、进程终止(退出码,exit,_exit)
linux·运维·服务器
Hali_Botebie4 小时前
服务器上用Slurm 管理训练bash 脚本任务
运维·服务器·bash
咕噜企业签名分发-淼淼4 小时前
app分发平台哪个好点?手机app应用内测分发平台支持负载均衡的重要性
运维·智能手机·负载均衡