当前位置: 首页 > news >正文

DHT11 实现温湿度传感器

DHT11
DHT11是一款含有已校准数字信号输出的温湿度复合传感器,它结合了电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。通过采用专用的数字模块采集技术和温湿度传感技术,DHT11确保了产品的高可靠性和长期稳定性 

DHT11时序部分主要为   DHT11启动时序,读取数字0和读取数字1

1 . DHT11启动时序 

主机首先将电平拉低,至少持续18us [ mdelay(20) ],随后再拉高;

static void dht11_start(void)
{gpio_direction_output(PIN_DHT11, 0);mdelay(20);gpio_set_value(PIN_DHT11, 1);udelay(30);gpio_direction_input(PIN_DHT11); 
//将引脚设置为输入模式开始读取数据
}

② 


随后读取HDT发送的响应,先是80us的低电平随后拉高至80us;
表明DHT11已经正确响应启动信号,即将开始传输数据

static int dht11_wait_repon(void)
{int time = 100;while(gpio_get_value(PIN_DHT11))   // wait H end{udelay(1);if(!time--)return -1;}time = 100;while(!gpio_get_value(PIN_DHT11) && time)  // wait 80us L end{udelay(1);if(!time--)return -2;}time = 100;while(gpio_get_value(PIN_DHT11))   // wait 80us H end{udelay(1);if(!time--)return -3;}return 0;
}

2 . 读取0/1


当在启动时序的最后拉高80us后,如果遇到拉低50us和拉高26-28us则表示读取到 ‘ 0 ’;

 当在启动时序最后 ,如果遇到了拉低50us和拉高70us则表示读取到 ‘ 1 ’ ; 

所以可以根据高电平拉高时间来判断读取的是 ‘ 0 ’ 或者 ‘ 1 ’;

 ②
判断数据是都传输正确 
数据接收完毕后,根据ret的值进行检验,如果hum_h、hum_l、temp_h、temp_l 相加的值的后8位和校验位不相等,那么此次数据作废。 

static int dht11_get_value(unsigned char * data)
{int i = 0;int j = 0;unsigned char sum = 0;for(i = 0; i < 5; i++){data[i] = 0;for(j = 0; j < 8; j++){char bit = dht11_get_bit();	if(bit < 0)return bit;data[i] <<= 1;data[i] |= bit;}}for(i = 0; i < 4; i++){sum += data[i];}if(sum == data[4])return 4;elsereturn -1;
}

 

=== 数据格式:

DHT11采用单总线双向串行通信协议,每次采集信号时,都需要单片机向DHT11发送开始信号。DHT11在接收到开始信号后,即发送40bit的数据给单片机。高位在前,数据格式为:

        湿度高8位+湿度低8位+温度高8位+温度低8位+8bit校验位

        其中8bit校验位的值应与前4个8位数据相加后的数的低8位相同,如果不同则放弃本次数据

 


实践流程:

①编写dht11.c

②make Makefile 与 make Kconfig

③make modules 生成 dht11,ko

④cp drivers/char/dht11.ko  /home/linux/nfs/rootfs

⑤编写dht11_app.c 在 /home/linux/nfs/rootfs下

⑥arm-linux-gcc  dht11_app.c  -o  dht_app 

⑦sudo minicom

⑧insmod  dht11.ko

⑨./dht11_app 



完整代码

