S5PV210按键添加timer去抖动

本文详细介绍了S5PV210平台上的按键驱动实现,包括GPIO配置、中断处理、定时器使用及输入设备注册过程。通过具体代码示例,展示了如何在Linux环境下完成按键去抖动和状态报告。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码如下:

#include <linux/input.h>
#include <linux/module.h>
#include <linux/init.h>

#include <asm/irq.h>
#include <asm/io.h>

#include <linux/gpio.h>

#include <linux/interrupt.h>

static struct input_dev *button_dev;
#define BUTTON_IRQ IRQ_EINT2

static struct timer_list buttons_timer;  /* 定义一个定时器结构体 */ 


static void func(void)
{
	int flag;
	s3c_gpio_cfgpin(S5PV210_GPH0(2), S3C_GPIO_SFN(0x0));
	flag = gpio_get_value(S5PV210_GPH0(2));
	s3c_gpio_cfgpin(S5PV210_GPH0(2), S3C_GPIO_SFN(0x0f));
	
	input_report_key(button_dev, KEY_LEFT, !flag);
	input_sync(button_dev);
}

//定义tasklet并绑定tasklet调度函数
DECLARE_TASKLET(mytasklet, func, 0);
//DECLARE_WORK(mywork, func);

static void buttons_timer_function(unsigned long data)
{
	tasklet_schedule(&mytasklet); //在上半步中进行tasklet调度
	//schedule_work(&mywork);
}


//中断的上半步
static irqreturn_t button_interrupt(int irq, void *dummy)
{

	/* 修改定时器定时时间,定时10ms,即10秒后启动定时器      
	* HZ 表示100个jiffies,jiffies的单位为10ms,即HZ = 100*10ms = 1s      
	* 这里HZ/100即定时10ms      
	*/  

	mod_timer(&buttons_timer, jiffies + (HZ /100));
	return IRQ_HANDLED;
}

static int __init s5pv210_button_init(void)
{
	int error;
	//add a timer to debouncing
	init_timer(&buttons_timer);  
	buttons_timer.function  = buttons_timer_function;
	add_timer(&buttons_timer);

	error = gpio_request(S5PV210_GPH0(2), "gph0_2");
	if (error)
	{
		printk(KERN_INFO "gpio_request fail\n");
	}
	//set to the eint2 mode
	s3c_gpio_cfgpin(S5PV210_GPH0(2), S3C_GPIO_SFN(0x0f));

	if (request_irq(BUTTON_IRQ, button_interrupt, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "button-sw5", NULL))
	{
       	printk(KERN_ERR "button.c: Can't allocate irq %d\n", BUTTON_IRQ);
       	return -EBUSY;
    }

	button_dev = input_allocate_device();
	if (!button_dev) {
		printk(KERN_ERR "button.c: Not enough memory\n");
		error = -ENOMEM;
		goto err_free_irq;
	}

	button_dev->evbit[0] = BIT_MASK(EV_KEY);
	button_dev->keybit[BIT_WORD(KEY_LEFT)] = BIT_MASK(KEY_LEFT);

	error = input_register_device(button_dev);
	if (error) {
		printk(KERN_ERR "button.c: Failed to register device\n");
		goto err_free_dev;
	}

	return 0;

 err_free_dev:
	input_free_device(button_dev);
 err_free_irq:
	free_irq(BUTTON_IRQ, button_interrupt);
	return error;
}

static void __exit s5pv210_button_exit(void)
{
    input_unregister_device(button_dev);
	free_irq(BUTTON_IRQ, button_interrupt);
}


module_init(s5pv210_button_init);
module_exit(s5pv210_button_exit);

// MODULE_xxx这种宏作用是用来添加模块描述信息
MODULE_LICENSE("GPL");							// 描述模块的许可证
MODULE_AUTHOR("Mark <867439374@qq.com>");		// 描述模块的作者
MODULE_DESCRIPTION("s5pv210 button driver");		// 描述模块的介绍信息
MODULE_ALIAS("s5pv210_button");					// 描述模块的别名信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值