linux添加定时器防抖,Linux按键驱动程序、定时器消抖

使用定时器可以防止因为按键抖动产生的多次响应函数~~

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define BUT_NAME "buttons"

#define DEVCOUNT 1

struct dev_button

{

dev_t dev;

struct cdev *cdev_p;

struct class * clz;

struct class_device * clz_dev;

struct timer_list timer;

};

struct key_dev

{

char * name;

const int irq_num;

unsigned int pin;

unsigned int key_status;

};

struct dev_button button_device;

struct key_dev keys[] = {

{.name = "S2", .irq_num = IRQ_EINT0, .pin = S3C2410_GPF0, .key_status = 0},

{.name = "s3", .irq_num = IRQ_EINT2, .pin = S3C2410_GPF2, .key_status = 0},

{.name = "s4", .irq_num = IRQ_EINT11, .pin = S3C2410_GPG3, .key_status = 0},

};

void timer_function(unsigned long data)

{

struct key_dev * p_dev = (struct key_dev *)data;

if(p_dev)

{

if(p_dev->key_status)

printk("Key %s pressed!\n", p_dev->name);

else

printk("Key %s unpressed!\n", p_dev->name);

}

}

irqreturn_t key_handler(int irq, void * param)

{

struct key_dev * p_dev = (struct key_dev *)param;

if(p_dev)

{

button_device.timer.data = (unsigned long)p_dev;

if(s3c2410_gpio_getpin(p_dev->pin))

p_dev->key_status = 0;

else

p_dev->key_status = 1;

mod_timer(&(button_device.timer), jiffies + HZ/100);

}

return 0;

}

struct file_operations f_ops = {

.owner = THIS_MODULE,

};

static int __init buttons_init(void)

{

int error = 0;

ssize_t i = 0;

printk("Button's driver is installing...\n");

if ((error = alloc_chrdev_region(&(button_device.dev), 0, DEVCOUNT, BUT_NAME)) < 0) {

printk(KERN_ERR

"button: Couldn't alloc_chrdev_region, error=%d\n",

error);

goto ERR_REG_DEVT;

}

printk("Alloc character region(%d, %d).\n",

MAJOR(button_device.dev), MINOR(button_device.dev));

button_device.cdev_p = cdev_alloc();

if(NULL == button_device.cdev_p)

{

printk(KERN_ERR

"button: Couldn't cdev_alloc");

goto ERR_ALLOC;

}

printk("Alloc cdev struct.\n");

button_device.cdev_p->ops = &f_ops;

error = cdev_add(button_device.cdev_p, button_device.dev, DEVCOUNT);

if(error < 0)

{

printk(KERN_ERR

"button: Couldn't cdev_add");

goto ERR_ADD_DEV;

}

printk("Add character device.\n");

button_device.clz = class_create(THIS_MODULE, BUT_NAME);

if(button_device.clz == NULL)

{

printk(KERN_ERR

"button: Couldn't class_create");

goto ERR_CLASS_CREATE;

}

printk("create class...\n");

button_device.clz_dev = class_device_create(button_device.clz, NULL, button_device.dev, NULL, BUT_NAME);

if(NULL == button_device.clz_dev)

{

printk(KERN_ERR

"button: Couldn't class_device_create");

goto ERR_DEV_CREATE;

}

printk("create device...\n");

printk("Button's driver installed successfully.\n");

for(i = 0; i < sizeof(keys)/sizeof(struct key_dev); i++)

{

if(0 != request_irq(keys[i].irq_num, key_handler, IRQT_BOTHEDGE, keys[i].name, (void*)(keys + i)))

{

printk(KERN_ERR

"button: Couldn't request_irq %s\n", keys[i].name);

goto ERR_REQUEST_IRQ;

}

printk("request_irq %d %s successfully\n", keys[i].irq_num,

keys[i].name);

}

init_timer(&button_device.timer);

button_device.timer.function = &timer_function;

add_timer(&button_device.timer);

return 0;

ERR_REQUEST_IRQ:

for( i-=1 ; i >= 0; i--)

free_irq(keys[i].irq_num, NULL);

ERR_DEV_CREATE:

class_destroy(button_device.clz);

ERR_CLASS_CREATE:

cdev_del(button_device.cdev_p);

ERR_ADD_DEV:

kfree(button_device.cdev_p);

ERR_ALLOC:

unregister_chrdev_region(button_device.dev, DEVCOUNT);

ERR_REG_DEVT:

printk("Error happened!\n");

return -1;

}

static void __exit buttons_exit(void)

{

ssize_t i = 0;

device_destroy(button_device.clz, button_device.dev);

class_destroy(button_device.clz);

kfree(button_device.cdev_p);

unregister_chrdev_region(button_device.dev, DEVCOUNT);

del_timer(&(button_device.timer));

for( i = 0 ; i < sizeof(keys) / sizeof(struct key_dev); i++)

free_irq(keys[i].irq_num, (void*)(keys + i));

return ;

}

module_init(buttons_init);

module_exit(buttons_exit);

MODULE_LICENSE("GPL");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值