由于按键是机械按键,里面的金属弹片在按下或松开的时候会发生抖动,在这样的条件下按下一次就有可能发生多次中断,为了解决这个问题,我们应该添加防抖动。
我们可以用定时器实现防抖动。假如按下一次产生了多次中断,那么在第一次中断产生之后,调用中断处理函数,在这里面设置10ms之后执行某一个操作,下次中断再来,由于是同一个定时器,定时器的值会清空然后再设置10ms之后执行那个操作,以此类推,直到最后一个中断到来之后才能满足10ms之后执行操作。这样,就可以完成防抖动。具体实现如下。
先定义一个定时器
static struct timer_list buttons_timer;
并在驱动的入口函数里完成对定时器的初始化:
init_timer(&buttons_timer);
buttons_timer.function = buttons_timer_function;
add_timer(&buttons_timer);
然后把所有应该在按键中断里做的事情转移到定时器中断里,并在按键中断里添加一句
//把dev_id记录下来
irq_pd = (struct pin_desc *)dev_id;
//设置10ms之后发生定时器中断
mod_timer(&buttons_timer,jiffies + HZ/100);
在这里面的jiffies是一个系统定义的东西,每过一个系统时钟(10ms)之后jiffies 就会加1。HZ的值是100 。以当前状态jiffies为参照,当jiffies+100/100=jiffies+1,也就是jiffies变化一次(10ms)之后发生定时器中断。当定时器中断发生的时候,就进入到定时器中断的处理函数static void buttons_timer_function(unsigned long data)。在这个函数里所做事情就是按键中断之前做的,唯一不同的是使用了储存在irq_pd里的dev_id,这里的irq_pd是一个全局变量。
大概就这么多了。
以上包括以前所有的都是初级驱动的知识,从下一篇开始要深入一点了,可能会很难,但我会尽力的。