5.按键定时器去抖动

按键定时器去抖动

按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,开关不会马上稳定地接通或断开。因而在闭合及断开的瞬间总是伴有一连串的抖动的。按键去抖动的方法主要有两种,一种是硬件电路去抖动;另一种就是软件延时去抖动。而延时又一般分为了两种,一种是for循环等待,另一种是定时器延时。在操作系统中,由于效率方面的原因,一般不允许使用for循环来等待,只能使用定时器。

上面是内核定时器的结构。其中expires是定时器延时的时间,function函数是定时器超时后要做的事情。

由上面可以知道,定时器的使用分为了四个步骤:1.定义定时器的变量,就是timer_list结构。2.要对结构进行初始化。Init_timer是系统自动运行的初始化函数,能初始化很大部分timer_list里面的成员。但是,超时函数是需要我们自己设置,就是function。3.使用add_timer函数注册定时器。4.mod_timer重启定时器。注意,定时器不是循环的,需要重复调用mod_timer函数。

接下来是例子:

Nkey.c:

#include <linux/module.h>        /* For module specific items */

#include <linux/fs.h>            /* For file operations */

#include <linux/ioport.h>        /* For io-port access */

#include <linux/io.h>            /* For inb/outb/... */

#include <linux/init.h>

#include <linux/miscdevice.h>

#include <linux/interrupt.h>

#include <linux/slab.h>

#define GPNCON 0x7f008830

#define GPNDAT 0x7f008834

struct work_struct *work1;

struct timer_list key_timer;//定义定时器

unsigned int *gpio_data;

void work1_func(struct work_struct *work)

{

//启动定时器 100毫秒超时=HZ/10,HZ=1秒。jiffies是系统当前时间

mod_timer(&key_timer,jiffies+HZ/10);

}

void key_timer_func(unsigned long data)

{

unsigned int key_val;

//超时的时候,就要读取data

key_val=readw(gpio_data)&0x01;//读出一个按键EINT0的值。

//当他被按下,就是低电平的时候,就是被按下了。才是有效的按键

if(0==key_val)//真正按下

printk("<0> key down!\n");

}

irqreturn_t key_int(int irq, void *dev_id)

{

//1.检测是否发生了按键中断

//2.清除已经发生的按键中断

//前面的都是硬件相关的工作,必须在中断里面执行

//下面是硬件无关的工作,我们把它提到中断以外的work1_func函数去处理。

//3.打印按键值

schedule_work(work1);

return 0;

}

void key_hw_init()

{

unsigned int *gpio_config;

unsigned short data;

gpio_config = ioremap(GPNCON,4);

data = readw(gpio_config);

data &= ~0b11;

data |= 0b10;

writew(data,gpio_config);

gpio_data = ioremap(GPNDAT,4);

}

int key_open(struct inode *node, struct file *filp)

{

return 0;

}

struct file_operations key_fops =

{

.open = key_open,

};

struct miscdevice key_miscdevice =

{

.minor = 200,

.name = "OK6410key",

.fops = &key_fops,

};

static int key_init()

{

misc_register(&key_miscdevice);

//硬件初始化

key_hw_init();

//注册中断处理程序

request_irq(IRQ_EINT(0),key_int, IRQF_TRIGGER_FALLING,"OK6410key",0);

//2. 创建工作

work1 = kmalloc(sizeof(struct work_struct),GFP_KERNEL);

INIT_WORK(work1, work1_func);

//定时器初始化

init_timer(&key_timer);

key_timer.function=key_timer_func;

//注册定时器

add_timer(&key_timer);

return 0;

}

static void key_exit()

{

misc_deregister(&key_miscdevice);

}

module_init(key_init);

module_exit(key_exit);

编译成功,拷贝生成的.ko驱动文件到开发板运行。

时间: 2024-11-03 22:15:54

5.按键定时器去抖动的相关文章

为QNetworkAccessManager添加超时提醒(自己记录一段时间里的下载字节数,用定时器去定期检测,从而判断是否超时)

在做更新,在测试异常的时候,在下载过程中,发现如果直接系统禁用了网络,会报错误,可以捕获.但是如果是第三方软件限制程序联网,问题来了. 程序会一直在那里等待,没有异常,也不发送QNetworkAccessManager::finsh和QNetworkReply::error和QNetworkReply::finsh信号. 所以动念头为下载加个超时,但是QNetworkAccessManager,QNetworkReply和QNetworkRequest都没有相关的设置函数.其实仔细想一下,也没有

Linux按键驱动程序设计详解---从简单到不简单