dht11.c

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <asm/io.h>
#include <asm/string.h>
#include <asm/uaccess.h>
#include <linux/miscdevice.h>
#include <asm-generic/errno-base.h>
#include <mach/gpio-nrs.h>
#include <mach/gpio.h>
#include <linux/delay.h>#define DEV_NAME "dht11"
#define PIN_DHT11 S3C2410_GPF(6)static void pin_init(void)
{gpio_request(PIN_DHT11, "dht11");
}static void dht11_start(void)
{gpio_direction_output(PIN_DHT11, 0);mdelay(20);gpio_set_value(PIN_DHT11, 1);udelay(30);gpio_direction_input(PIN_DHT11);
}static int dht11_wait_repon(void)
{int time = 100;while(gpio_get_value(PIN_DHT11))   // wait H end{udelay(1);if(!time--)return -1;}time = 100;while(!gpio_get_value(PIN_DHT11) && time)  // wait 80us L end{udelay(1);if(!time--)return -2;}time = 100;while(gpio_get_value(PIN_DHT11))   // wait 80us H end{udelay(1);if(!time--)return -3;}return 0;
}static int dht11_get_bit(void)
{int time = 100;while(!gpio_get_value(PIN_DHT11))  // wait 50us L end{udelay(1);	if(!time--)return -1;}udelay(30);if(0 == gpio_get_value(PIN_DHT11))return 0;while(gpio_get_value(PIN_DHT11))   // wait 40us H end{udelay(1);	if(!time--)return -2;}return 1;
}static int dht11_get_value(unsigned char * data)
{int i = 0;int j = 0;unsigned char sum = 0;for(i = 0; i < 5; i++){data[i] = 0;for(j = 0; j < 8; j++){char bit = dht11_get_bit();	if(bit < 0)return bit;data[i] <<= 1;data[i] |= bit;}}for(i = 0; i < 4; i++){sum += data[i];}if(sum == data[4])return 4;elsereturn -1;
}static int open (struct inode * inode, struct file * file)
{pin_init();printk("dht11 open ...\n");return 0;
}static ssize_t read (struct file * file, char __user * buf, size_t len, loff_t * offset)
{unsigned char data[4] = {0};int ret = 0;dht11_start();ret = dht11_wait_repon();if(ret < 0)goto err_wait;ret = dht11_get_value(data);if(ret < 0)goto err;copy_to_user(buf, data, sizeof(data));printk("dht11 read ...\n");return sizeof(data);err_wait:printk("dht11_wait_repon err ... \n");return ret;err:printk("dht11_get_value err ...\n");return ret;
}static ssize_t write (struct file * file, const char __user * buf, size_t len, loff_t * offset)
{return 0;
}static int close (struct inode * inode, struct file * file)
{printk("dht11 close ...\n");return 0;
}static struct file_operations fops = 
{.owner = THIS_MODULE,.open = open,.read = read,.write = write,.release = close
};static struct miscdevice misc = 
{.minor = MISC_DYNAMIC_MINOR,.name = DEV_NAME,.fops = &fops
};static int __init dht11_init(void)
{int ret = misc_register(&misc);if(ret < 0)goto err_misc_register;printk("dht11_init  ...\n");return ret;err_misc_register:misc_deregister(&misc);printk("dht11 misc_register faidht11\n");	return ret;
}static void __exit dht11_exit(void)
{misc_deregister(&misc);printk("dht11_exit  ###############################\n");
}module_init(dht11_init);
module_exit(dht11_exit);
MODULE_LICENSE("GPL");

