DM355上按键程序 收藏
利用中断捕捉按键信息,延时去抖后即可读出
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DEVICE_NAME "buttons" /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */
#define BUTTON_NR_DEVS 1
struct button_irq_desc {
int irq;
int pin;
int number;
char *name;
};
#define GPIO8 8
#define GPIO9 9
#define GPIO5 5
#define GPIO6 6
#define GPIO7 7
/* For registeration of charatcer device */
#define BUTTONS_STATUS_GET 1
static struct cdev c_dev;
/* device structure to make entry in device */
static dev_t dev;
static struct class_simple *af_class = NULL;
/* 用来指定按键所用的外部中断引脚及中断触发方式, 名字 */
static struct button_irq_desc button_irqs [] = {
{IRQ_DM355_GPIO8, GPIO8, 0, "KEY1"}, /* K1 */
{IRQ_DM355_GPIO9, GPIO9, 1, "KEY2"}, /* K2 */
{IRQ_DM355_GPIO5, GPIO5, 2, "KEY3"}, /* K3 */
{IRQ_DM355_GPIO6, GPIO6, 3, "KEY4"}, /* K4 */
{IRQ_DM355_GPIO7, GPIO7, 4, "KEY5"}, /* K5 */
};
/* 按键被按下的次数(准确地说,是发生中断的次数) */
static volatile int key_values [] = {0, 0, 0, 0, 0};
/* 等待队列:
* 当没有按键被按下时,如果有进程调用davinci_buttons_read函数,
* 它将休眠
*/
static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
/* 中断事件标志, 中断服务程序将它置1,davinci_buttons_read将它清0 */
static volatile int ev_press = 0;
static struct timer_list button_timer;
/* 中断服务程序 void *dev_id响应管脚的button_irqs[i] 因为每个管脚的中断都注册了响应的button_irqs[i]
err = request_irq(button_irqs[i].irq, buttons_interrupt, NULL, button_irqs[i].name, (void *)&button_irqs[i]);*/
static irqreturn_t buttons_interrupt(int irq, void *dev_id,struct pt_regs *regs)
{
int i;
struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;
//屏蔽按键中断
button_timer.data=(unsigned long)button_irqs;
for (i = 0; i gpio_interrupt_disable(button_irqs[i].pin,TRIGGER_FALLING_EDGE );
}
button_timer.expires=jiffies+HZ/100;
add_timer(&button_timer);
return IRQ_RETVAL(IRQ_HANDLED);
}
static void button_timer_handler(unsigned long data)
{
int i;
int KeyStatus=0;
struct button_irq_desc *button_irqs = (struct button_irq_desc *)data;
KeyStatus=gpio_get_value(button_irqs->pin);
if(KeyStatus==0)
{
key_values[button_irqs->number] += 1;
printk("the button %d was push down\n",button_irqs->number);
ev_press = 1; /* 表示中断发生了 */
wake_up_interruptible(&button_waitq); /* 唤醒休眠的进程 */
}
//重新开启按键中断
for (i = 0; i gpio_interrupt_enable(button_irqs[i].pin,TRIGGER_FALLING_EDGE );
}
}
/* 应用程序对设备文件/dev/buttons执行open(...)时,
* 就会调用davinci_buttons_open函数
*/
static int davinci_buttons_open(struct inode *inode, struct file *file)
{
int i;
int err;
__REG(0x01c4000c)&=0xf1ffffff;
for (i = 0; i
/* Enable interrupt generation from GPIO Bank 0 (GPIO0-GPIO15) */
gpio_interrupt_bank_enable(button_irqs[i].pin);
/* Configure GPIO1 as an input */
gpio_set_direction(button_irqs[i].pin, GIO_DIR_INPUT);
/* Configure GPIO1 to generate an interrupt on falling edge only */
gpio_interrupt_enable(button_irqs[i].pin,TRIGGER_FALLING_EDGE );
gpio_interrupt_disable(button_irqs[i].pin, TRIGGER_RISING_EDGE);
// 注册中断处理函数
err = request_irq(button_irqs[i].irq, buttons_interrupt, NULL,
button_irqs[i].name, (void *)&button_irqs[i]);
if (err)
break;
}
if (err) {
// 释放已经注册的中断
i--;
for (; i >= 0; i--) {
disable_ir