使用定时器进行按键消抖

.如何消去按键抖动

通过定时器延时10ms,然后每当按键进入中断时就更新定时器延时10ms,若延时10ms到了说明已经过了抖动范围,然后再打印按键电平信息

两个全局变量:

jiffies: 是系统时钟,全局变量,默认每隔10ms加1

HZ:是每S的频率,通过系统时钟换算出来,比如每隔10ms加1,那么HZ就等于100,

1s等于HZ,jiffies+HZ/100意思jiffies+1s/100=jiffies+1000ms/100 =jiffies+10ms所以每个10s加一

.定时器结构体和函数介绍

定时器结构体timer_list:

timer_list常用结构体成员

(1)data         //传递到*function超时处理函数的参数,可以通过参数来获取信息
(2)expires     //定时器到期的时间,当expires小于等于jiffies时,这个定时器便到期并调用定时器超时处理函数,然后就不会再调用了,
                     比如要使用10ms后到期,赋值(jiffies+HZ/100)即可
(3)void (*function)(unsigned long)     //定时器超时处理函数。

定时器常用函数:

init_timer(struct timer_list*) //定时器初始化结构体函数,

add_timer(struct timer_list*) //往系统添加定时器,告诉内核有个定时器结构体

mod_timer(struct timer_list *, unsigned long jiffier_timerout) //修改定时器的超时时间为jiffies_timerout,

                                                                                               当expires小于等于jiffies时,便调用定时器超时处

imer_pending(struct timer_list *) //定时器状态查询,如果在系统的定时器列表中则返回1,否则返回0;

del_timer(struct timer_list*) //删除定时器,在本驱动程序出口函数sixth_drv_exit()里添加

修改驱动程序实现定时器消抖动

1首先定义一个定时器结构体:

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

2在init入口函数中初始化定时器结构体:

init_timer(&buttons_timer); //初始化结构体

/*成员.data未使用

不需要定时器到期时间,所以成员.expires无需初始化,默认为0,由于小于等于jiffies,会进入一次定时器超时函数*/

buttons_timer. function= buttons_timer_ function;

add_timer(&buttons_timer); //告诉内核,有一个定时器

在exit出口函数中删除定时器:

del_timer(&buttons_timer); //删除定时器

4定义全局变量*irq_dev_id,然后在中断服务函数中获取dev_id

struct pin_desc *irq_dev_id ; //定义全局变量获取dev_id

修改中断服务函数:

static irqreturn_t buttons_irq (int irq, void *dev_id) //中断服务函数

{

       irq_dev_id =(struct pin_desc *)dev_id; //获取引脚描述结构体

       /*每产生一次中断,则更新定时器10ms超时 */

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

        return IRQ_RETVAL(IRQ_HANDLED);

}

5当10ms超时到了,进入定时器超时函数,处理*irq_dev_id来判断是哪个按键按下的

static void buttons_timer_function(unsigned long data) //定时器超时函数

{

             unsigned int pin_val=0;

              if(!irq_dev_id) //初始化时,由于定时器.expires成员=0,会进入一次,若irq_dev_id为0则退出

             {

                    printk("expires: timer out\n");

                  return ;

              }

            pin_val=s3c2410_gpio_getpin(irq_dev_id->pin); //获取按键值

           if(pin_val)

           {                   /*按下 (下降沿),清除0x80*/

                           key_val=irq_dev_id->pin_status&0xef;

      }
      else
      {      
                 /*没有按下(上升沿),加上0x80*/
                   key_val=irq_dev_id->pin_status|0x80;
       }
       even_press=1;                                        //退出等待队列
       wake_up_interruptible(&button_wait);                //唤醒 中断
       kill_fasync(&button_async, SIGIO, POLL_IN);        //发送SIGIO信号给应用层
}

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值