百度提交网站收录,免费设计图网站,园林设计网站大全,wordpress ushare目录 一、工作方式
二、接口图
三、编写思路
1.构造file_operations结构体
2.实现read函数
3.编写入口函数
4.编写中断处理函数
5.编写出口函数
6.声明出入口函数以及协议
四、源码
五、课程链接 一、工作方式
SR501人体红外感应模块有两种工作模式#xff1a; …
目录 一、工作方式
二、接口图
三、编写思路
1.构造file_operations结构体
2.实现read函数
3.编写入口函数
4.编写中断处理函数
5.编写出口函数
6.声明出入口函数以及协议
四、源码
五、课程链接 一、工作方式
SR501人体红外感应模块有两种工作模式 通过跳线来设置是否可以重复触发默认为L。其中L表示不可重复H表示可重复。含义如下:
①不可重复触发方式:
感应到人体并输出高电平后延时时间一结束输出将自动从高电平变为低电平。
②重复触发方式: 感应到人体后输出高电平后在延时时间段内如果有人体在其感应范围内活动其输出将一直保持高电平直到人离开后才延时将高电平变为低电平(感应模块检测到人体的每一次活动后会自动顺延一个延时时间段,并且以最后一次活动的时间为延时时间的起始点)。
在本次实验中我们使用的是不可重复触发方式。
二、接口图 根据下面接口图我们可以算出SR501模块所在的引脚编号为115。 三、编写思路
1.构造file_operations结构体 对于SR501模块我们只需要读取他即可。
static struct file_operations sr501_drv {.owner THIS_MODULE,.read sr501_drv_read,
};
2.实现read函数
先是构造了一个环形buf用来存放数据读取也是直接从这个环形buf中读取数据。此外还引入了对应用层是使用阻塞还是非阻塞方式执行的判断。
使用到的函数
wait_event_interruptible() copy_to_user()DECLARE_WAIT_QUEUE_HEAD()
3.编写入口函数
先将gpio编号转换为中断号然后再申请中断然后就是注册file_operations结构体
使用到的函数
gpio_to_irq()request_irq()register_chrdev()class_create()device_create()
4.编写中断处理函数
每当产生上升沿或者下降沿时就会触发中断这时候就读取引脚电平将数据放入环形buf。
使用到的函数 gpio_get_value()
5.编写出口函数 释放掉入口函数中注册的资源。
使用到的函数
device_destroy()class_destroy()unregister_chrdev()free_irq()
6.声明出入口函数以及协议
module_init()module_exit()MODULE_LICENSE(GPL)
四、源码
驱动
#include asm-generic/errno-base.h
#include asm-generic/gpio.h
#include asm/uaccess.h
#include linux/module.h
#include linux/poll.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.h#define BUF_LEN 128struct gpio_desc{int gpio;int irq;char *name;int key;struct timer_list key_time;
};static struct gpio_desc gpios[2] {{115, 0, sr501},
};static int major;
static struct class *sr501_class;
static struct fasync_struct *sr501_fasync;static int r, w;
static int g_buf[BUF_LEN];static int is_empty(void)
{return (r w);
}static int is_full(void)
{return (r ((w 1) % BUF_LEN));
}static void put_val(int val)
{if (!is_full()){g_buf[w] val;w (w 1) % BUF_LEN;}
}static int get_val(void)
{int val 0;if (!is_empty()){val g_buf[r];r (r 1) % BUF_LEN;}return val;
}static DECLARE_WAIT_QUEUE_HEAD(gpio_wait);static ssize_t sr501_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{int val;int ret;if (!is_empty() (file-f_flags O_NONBLOCK)){return -EINVAL;}wait_event_interruptible(gpio_wait, !is_empty());val get_val();ret copy_to_user(buf, val, 4);return 4;
}static struct file_operations sr501_drv {.owner THIS_MODULE,.read sr501_drv_read,
};static irqreturn_t sr501_isr(int irq, void *dev_id)
{int val;int key;struct gpio_desc *gpio_desc dev_id;val gpio_get_value(gpio_desc-gpio);key (gpio_desc-key) | (val 8);put_val(key);wake_up_interruptible(gpio_wait);return IRQ_HANDLED;
}static int __init sr501_drv_init(void)
{int ret;int count sizeof(gpios) / sizeof(gpios[0]);int i;for (i 0; i count; i){gpios[i].irq gpio_to_irq(gpios[i].gpio);ret request_irq(gpios[i].irq, sr501_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, gpios[i].name, gpios[i]);}major register_chrdev(0, sr501_drv,sr501_drv);sr501_class class_create(THIS_MODULE, sr501_class);device_create(sr501_class, NULL, MKDEV(major, 0), NULL, sr501_drv);return ret;
}static void __exit sr501_drv_exit(void)
{int i;int count sizeof(gpios) / sizeof(gpios[0]);device_destroy(sr501_class, MKDEV(major, 0));class_destroy(sr501_class);unregister_chrdev(major, sr501_drv);for (i 0; i count; i){free_irq(gpios[i].irq, gpios[i]);}
}module_init(sr501_drv_init);
module_exit(sr501_drv_exit);MODULE_LICENSE
(GPL);应用 #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.hint main(int argc, char **argv)
{int fd;int val;if (argc ! 2){printf(Usage : %s dev\n, argv[0]);return -1;}fd open(argv[1], O_RDWR);if (fd -1){printf(open %s error\n, argv[1]);return -1;}while (1){if (read(fd, val, 4) 4){printf(get sr501 : %d\n, val);}else{printf(get sr501 : error\n);}}close(fd);return 0;
}五、课程链接
40_模板1实战_SR501红外模块驱动编程 (100ask.net)https://video.100ask.net/p/t_pc/course_pc_detail/video/v_636c762ce4b0276efeaea816?product_idp_634cbce4e4b00a4f37500252content_app_idtype6