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

自己如何做网站教程中山企业网站推广公司

自己如何做网站教程,中山企业网站推广公司,抖音个人主页模板,有做网站动态效果软件一、DHT11简介 DHT11是一款可测量温度和湿度的传感器。比如市面上一些空气加湿器#xff0c;会测量空气中湿度#xff0c;再根据测量结果决定是否继续加湿。 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器#xff0c;具有超小体积、极低功耗的特点…一、DHT11简介 DHT11是一款可测量温度和湿度的传感器。比如市面上一些空气加湿器会测量空气中湿度再根据测量结果决定是否继续加湿。 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器具有超小体积、极低功耗的特点使用单根总线与主机进行双向的串行数据传输。DHT11测量温度的精度为± 2℃检测范围为-20℃ -60℃。湿度的精度为± 5%RH检测范围为 5%RH-95%RH常用于对精度和实时性要求不高的温湿度测量场合。 1.1 DHT11模块硬件设计 主机通过一条数据线与DH11连接主机通过这条线发命令给DHT11DHT11再通过这条线把数据发送给主机。 1.2 DHT11模块软件设计 DHT11的硬件电路比较简单核心要点就是主机发给DHT11的命令格式和DHT11返回的数据格式。 1.3 DHT11通讯协议 通讯过程如图所示 当主机没有与 DHT11 通信时总线处于空闲状态此时总线电平由于上拉电阻的作用处于高电平。 当主机与 DHT11 正在通信时总线处于通信状态一次完整的通信过程如下 a) 主机将对应的 GPIO 管脚配置为输出准备向 DHT11 发送数据 b主机发送一个开始信号开始信号 一个低脉冲 一个高脉冲。低脉冲至少持续 18ms高脉冲持续 20-40us。 c) 主机将对应的 GPIO 管脚配置为输入准备接受 DHT11 传来的数据这时信号由上拉电阻拉高 d) DHT11 发出响应信号响应信号 一个低脉冲 一个高脉冲。低脉冲持续 80us高脉冲持续 80us。 e) DHT11 发出数据信号 数据为 0 的一位信号 一个低脉冲 一个高脉冲。低脉冲持续50us高脉冲持续 2628us。数据为 1 的一位信号 一个低脉冲 一个高脉冲。低脉冲持续50us高脉冲持续 70us。 f) DHT11 发出结束信号 最后 1bit 数据传送完毕后 DHT11 拉低总线 50us然后释放总线总线由上拉电阻拉高进入空闲状态。 1.4 DHT11数据格式 8bit 湿度整数数据 8bit 湿度小数数据 8bi 温度整数数据 8bit 温度小数数据 8bit 校验和。数据传送正确时,校验和等于“8bit 湿度整数数据8bit 湿度小数数据8bi温度整数数据8bit 温度小数数据”所得结果的末 8 位。 二、相关代码 2.1 驱动代码 #include asm-generic/errno-base.h #include asm-generic/gpio.h #include linux/jiffies.h #include linux/module.h #include linux/poll.h #include linux/delay.h #include linux/fs.h #include linux/errno.h #include linux/miscdevice.h #include linux/kernel.h #include linux/major.h #include linux/mutex.h #include linux/proc_fs.h #include linux/seq_file.h #include linux/stat.h #include linux/init.h #include linux/device.h #include linux/tty.h #include linux/kmod.h #include linux/gfp.h #include linux/gpio/consumer.h #include linux/platform_device.h #include linux/of_gpio.h #include linux/of_irq.h #include linux/interrupt.h #include linux/irq.h #include linux/slab.h #include linux/fcntl.h #include linux/timer.hstruct gpio_desc{int gpio;int irq;char *name;int key;struct timer_list key_timer; } ;static struct gpio_desc gpios[] {{115, 0, dht11, }, };/* 主设备号 */ static int major 0; static struct class *gpio_class;static u64 g_dht11_irq_time[84]; static int g_dht11_irq_cnt 0;/* 环形缓冲区 */ #define BUF_LEN 128 static char g_keys[BUF_LEN]; static int r, w;struct fasync_struct *button_fasync;static irqreturn_t dht11_isr(int irq, void *dev_id); static void parse_dht11_datas(void);#define NEXT_POS(x) ((x1) % BUF_LEN)static int is_key_buf_empty(void) {return (r w); }static int is_key_buf_full(void) {return (r NEXT_POS(w)); }static void put_key(char key) {if (!is_key_buf_full()){g_keys[w] key;w NEXT_POS(w);} }static char get_key(void) {char key 0;if (!is_key_buf_empty()){key g_keys[r];r NEXT_POS(r);}return key; }static DECLARE_WAIT_QUEUE_HEAD(gpio_wait);// static void key_timer_expire(struct timer_list *t) static void key_timer_expire(unsigned long data) {// 解析数据, 放入环形buffer, 唤醒APPparse_dht11_datas(); }/* 实现对应的open/read/write等函数填入file_operations结构体 */ static ssize_t dht11_read (struct file *file, char __user *buf, size_t size, loff_t *offset) {int err;char kern_buf[2];if (size ! 2)return -EINVAL;g_dht11_irq_cnt 0;/* 1. 发送18ms的低脉冲 */err gpio_request(gpios[0].gpio, gpios[0].name);gpio_direction_output(gpios[0].gpio, 0);gpio_free(gpios[0].gpio);mdelay(18);/* 引脚变为输入方向, 由上拉电阻拉为1*//* 当主机没有与DHT11通信时总线处于空闲状态此时总线电平由于上拉电阻的作用处于高电平*/gpio_direction_input(gpios[0].gpio); /* 2. 注册中断 后面的语句执行时可能会导致前几次的中断丢失*/err request_irq(gpios[0].irq, dht11_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, gpios[0].name, gpios[0]);mod_timer(gpios[0].key_timer, jiffies 10);修改定时器的超时时间 jiffies(当前时间) 10 /* 3. 休眠等待数据 *///等待 条件为真有数据时才会被唤醒并执行后面语句wait_event_interruptible(gpio_wait, !is_key_buf_empty());free_irq(gpios[0].irq, gpios[0]);//printk(%s %s %d\n, __FILE__, __FUNCTION__, __LINE__);/* 设置DHT11 GPIO引脚的初始状态: output 1 保险起见手动设置高电平最后 1bit 数据传送完毕后 DHT11 拉低总线 50us然后释放总线总线由上拉电阻拉高进入空闲状态*/err gpio_request(gpios[0].gpio, gpios[0].name);if (err){printk(%s %s %d, gpio_request err\n, __FILE__, __FUNCTION__, __LINE__);}gpio_direction_output(gpios[0].gpio, 1);gpio_free(gpios[0].gpio);/* 4. copy_to_user */kern_buf[0] get_key();kern_buf[1] get_key();printk(get val : 0x%x, 0x%x\n, kern_buf[0], kern_buf[1]);if ((kern_buf[0] (char)-1) (kern_buf[1] (char)-1)){printk(get err val\n);return -EIO;}err copy_to_user(buf, kern_buf, 2);return 2; }static int dht11_release (struct inode *inode, struct file *filp) {return 0; }/* 定义自己的file_operations结构体 */ static struct file_operations dht11_drv {.owner THIS_MODULE,.read dht11_read,.release dht11_release, };//解析数据 static void parse_dht11_datas(void) {int i;u64 high_time;unsigned char data 0;int bits 0;unsigned char datas[5];//40位 5个字节int byte 0;unsigned char crc;/* 中断发生次数: 可能是81、82、83、84 */if (g_dht11_irq_cnt 81){/* 出错 */put_key(-1);put_key(-1);// 唤醒APPwake_up_interruptible(gpio_wait);g_dht11_irq_cnt 0;return;}// 解析数据, 81、82、83、84 for (i g_dht11_irq_cnt - 80; i g_dht11_irq_cnt; i 2){high_time g_dht11_irq_time[i] - g_dht11_irq_time[i-1];//高脉冲时间data 1;//左移一位//50us 50000ns//如果数据是高电平if (high_time 50000) /* data 1 */{data | 1;//或}bits;if (bits 8){datas[byte] data;data 0;bits 0;byte;}}// 放入环形buffercrc datas[0] datas[1] datas[2] datas[3];if (crc datas[4]){put_key(datas[0]);put_key(datas[2]);}else{put_key(-1);put_key(-1);}g_dht11_irq_cnt 0;// 唤醒APPwake_up_interruptible(gpio_wait); }static irqreturn_t dht11_isr(int irq, void *dev_id) {struct gpio_desc *gpio_desc dev_id;u64 time;/* 1. 记录中断发生的时间 */time ktime_get_ns();//单位ns 精准的到当前时间//static u64 g_dht11_irq_time[84]; static int g_dht11_irq_cnt 0;g_dht11_irq_time[g_dht11_irq_cnt] time;/* 2. 累计次数 */g_dht11_irq_cnt;/* 3. 次数足够: 解析数据, 放入环形buffer, 唤醒APP */if (g_dht11_irq_cnt 84){del_timer(gpio_desc-key_timer);parse_dht11_datas();//解析数据}return IRQ_HANDLED; }/* 在入口函数 */ static int __init dht11_init(void) {int err;int i;int count sizeof(gpios)/sizeof(gpios[0]);//count 1printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);for (i 0; i count; i){ gpios[i].irq gpio_to_irq(gpios[i].gpio);/* 设置DHT11 GPIO引脚的初始状态: output 1 */err gpio_request(gpios[i].gpio, gpios[i].name); //申请gpiogpio_direction_output(gpios[i].gpio, 1); //输出方向高电平gpio_free(gpios[i].gpio); //释放引脚//设置定时器定时器结构体定时器超时函数传给超时函数的参数setup_timer(gpios[i].key_timer, key_timer_expire, (unsigned long)gpios[i]);//gpios[i].key_timer.expires ~0;//add_timer(gpios[i].key_timer);//err request_irq(gpios[i].irq, dht11_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 100ask_gpio_key, gpios[i]);}/* 注册file_operations */major register_chrdev(0, 100ask_dht11, dht11_drv); /* /dev/gpio_desc */gpio_class class_create(THIS_MODULE, 100ask_dht11_class);if (IS_ERR(gpio_class)) {printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);unregister_chrdev(major, 100ask_dht11);return PTR_ERR(gpio_class);}device_create(gpio_class, NULL, MKDEV(major, 0), NULL, mydht11); /* /dev/mydht11 */return err; }/* 有入口函数就应该有出口函数卸载驱动程序时就会去调用这个出口函数*/ static void __exit dht11_exit(void) {int i;int count sizeof(gpios)/sizeof(gpios[0]);printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);device_destroy(gpio_class, MKDEV(major, 0));class_destroy(gpio_class);unregister_chrdev(major, 100ask_dht11);for (i 0; i count; i){//free_irq(gpios[i].irq, gpios[i]);del_timer(gpios[i].key_timer);} }/* 7. 其他完善提供设备信息自动创建设备节点 */module_init(dht11_init); module_exit(dht11_exit);MODULE_LICENSE(GPL); 2.2 测试代码 #include sys/types.h #include sys/stat.h #include fcntl.h #include unistd.h #include stdio.h #include string.h #include poll.h #include signal.hstatic int fd;/** ./button_test /dev/mydht11**/ int main(int argc, char **argv) {char buf[2];int ret;int i;/* 1. 判断参数 */if (argc ! 2) {printf(Usage: %s dev\n, argv[0]);return -1;}/* 2. 打开文件 */fd open(argv[1], O_RDWR | O_NONBLOCK);if (fd -1){printf(can not open file %s\n, argv[1]);return -1;}while (1){if (read(fd, buf, 2) 2)printf(get Humidity: %d, Temperature : %d\n, buf[0], buf[1]);elseprintf(get dht11: -1\n);sleep(5);}close(fd);return 0; } 2.3 上板子测试 可以看到测到的温度和湿度数值都是正常的但偶尔会测得失败的数据这是因为在驱动程序里注册中断函数后后面的语句执行花时间可能会导致前几次的中断丢失。经测试如果中断发生次数小于81则会测得错误数据中断发生次数在81~84含等于就可测得准确数值。
http://www.zqtcl.cn/news/887153/

