2015年(109)
分类:
2015-01-23 16:37:37
原文地址:基于SEP4020的5X5键盘驱动开发 作者:myleeming
1. 首先定义一个定时器的结构体:static struct timer_list key_timer;
2. 在驱动的初始化中对定时器进行初始化 setup_timer(&key_timer,key_timer_handler,0);其中key_timer是我们刚刚定义的定时器结构体,key_timer_handler是我们的定时器处理函数;
3. 在想使用定时器的地方(主要是中断中使用,因为定时器的使用可以减少在中断中的等待,有点linux中断的底半部机制的感觉)添加以下代码:
key_timer.expires = jiffies + KEY_TIMER_DELAY1;//设定了linux的延迟时间
add_timer(&key_timer);//启动定时器
4. 编写你的定时器处理函数,注意如果你的定时器使用的地方是在中断中,那相应的在应该在定时器结束的最好开中断。(给一个定时器处理函数的样例)
5. 方便理解下面给出一个定时器使用的样例,就是一个5X5的键盘驱动,硬件是基于arm720T的东南大学sep4020处理器,操作系统版本为linux
基本思想:1.键盘来一个中断,进入中断处理函数,并设定此时键盘状态为UNSURE(因为此时不确定是正常击键行为还是抖动).
2.在中断处理函数的最后启动一个延时20ms的定时器(这个定时器的作用是检查是不是抖动),在20ms到期后进入定时器处理函数,判断硬件上是否有键按着,若没有,则显然是抖动,将键盘状态设定为初始值UP,退出定时器处理函数。若有键按着,则是用户正常击键行为,因此将键盘状态设定为DOWN,并记录键值,启动一个100ms的定时器,这个定时器的作用是判断用户何时松开键盘(注意这里是100ms的定时器,与刚才的20ms不同)。
3. 在100ms定时器到期之后,依旧会进入此中断处理函数,此时还是判断键是否被按下,若还是按下,则要判断键盘的状态,如果是UNSURE则说明是刚从中断处理函数出来的正常击键行为,就是刚刚2的操作,如果键盘状态是DOWN则说明此次击键行为只是上次击键的延续,由于在2中已记录键值,因此在此处只需继续添加定时器延时,等待用户松开键盘即可。
static void key_timer_handler(void)
{
int j = 0;
j = *(volatile unsigned long*)GPIO_PORTA_DATA_V;
if ((j&0x
{
if(keystatus == KEY_UNSURE)//看键值是什么,UNSURE,进入步骤2
{
keystatus = KEY_DOWN;
keyevent();
real_keynum = keynum;//记录键值
wake_up_interruptible(&button_waitq);
key_timer.expires = jiffies + KEY_TIMER_DELAY2;//这是第二次添加定时器,
add_timer(&key_timer);
}
else //键没有松开,但是键的状态不是UNSURE,说明是上次击键的延续,只需延时即可
{
key_timer.expires = jiffies + KEY_TIMER_DELAY2;
add_timer(&key_timer);
}
}
else//键松开,退出,因为键值在DOWN的时候就记录了,所以什么都不用做
{
keystatus = KEY_UP;
unmaskkey();
}
}