無延時去抖按鍵實現方法(不耗CPU)

這一靈感來源於定時器計數的方法,最後可以實現的效果跟咱們電腦鍵盤按鍵的效果一樣!我先來介紹下基本原理吧!

採用定時器中斷的方法,比如定時器終端我們設置爲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 : [email protected]
 * 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章