基于smart210的按键驱动(定时器防抖)

1.定时器有两个概念:
1,超时时间:
2,时间到了之后的“处理函数”。
可以在中断处理中,如定时 10ms 后处理确定按键值上报。
产生中断

我们先来看看两个全局变量:
jiffies: 是系统时钟,全局变量,默认每隔10ms加1
HZ:是每S的频率,通过系统时钟换算出来,比如每隔10ms加1,那么HZ就等于100

定时器结构体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时,便调用定时器超时处理函数。
timer_pending(struct timer_list ) //定时器状态查询,如果在系统的定时器列表中则返回1,否则返回0;
del_timer(struct timer_list
) //删除定时器,在本驱动程序出口函数sixth_drv_exit()里添加

2.修改驱动程序实现定时器消抖动
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); //告诉内核,有一个定时器

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

4)定义全局变量*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信号给应用层
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值