DHT11
本文旨在详细介绍如何使用 Luckfox Pico Plus 来驱动 DHT11 温湿度传感器模块,我们采用的是微雪的 DHT11(温湿度传感器) 模块,屏幕的具体参数可以查看 DHT11(温湿度传感器)的产品wiki。您可以下载镜像文件和示例程序直接使用或按照步骤自己配置。
1. 快速使用
1.1 烧录镜像
烧录文章开头提供的镜像。
1.2 硬件连接
Luckfox Pico

Luckfox Pico Plus 
Luckfox Pico Pro/Max

连接引脚对应关系
| DHT11 | Pico / Plus / Pro / Max | 功能 |
|---|---|---|
| VCC | 3V3 | 电源输入 |
| GND | GDN | 电源地 |
| DOUT | GPIO1_C7_d(55) | 通信端口 |
1.3 导入模块
连接好模块后上电,将示例程序中的 dht11_drv.ko 和 dht11 文件拷贝到开发板,导入模块:
insmod dht11_drv.ko
1.4 运行程序
chmod +x dht11
./dht11
2. 引脚配置
Luckfox Pico / Plus / Pro / Max 系列主要参考了 Raspberry Pi Pico 的引脚布局,通过引脚配置可以兼容部分 Raspberry Pi Pico 的外设。

