一、DHT11传感器概述
基本特性
-
类型:温湿度复合传感器
-
通信协议:单总线异步半双工通信
-
引脚配置:VCC、DATA、GND三线制
-
通信方式 :单总线(Single Bus)------仅需1根数据线(除VCC、GND外)
-
精度指标:
-
温度精度:±2℃
-
湿度精度:±5%RH
-
分辨率:1
-
硬件连接要求
-
上拉电阻:DATA线需外接4.7K上拉电阻
-
作用:确保DATA线在空闲状态保持高电平
二、DHT11通信协议详解
-
数据格式
-
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
-
避免在中断上下文使用可能引起休眠的函数
六、调试与问题排查
常见问题
-
返回错误码:检查GPIO连接和上拉电阻
-
数据全零:确认GPIO模式正确切换
-
校验失败:检查电源稳定性和读取间隔
编译部署流程
# 编译设备树
make pt.dtb
# 编译驱动模块
make modules
# 目标板加载
insmod dht11_1.ko
./dht11_app
七、核心技术要点总结
-
协议理解:严格遵循DHT11单总线时序规范
-
驱动架构:采用platform_driver + miscdevice标准框架
-
资源管理:通过设备树获取GPIO,确保可移植性
-
鲁棒性设计:超时机制+错误码返回+用户层校验
-
性能考虑:最小化内核态操作,数据快速传递到用户空间