hdt11_app.c 

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <asm/io.h>
#include <asm/string.h>
#include <asm/uaccess.h>
#include <linux/miscdevice.h>
#include <asm-generic/errno-base.h>
#include <mach/gpio-nrs.h>
#include <mach/gpio.h>
#include <linux/delay.h>#define DEV_NAME "dht11"
#define PIN_DHT11 S3C2410_GPF(6)static void pin_init(void)
{gpio_request(PIN_DHT11, "dht11");
}static void dht11_start(void)
{gpio_direction_output(PIN_DHT11, 0);mdelay(20);gpio_set_value(PIN_DHT11, 1);udelay(30);gpio_direction_input(PIN_DHT11);
}static int dht11_wait_repon(void)
{int time = 100;while(gpio_get_value(PIN_DHT11))   // wait H end{udelay(1);if(!time--)return -1;}time = 100;while(!gpio_get_value(PIN_DHT11) && time)  // wait 80us L end{udelay(1);if(!time--)return -2;}time = 100;while(gpio_get_value(PIN_DHT11))   // wait 80us H end{udelay(1);if(!time--)return -3;}return 0;
}static int dht11_get_bit(void)
{int time = 100;while(!gpio_get_value(PIN_DHT11))  // wait 50us L end{udelay(1);	if(!time--)return -1;}udelay(30);if(0 == gpio_get_value(PIN_DHT11))return 0;while(gpio_get_value(PIN_DHT11))   // wait 40us H end{udelay(1);	if(!time--)return -2;}return 1;
}static int dht11_get_value(unsigned char * data)
{int i = 0;int j = 0;unsigned char sum = 0;for(i = 0; i < 5; i++){data[i] = 0;for(j = 0; j < 8; j++){char bit = dht11_get_bit();	if(bit < 0)return bit;data[i] <<= 1;data[i] |= bit;}}for(i = 0; i < 4; i++){sum += data[i];}if(sum == data[4])return 4;elsereturn -1;
}static int open (struct inode * inode, struct file * file)
{pin_init();printk("dht11 open ...\n");return 0;
}static ssize_t read (struct file * file, char __user * buf, size_t len, loff_t * offset)
{unsigned char data[4] = {0};int ret = 0;dht11_start();ret = dht11_wait_repon();if(ret < 0)goto err_wait;ret = dht11_get_value(data);if(ret < 0)goto err;copy_to_user(buf, data, sizeof(data));printk("dht11 read ...\n");return sizeof(data);err_wait:printk("dht11_wait_repon err ... \n");return ret;err:printk("dht11_get_value err ...\n");return ret;
}static ssize_t write (struct file * file, const char __user * buf, size_t len, loff_t * offset)
{return 0;
}static int close (struct inode * inode, struct file * file)
{printk("dht11 close ...\n");return 0;
}static struct file_operations fops = 
{.owner = THIS_MODULE,.open = open,.read = read,.write = write,.release = close
};static struct miscdevice misc = 
{.minor = MISC_DYNAMIC_MINOR,.name = DEV_NAME,.fops = &fops
};static int __init dht11_init(void)
{int ret = misc_register(&misc);if(ret < 0)goto err_misc_register;printk("dht11_init  ...\n");return ret;err_misc_register:misc_deregister(&misc);printk("dht11 misc_register faidht11\n");	return ret;
}static void __exit dht11_exit(void)
{misc_deregister(&misc);printk("dht11_exit  ###############################\n");
}module_init(dht11_init);
module_exit(dht11_exit);
MODULE_LICENSE("GPL");


http://www.mrgr.cn/news/13995.html

相关文章:

  • 光庭信息半年报:营收利润「双」下降,汽车软件业务竞争加剧
  • polarctf靶场[WEB]Don‘t touch me、机器人、uploader、扫扫看
  • linux系统中内存和缓冲简介
  • EmguCV学习笔记 C# 第7章 特征点检测与匹配
  • 过滤器与拦截器对比
  • java基础 之 接口
  • Nginx负载均衡SSL证书配置全指南
  • Spring框架:从依赖注入到微服务
  • 使用Hutool操作Excel的时候出现的问题(压缩比问题)
  • ## 已解决:亲测有效的 `java.nio.charset.CoderMalfunctionError` 编码器故障错误解决方法
  • Web大学生网页作业成品——VIVO介绍网页设计与实现(HTML+CSS)(1个页面)
  • 【2024年】为Python股票量化分析最新整理的免费股票数据API接口之历史数据
  • 服务器远程管理
  • C++ 设计模式——组合模式
  • 1万2千多条电工考试题库ACCESS\EXCEL数据库
  • 不良信息公示
  • 【小沐学Rust】Rust实现TCP网络通信
  • 低代码用户中心的构建与应用
  • 收藏夹里的“小网站”被误报违规不让上怎么办?如何将Chrome和Edge安装到 D 盘(含用户数据),重装系统也不会丢失收藏夹和密码?
  • spi....