Luckfox Pico 不同型号支持的兼容设备列表参考Luckfox-Pico_support-List
兼容设备选项本质上是多种引脚配置的组合,可以简化配置的步骤
Luckfox Pico 在 ubuntu 下由于没有 io 命令直接配置寄存器,配置兼容设备 Pico-LCD 时引脚无法配置为默认上拉,无法正常控制按键
启动兼容设备配置时会覆盖原有配置,需要取消兼容设备到 Advanced Options 界面关闭启动的设备功能即可
3. 示例程序
3.1 dht11_drv.c
该代码是一个用于与 DHT11 传感器进行交互的 Linux 内核模块,它通过字符设备文件提供温度和湿度的读取接口。下面是对代码的解析:
数据结构定义
typedef struct DHT11_SENSOR_DATA
{
u16 temp; // Temperature
u16 hum; // Humidity
} dht11_data;
- 功能:定义了一个结构体
DHT11_SENSOR_DATA,用于存储从DHT11传感器读取的温度和湿度数据。
DHT11_Read_DQ
static u8 DHT11_Read_DQ(void)
{
DHT11_IO_IN;
return gpio_get_value(dht11_gpio);
}
- 功能:读取DHT11传感器的数据线状态。
- 步骤:将数据线设置为输入模式(DHT11_IO_IN),然后使用
gpio_get_value获取数据线的值。
DHT11_Rst
static void DHT11_Rst(void)
{
DHT11_DQ_Low;
delay_ms(20);
DHT11_DQ_High;
delay_us(30);
}
- 功能:复位DHT11传感器,拉低数据线,等待一段时间后再拉高。
- 步骤:将数据线拉低(DHT11_DQ_Low),延时20毫秒,然后将数据线拉高(DHT11_DQ_High)并延时30微秒。
DHT11_Check
static u8 DHT11_Check(void)
{
u8 retry = 0;
DHT11_IO_IN;
while ((DHT11_Read_DQ() == 1) && retry < 100)
{
retry++;
delay_us(1);
}
if (retry >= 100)
return 1;
else
retry = 0;
while ((DHT11_Read_DQ() == 0) && retry < 100)
{
retry++;
delay_us(1);
}
if (retry >= 100)
return 1;
return 0;
}
- 功能:检查DHT11传感器是否存在,通过监控数据线状态。
- 步骤:等待数据线从高电平变为低电平,再从低电平变为高电平。
DHT11_Read_Bit
static u8 DHT11_Read_Bit(void)
{
u8 retry = 0;
while ((DHT11_Read_DQ() == 1) && retry < 100)
{
retry++;
delay_us(1);
}
retry = 0;
while ((DHT11_Read_DQ() == 0) && retry < 100)
{
retry++;
delay_us(1);
}
delay_us(40);
if (DHT11_Read_DQ() == 1)
return 1;
else
return 0;
}
- 功能:从DHT11传感器读取一个位。
- 步骤:等待数据线从高电平变为低电平,再从低电平变为高电平,然后延时40微秒,最后读取数据线的状态。
DHT11_Read_Byte
static u8 DHT11_Read_Byte(void)
{
u8 i, dat;
dat = 0;
for (i = 0; i < 8; i++)
{
dat <<= 1;
dat |= DHT11_Read_Bit();
}
return dat;
}
- 功能:从DHT11传感器读取一个字节(8位)。
- 步骤:调用
DHT11_Read_Bit函数8次,每次左移一位并与读取的位进行按位或操作。
DHT11_Read_Data
static u8 DHT11_Read_Data(u16 *temp, u16 *humi)
{
u8 buf[5];
u8 i;
DHT11_Rst();
if (DHT11_Check() == 0)
{
for (i = 0; i < 5; i++)
{
buf[i] = DHT11_Read_Byte();
}
if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])
{
*humi = buf[0] << 8 | buf[1];
*temp = buf[2] << 8 | buf[3];
printk("buf=%d,%d,%d,%d,%d\n", buf[0], buf[1], buf[2], buf[3], buf[4]);
return 0;
}
else
return 1;
}
else
return 1;
}
- 功能:从DHT11传感器读取温度和湿度数据。
- 步骤:调用
DHT11_Rst进行复位和初始化,然后通过调用DHT11_Check检查传感器是否存在。如果存在,继续通过调用DHT11_Read_Byte读取40位的数据,然后验证校验和。
DHT11_Init
static void DHT11_Init(void)
{
DHT11_DQ_High;
DHT11_Rst();
DHT11_Check();
}
- 功能:初始化DHT11传感器的IO口,并检测传感器的存在。
- 步骤:将数据线拉高,然后调用
DHT11_Rst进行复位,最后调用DHT11_Check等待传感器的回应。
DHT11_open
int DHT11_open(struct inode *inode, struct file *flips)
{
printk("--------------%s--------------\n", __FUNCTION__);
return 0;
}
- 功能:字符设备文件的打开操作。
DHT11_read
static ssize_t DHT11_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
dht11_data Last_dht11_data;
printk("--------------%s--------------\n", __FUNCTION__);
if (DHT11_Read_Data(&Last_dht11_data.temp, &Last_dht11_data.hum) == 0)
{
if (copy_to_user(buf, &Last_dht11_data, sizeof(Last_dht11_data)))
{
return -EFAULT;
}
}
return 0;
}
- 功能:字符设备文件的读取操作,从DHT11传感器读取温湿度数据。
- 步骤:调用
DHT11_Read_Data函数读取数据,然后将数据拷贝到用户空间。
DHT11_close
static int DHT11_close(struct inode *inode, struct file *flip)
{
printk("--------------%s--------------\n", __FUNCTION__);
return 0;
}
- 功能:字符设备文件的关闭操作。
dht11_probe
static int dht11_probe(struct platform_device *pdev)
{
...
}
- 功能:处理平台设备的探测和初始化。
- 步骤:包括获取GPIO信息,注册字符设备,创建设备类和设备节点,以及初始化DHT11传感器。
dht11_remove
static int dht11_remove(struct platform_device *pdev)
{
...
}
- 功能:处理平台设备的卸载。
- 步骤:包括销毁设备节点、设备类,注销字符设备。
dht11_shutdown
static void dht11_shutdown(struct platform_device *pdev)
{
printk("-------%s-------------\n", __FUNCTION__);
}
- 功能:处理设备关机操作。
- 步骤:打印一条调试信息。
3.2 dht11_test.c
该代码是调用设备文件读取温湿度的示例代码。下面是对代码的解析:
打开设备文件
fd = open("/dev/dht11", O_RDONLY);
if (fd == -1)
{
perror("open dht11 error\n");
exit(-1);
}
使用 open 函数以只读方式打开名为 "/dev/dht11" 的字符设备文件。如果打开失败,输出错误信息并退出程序。
循环读取传感器数据
while (1)
{
sleep(1);
retval = read(fd, &Curdht11_data, sizeof(Curdht11_data));
if (retval == -1)
{
perror("read dht11 error");
printf("read dht11 error");
exit(-1);
}
if (Curdht11_data.temp != 0xffff)
printf("Temperature:%d.%d C,Humidity:%d.%d %%RH\n", Curdht11_data.temp >> 8, Curdht11_data.temp & 0xff, \
Curdht11_data.hum >> 8, Curdht11_data.hum & 0xff);
}
每隔1秒读取一次传感器数据。如果读取失败,输出错误信息并退出程序。如果温度值不是0xffff,就打印温度和湿度的信息。
关闭设备文件
close(fd);
使用 close 函数关闭设备文件。
3.3 编译程序
修改Makefile
将 Makefile 中
<SDK Directory>修改为自己的 SDK 路径,如/home/luckfox/luckfox-pico/ARCH=arm
CROSS_COMPILE=<SDK Directory\>/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/bin/arm-rockchip830-linux-uclibcgnueabihf-
export ARCH CROSS_COMPILE
KERN_DIR = <SDK Directory>/sysdrv/source/kernel
name=dht11
PWD?=$(shell pwd)
all:
make -C $(KERN_DIR) M=$(PWD) modules
$(CROSS_COMPILE)gcc $(name)_test.c -o $(name)
echo $(PWD)
clean:
rm -f *.ko *.o *.mod *.mod.o *.mod.c *.symvers *.order *.cmd
# make -C $(KERN_DIR) M=$(PWD) modules clean
# rm -rf modules.order
# rm -f $(name)_test
obj-m += $(name)_drv.o编译
执行
make对两个文件进行编译,把产物中的dht11_drv.ko和dht11拷贝到开发板上。
4. 实现效果
4.1 导入模块
insmod dht11_drv.ko
效果如下:
# insmod dht11_drv.ko
[ 57.655150] -------dht11_probe-------------
[ 57.655337] dht11-gpio: 55 is valid!
[ 57.655365] gpio 55 request success!
[ 57.655381] dht11_major =239
[ 57.681960] dht11 Initing...
4.2 读取温湿度
chmod +x dht11
./dht11
效果如下:
# chmod +x dht11
# ./dht11
Press CTRL+C to exit.
[ 91.447436] --------------DHT11_open--------------
open /dev/dht11 successfully
[ 93.447934] --------------DHT11_read--------------
[ 93.475741] buf=37,0,25,7,69
Temperature:25.7 C, Humidity:37.0 %RH
[ 94.476565] --------------DHT11_read--------------
Temperature:25.7 C, Humidity:37.0 %RH
[ 95.502423] --------------DHT11_read--------------
[ 95.532409] buf=37,0,25,7,69
Temperature:25.7 C, Humidity:37.0 %RH
[ 96.533221] --------------DHT11_read--------------
Temperature:25.7 C, Humidity:37.0 %RH
[ 97.559087] --------------DHT11_read--------------
[ 97.589061] buf=37,0,25,9,71
Temperature:25.9 C, Humidity:37.0 %RH
[ 98.589883] --------------DHT11_read--------------
Temperature:25.9 C, Humidity:37.0 %RH