这一灵感来源于定时器计数的方法,最后可以实现的效果跟咱们电脑键盘按键的效果一样!我先来介绍下基本原理吧!
采用定时器中断的方法,比如定时器终端我们设置为5ms,我们需要按键按下超过40ms时才算有按键按下,如果按键超过500ms时,我们就确定按键是连续按下的!
那么我就需要一个变量来计数!每次定时器中断时,我们就需要检测下,某个按键是否按下,如果按下,那么我们就把他对应的计数变量加1,如果这个变量等于8(8 = 40ms/5ms)时,我们就给按键的标志位置为1,如果没有按键检测到那个按键没有按下,那么我们就把他对应的按键标志位清零,且他对应的计数变量清零。下面是他的流程图!
下面具体看程序,程序里面有说的很详细,只是我的英语不是怎么样,可能写的不是很通顺,但是我确定,程序肯定是写的令大家满意的!希望大家多多指点!
/*
* @for Key Board
* Usage : First of All ,You Must Add Your Code to Scan Your Board Keys
* : in Function of "unsigned char GetKeyValue(void)";
* : Add function "void CheckKey(void)" into your Timer Interrupter Function;
* : Meanwhile , your should Can modify "TYPECOUNT" to change Count Range;
* : "KEYNUMBER" is a number of key;
* : "LIMITCOUNT_VALUE" is to confirm weather there is key click;
* : "MAXCOUNT_VALUE" is stand for a starting signal to repeat count;
* Author : Chen Zhenwei
* E-mail : ieczw@qq.com
* Date : 2014-04-03
* PS : My English is Poor,So There Must Be a Great Deal of Fault;
*/
/*
* @Get Key Value
* Depend on Your Board,You Must Edit By yourself;
* Return Key Value
* 0 : No Valid Key Value
* >0 : Valid Key Value
*/
unsigned char GetKeyValue(void)
{
unsigned char KeyValue = 0;
// To Add your Code to Get KeyValue
return KeyValue;
}
/*
* Define for Variable Type
* You can Set The Type of Variable According to Your Requirement;
*/
#define TYPECOUNT unsigned char // 0 ~ 255
/*
* Number of Key‘s Value
*/
#define KEYNUMBER 16
/*
* Limit Value of Count
* _ ____ ____________________ __ _
* ___| |_| |__| |__| |_| |______
* | | | | | | | | | | | | |
* 1 2 3 4 5 6 7 8 9 10 11 12 13
* You Can Set KEYNUMBER 6 ~ 9
*/
#define LIMITCOUNT_VALUE 20
/*
* Model of Keeping Down
* _ ____ ________________________________________________
* ___| |_| |__| ....
* | | | | | | | | | | | | | | | | ....
* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
*/
#define MAXCOUNT_VALUE 50
/*
* Declare a Global Variable for Key Count
*/
TYPECOUNT KeyCount[KEYNUMBER];
/*
* Usage :
* Get Value : (KeyFilg & (1<<n))
* 1 : on click
* 0 : no
*/
unsigned long KeyFlag;
typedef void (*FUNC)(void * arg);
FUNC KeyFunction[KEYNUMBER]={
// Register for Key Function
// Key0
// Key1
// Add your Key Function
};
#define NULL 0x0000
/*
* To Check the Key Board
*/
void CheckKey(void)
{
unsigned char ret;
unsigned char i = 0;
ret = GetKeyValue();
for(i=0; i<KEYNUMBER; i++){
if(i+1 == ret){
// Count for Key Which is on Clicking
KeyCount[i] ++;
}
else{
// Clear Key Flag And Count
KeyCount[i] = 0;
KeyFlag &= ~(1<<i);
}
if(KeyCount[i] == LIMITCOUNT_VALUE){
// Set Key Flag ‘1‘
KeyFlag |= (1<<i);
// Do Your Given Key Function
KeyFunction[i](NULL);
}
if(KeyCount[i] > MAXCOUNT_VALUE){
KeyCount[i] = 0;
KeyFlag &= ~(1<<i);
}
}
}
/*
* Key Status
*/
#define KEYDOWN 1L
#define KEYUP 0L
/*
* You Can Use GetKeyStatus(i) to Get The Key Status;
* And In Here , You Don‘t Need to Care About to Clear the Key Flag,
* Because It Will Be Auto to Clear the Key Flag.
*/
unsigned char GetKeyStatus(unsigned char KeyNumber)
{
unsigned long Status;
// Get Status of KeyNumber
Status = KeyFlag&(1<<KeyNumber);
// Clear Key Flag
KeyFlag &= ~(1<<KeyNumber);
return (Status ? KEYDOWN : KEYUP);
}
转载声明:http://blog.csdn.net/ieczw/article/details/22926523
无延时去抖按键实现方法(不耗CPU),布布扣,bubuko.com
原文:http://blog.csdn.net/ieczw/article/details/22926523