混杂设备驱动模型: 1. 混杂设备描述 在Linux系统中,存在一类字符设备,它们拥有相同的主设备号(10),单次设备号不同,我们称这类设备为混            杂设备(miscdevice).所有的混杂设备形成一个链表,对设备访问时内核根据次设备号查到相应的混杂设备. 混杂设备也是字符设备! linux中使用struct miscdevice来描述一个混杂设备. 2. 混杂驱动注册 Linux中使用misc_register函数来注册一个混杂设备驱动. int  misc_registe

矩阵按键的组合按键触发

/***12个按键,每一个按键都会让蜂鸣器发出“嘀”的一声, 同时按下S1和S12会点亮一个LED灯,同时按下***/#include "REG52.H"#define const_voice_short 40#define const_key_time 12#define const_key_time_comb 14 //组合按键去抖动延时时间void initial_myself();void initial_peripheral();void delay_long(unsigne

Linux驱动之输入子系统框架

    好记性不如烂笔头,整理一下笔记~ Linux驱动之输入子系统框架 输入子系统将该类驱动划分为3部分 1.核心层 input.c 2.设备层 Gpio_keys.c ... 3.事件处理层 Evdev.c 事件处理层为纯软件的东西,设备层涉及底层硬件,它们通过核心层建立联系,对外提供open write等接口. 1.我们首先来看,核心层 input.c如何向外界提供接口 在 input_init 中注册了字符设备驱动 register_chrdev(INPUT_MAJOR, "input&

[国嵌攻略][122][按键定制器去抖]

按键抖动 按键所用的开关为机械弹性开关,当机械触点断开.闭合时,由于机械触点的弹性作用,开关不会马上稳定地接通或断开.因而在闭合及断开的瞬间总伴随有一连串的抖动. 按键去抖动的方法主要有两种,一种是硬件电路去抖:另一种就是软件延时去抖.而延时去抖一般又分为两种,一种是for循环等待,另一种是定时器延时.在操作系统中,由于效率方面的原因,一般不允许使用for循环来等待,只能使用定时器. 内核定时器 Linux内核使用struct timer_list来描述一个定时器: struct timer_l

【CC2530强化实训03】定时器间隔定时实现按键N连击

[CC2530强化实训03]定时器间隔定时实现按键N连击 [题目要求]      2018年全国职业院校技能大赛"物联网技术应用"国赛(高职组)中关于感知层开发的难度陡然增大,三个题目均在Zigbee协议栈下完成.其中第一个题目"仓库温湿度智能控制系统"考查了按键单击.双击和三连击.为了让大家更好的掌握按键的复杂处理思路,在这里通过一个具体的实训案例,讲述通过间隔定时实现按键N连击的基本思路.      在新大陆国赛设备的黑色Zigbee模块上,或者小蜜蜂制作的XM

key单片机按键抖动

为什么会有按键抖动 通常的按键所用开关为机械弹性开关,当机械触点断开.闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开.因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖. 抖动时间 抖动时间的长短由按键的机械特性决定,一般为5ms-10ms.这是一个很重要的时间参数,在很多场合都要用到.点击查看图片按键按键稳定闭合时间的长短则是由操作人员的按键动作决定的,一般为零点几秒至数秒.按键抖动会引起一次按键被误读多次.为

11.按键驱动之定时器防抖(详解)

本节目标: 通过定时器来防止按键抖动,测试程序是使用上节的:阻塞操作的测试程序 1.如下图所示,在没有定时器防抖情况下,按键没有稳定之前会多次进入中断,使得输出多个相同信息出来 2.按键波形图,如下所示: 3.如何消去按键抖动 通过定时器延时10ms,然后每当按键进入中断时就更新定时器延时10ms,若延时10ms到了说明已经过了抖动范围,然后再打印按键电平信息 4.定时器结构体和函数介绍 我们先来看看两个全局变量: jiffies: 是系统时钟,全局变量,默认每隔10ms加1 HZ:是每S的频率

OSAL之按键驱动

本博文根据协议栈1.3.2,尊重原创,注明出处,欢迎转载 学习按键驱动的主要有两大块: 第一:按键引脚设置: 第二:按键事件的触发检测与轮询,以及按键消息的发送 先说明第一大块,按键引脚设置, 超出cc2540片子从机的按键两个按键,按键是共地.所以它的触发方式是下降沿触发按键中断,同时程序对按键按下这个动作检测是中断方式检测,一旦有按键按下,触发一个按键轮询函数执行,同时把对按键的检测方式换成轮询模式.所以对按键引脚设置的内容也就出来了.主要一下几个方面: 1.设置按键映射到的物理引脚GPIO