相关文章:

  • 网站每年费用本地同城服务平台
  • 暗网网站有那些青岛网站设计公司推荐
  • 营业执照咋做网等网站遂宁网站建设公司哪家好
  • 湖南平台网站建设找哪家重庆网站建设营销
  • wordpress搭建企业网站小型网络架构
  • 淘宝联盟链接的网站怎么做培训网站排名
  • 上海高端网站建设定制大连开发区邮编
  • 手机网站公司免费crm软件下载
  • 家居企业网站建设平台周口seo
  • 扁平化网站建设公司广告推广方案
  • 高端企业网站 程序北京做网站费用
  • net做网站遇到的问题搜索引擎优化方法
  • 专业的设计网站有哪些网站数据库做好了 怎么做网页
  • 鄂州网站建设公司网站制作过程教程
  • 网站建设课程小结二建证考试需要什么条件
  • 比较好的商城网站设计品牌策划案
  • 自适应科技公司网站模板做网站的公司深
  • 网站怎么吸引流量用淘宝做公司网站
  • asp做的网站后台怎么进去老河口城乡建设局网站
  • 中铁建设集团有限公司官方网站wordpress质感
  • 那个网站点击率高pc网站自动生成app
  • 东莞营销型网站建站淘金企业网站建设
  • 怎么用模板做网站手机python编程软件
  • 做视频网站都需要什么软件下载广东网站建设哪家专业
  • 开淘宝的店铺网站怎么做网页设计需要学什么书
  • 如何做收费网站微信小程序开发教程详解
  • 软件下载网站如何履行安全管理义务网站合同书
  • 普宁17网站一起做淘宝网站建设 丽水
  • 网站注册需要多少钱wordpress缓存失败
  • 西安h5响应式网站施工企业安全生产管理规范最新版