AVR 矩陣鍵盤程序源代碼V3.5(有連續(xù)按鍵功能,有組合鍵功能)
1.有連續(xù)按鍵功能
2.有組合鍵功能
3.連續(xù)按鍵起始時間和間隔時間自定義
4.可根據(jù)需要擴展組合鍵
使用方法:
將文件"Keypad.h"和"Keypad.c"放入您的工程,將按鍵需要執(zhí)行的函數(shù)賦值給對應(yīng)的函數(shù)指針
注:需要執(zhí)行的函數(shù)必須為無參數(shù),無返回值
例:您按下A時需要執(zhí)行以下函數(shù):
voidfun(void)
{
printf("我按下了A");
}
{
printf("我按下了A");
}
只需執(zhí)行下列語句
p_Key_A=MenuExit;
并在主循環(huán)中調(diào)用
KeypadPoll();
以下是兩個文件源碼
Keypad.h
/******** AVR 4*4矩陣鍵盤掃描程序 ********
* 版本.........: 3.5
* 作者.........: 陳利棟
* 目標.........: AVR
* 文件名.......: Keypad.h
* 編譯器.......: IAR for AVR V5.5
* 創(chuàng)建時間.....: 2010.09.12
* 最后修改.....: 2010.10.09
*****************************************/
#ifndef __KEYPAD_H__
#define __KEYPAD_H__
#includeavr.h>
#include "delay.h"
#define KEYPAD_PORT PORTC
#define KEYPAD_DDR DDRC
#define KEYPAD_PIN PINC
/* 以下3個值根據(jù)實際情況調(diào)整 */
#define KEY_READY_COUNT 2000// 檢測按鍵穩(wěn)定持續(xù)的次數(shù)
#define KEY_CONTINUE_START_COUNT 40000// 檢測連續(xù)按鍵開始需要的次數(shù)
#define KEY_CONTINUE_RUNNING_COUNT 3000// 連續(xù)按鍵間隔檢測次數(shù)
#define KEY_NULL 0xff
inlinevoidNullFunction(void){}// 空函數(shù)
#define NULL_FUNC NullFunction// 空函數(shù)宏定義
#define NULL_FUNC2 ((void(*)(unsigned char))NULL_FUNC)
// 矩陣鍵盤函數(shù)指針聲明(一個按鍵一個指針)
externvoid(*p_Key_1)(void);
externvoid(*p_Key_2)(void);
externvoid(*p_Key_3)(void);
externvoid(*p_Key_4)(void);
externvoid(*p_Key_5)(void);
externvoid(*p_Key_6)(void);
externvoid(*p_Key_7)(void);
externvoid(*p_Key_8)(void);
externvoid(*p_Key_9)(void);
externvoid(*p_Key_0)(void);
externvoid(*p_Key_A)(void);
externvoid(*p_Key_B)(void);
externvoid(*p_Key_C)(void);
externvoid(*p_Key_D)(void);
externvoid(*p_Key_Xing)(void);// 星號鍵
externvoid(*p_Key_Jin)(void);// 井號鍵
externvoid(*p_Key_A_B)(void);// A+B的組合鍵
// 任意按鍵按下或彈起的函數(shù)指針聲明(參數(shù)為按鍵值的ascii字符)
externvoid(*p_Key_Down)(unsignedcharc);
externvoid(*p_Key_Up)(unsignedcharc);
// 連續(xù)按鍵的標記
externvolatileunsignedcharkey_continue_flag;
// 在主循環(huán)中調(diào)用此函數(shù)
externvoidKeypadPoll(void);
#endif/* __KEYPAD_H__ */
* 版本.........: 3.5
* 作者.........: 陳利棟
* 目標.........: AVR
* 文件名.......: Keypad.h
* 編譯器.......: IAR for AVR V5.5
* 創(chuàng)建時間.....: 2010.09.12
* 最后修改.....: 2010.10.09
*****************************************/
#ifndef __KEYPAD_H__
#define __KEYPAD_H__
#include
#include "delay.h"
#define KEYPAD_PORT PORTC
#define KEYPAD_DDR DDRC
#define KEYPAD_PIN PINC
/* 以下3個值根據(jù)實際情況調(diào)整 */
#define KEY_READY_COUNT 2000// 檢測按鍵穩(wěn)定持續(xù)的次數(shù)
#define KEY_CONTINUE_START_COUNT 40000// 檢測連續(xù)按鍵開始需要的次數(shù)
#define KEY_CONTINUE_RUNNING_COUNT 3000// 連續(xù)按鍵間隔檢測次數(shù)
#define KEY_NULL 0xff
inlinevoidNullFunction(void){}// 空函數(shù)
#define NULL_FUNC NullFunction// 空函數(shù)宏定義
#define NULL_FUNC2 ((void(*)(unsigned char))NULL_FUNC)
// 矩陣鍵盤函數(shù)指針聲明(一個按鍵一個指針)
externvoid(*p_Key_1)(void);
externvoid(*p_Key_2)(void);
externvoid(*p_Key_3)(void);
externvoid(*p_Key_4)(void);
externvoid(*p_Key_5)(void);
externvoid(*p_Key_6)(void);
externvoid(*p_Key_7)(void);
externvoid(*p_Key_8)(void);
externvoid(*p_Key_9)(void);
externvoid(*p_Key_0)(void);
externvoid(*p_Key_A)(void);
externvoid(*p_Key_B)(void);
externvoid(*p_Key_C)(void);
externvoid(*p_Key_D)(void);
externvoid(*p_Key_Xing)(void);// 星號鍵
externvoid(*p_Key_Jin)(void);// 井號鍵
externvoid(*p_Key_A_B)(void);// A+B的組合鍵
// 任意按鍵按下或彈起的函數(shù)指針聲明(參數(shù)為按鍵值的ascii字符)
externvoid(*p_Key_Down)(unsignedcharc);
externvoid(*p_Key_Up)(unsignedcharc);
// 連續(xù)按鍵的標記
externvolatileunsignedcharkey_continue_flag;
// 在主循環(huán)中調(diào)用此函數(shù)
externvoidKeypadPoll(void);
#endif/* __KEYPAD_H__ */
Keypad.c
/******** AVR 4*4矩陣鍵盤掃描程序 ********
* 版本.........: 3.5
* 作者.........: 陳利棟
* 目標.........: AVR
* 文件名.......: Keypad.c
* 編譯器.......: IAR for AVR V5.5
* 創(chuàng)建時間.....: 2010.09.12
* 最后修改.....: 2010.10.09
*****************************************/
#include "Keypad.h"
volatileunsignedcharkey_continue_flag=0;
staticvolatileunsignedchar_key_last=KEY_NULL;
staticvolatileunsignedint_key_count=0;
staticvolatileunsignedint_key_continue_count=0;
// 矩陣鍵盤函數(shù)指針(一個按鍵一個指針)
void(*p_Key_1)(void)=NULL_FUNC;
void(*p_Key_2)(void)=NULL_FUNC;
void(*p_Key_3)(void)=NULL_FUNC;
void(*p_Key_4)(void)=NULL_FUNC;
void(*p_Key_5)(void)=NULL_FUNC;
void(*p_Key_6)(void)=NULL_FUNC;
void(*p_Key_7)(void)=NULL_FUNC;
void(*p_Key_8)(void)=NULL_FUNC;
void(*p_Key_9)(void)=NULL_FUNC;
void(*p_Key_0)(void)=NULL_FUNC;
void(*p_Key_A)(void)=NULL_FUNC;
void(*p_Key_B)(void)=NULL_FUNC;
void(*p_Key_C)(void)=NULL_FUNC;
void(*p_Key_D)(void)=NULL_FUNC;
void(*p_Key_Xing)(void)=NULL_FUNC;// 星號鍵
void(*p_Key_Jin)(void)=NULL_FUNC;// 井號鍵
void(*p_Key_A_B)(void)=NULL_FUNC;// A+B的組合鍵
// 任意按鍵按下或彈起的函數(shù)指針(參數(shù)為按鍵值的ascii字符)
void(*p_Key_Down)(unsignedcharc)=NULL_FUNC2;
void(*p_Key_Up)(unsignedcharc)=NULL_FUNC2;
staticunsignedchar_hex_to_ascii(unsignedcharh)
{
switch(h)
{
case0xEB:return0;
case0x77:return1;
case0x7B:return2;
case0x7D:return3;
case0xB7:return4;
case0xBB:return5;
case0xBD:return6;
case0xD7:return7;
case0xDB:return8;
case0xDD:return9;
case0x7E:returnA;
case0xBE:returnB;
case0xDE:returnC;
case0xEE:returnD;
case0xE7:return*;
case0xED:return#;
default:return ;
}
}
// 內(nèi)部函數(shù)
staticinlineunsignedchar_keypad_scan(void)
{
staticunsignedchartemp=0;
KEYPAD_DDR=0x0f;
KEYPAD_PORT=0xf0;
_delay_us(5);
temp=KEYPAD_PIN;
KEYPAD_DDR=0xf0;
KEYPAD_PORT=0x0f;
_delay_us(5);
temp|=KEYPAD_PIN;
if(temp!=_key_last)
{
_key_count++;
if(_key_count>=KEY_READY_COUNT)
{
if(temp==KEY_NULL)
{
p_Key_Up(_hex_to_ascii(_key_last));
}
_key_last=temp;
_key_count=0;
return_key_last;
}
key_continue_flag=0;
_key_continue_count=0;
}
else
{
_key_count=0;
if(_key_last!=KEY_NULL)
{
_key_continue_count++;
if(key_continue_flag==0)
{
if(_key_continue_count>=KEY_CONTINUE_START_COUNT)
{
key_continue_flag=1;
_key_continue_count=0;
return_key_last;
}
}
else
{
if(_key_continue_count>=KEY_CONTINUE_RUNNING_COUNT)
{
_key_continue_count=0;
return_key_last;
}
}
}
}
returnKEY_NULL;
}
// 在主循環(huán)中調(diào)用此函數(shù)
voidKeypadPoll(void)
{
staticunsignedchartemp=0;
temp=_keypad_scan();
if(temp==KEY_NULL)
{
return;
}
p_Key_Down(_hex_to_ascii(temp));
switch(temp)
{
caseKEY_NULL:break;
case0xEB:p_Key_0();break;
case0x77:p_Key_1();break;
case0x7B:p_Key_2();break;
case0x7D:p_Key_3();break;
case0xB7:p_Key_4();break;
case0xBB:p_Key_5();break;
case0xBD:p_Key_6();break;
case0xD7:p_Key_7();break;
case0xDB:p_Key_8();break;
case0xDD:p_Key_9();break;
case0x7E:p_Key_A();break;
case0xBE:p_Key_B();break;
case0xDE:p_Key_C();break;
case0xEE:p_Key_D();break;
case0xE7:p_Key_Xing();break;// *
case0xED:p_Key_Jin();break;// #
case0x3E:p_Key_A_B();break;// A + B 組合鍵
// 此處添加其它組合鍵
default:break;
}
}
* 版本.........: 3.5
* 作者.........: 陳利棟
* 目標.........: AVR
* 文件名.......: Keypad.c
* 編譯器.......: IAR for AVR V5.5
* 創(chuàng)建時間.....: 2010.09.12
* 最后修改.....: 2010.10.09
*****************************************/
#include "Keypad.h"
volatileunsignedcharkey_continue_flag=0;
staticvolatileunsignedchar_key_last=KEY_NULL;
staticvolatileunsignedint_key_count=0;
staticvolatileunsignedint_key_continue_count=0;
// 矩陣鍵盤函數(shù)指針(一個按鍵一個指針)
void(*p_Key_1)(void)=NULL_FUNC;
void(*p_Key_2)(void)=NULL_FUNC;
void(*p_Key_3)(void)=NULL_FUNC;
void(*p_Key_4)(void)=NULL_FUNC;
void(*p_Key_5)(void)=NULL_FUNC;
void(*p_Key_6)(void)=NULL_FUNC;
void(*p_Key_7)(void)=NULL_FUNC;
void(*p_Key_8)(void)=NULL_FUNC;
void(*p_Key_9)(void)=NULL_FUNC;
void(*p_Key_0)(void)=NULL_FUNC;
void(*p_Key_A)(void)=NULL_FUNC;
void(*p_Key_B)(void)=NULL_FUNC;
void(*p_Key_C)(void)=NULL_FUNC;
void(*p_Key_D)(void)=NULL_FUNC;
void(*p_Key_Xing)(void)=NULL_FUNC;// 星號鍵
void(*p_Key_Jin)(void)=NULL_FUNC;// 井號鍵
void(*p_Key_A_B)(void)=NULL_FUNC;// A+B的組合鍵
// 任意按鍵按下或彈起的函數(shù)指針(參數(shù)為按鍵值的ascii字符)
void(*p_Key_Down)(unsignedcharc)=NULL_FUNC2;
void(*p_Key_Up)(unsignedcharc)=NULL_FUNC2;
staticunsignedchar_hex_to_ascii(unsignedcharh)
{
switch(h)
{
case0xEB:return0;
case0x77:return1;
case0x7B:return2;
case0x7D:return3;
case0xB7:return4;
case0xBB:return5;
case0xBD:return6;
case0xD7:return7;
case0xDB:return8;
case0xDD:return9;
case0x7E:returnA;
case0xBE:returnB;
case0xDE:returnC;
case0xEE:returnD;
case0xE7:return*;
case0xED:return#;
default:return ;
}
}
// 內(nèi)部函數(shù)
staticinlineunsignedchar_keypad_scan(void)
{
staticunsignedchartemp=0;
KEYPAD_DDR=0x0f;
KEYPAD_PORT=0xf0;
_delay_us(5);
temp=KEYPAD_PIN;
KEYPAD_DDR=0xf0;
KEYPAD_PORT=0x0f;
_delay_us(5);
temp|=KEYPAD_PIN;
if(temp!=_key_last)
{
_key_count++;
if(_key_count>=KEY_READY_COUNT)
{
if(temp==KEY_NULL)
{
p_Key_Up(_hex_to_ascii(_key_last));
}
_key_last=temp;
_key_count=0;
return_key_last;
}
key_continue_flag=0;
_key_continue_count=0;
}
else
{
_key_count=0;
if(_key_last!=KEY_NULL)
{
_key_continue_count++;
if(key_continue_flag==0)
{
if(_key_continue_count>=KEY_CONTINUE_START_COUNT)
{
key_continue_flag=1;
_key_continue_count=0;
return_key_last;
}
}
else
{
if(_key_continue_count>=KEY_CONTINUE_RUNNING_COUNT)
{
_key_continue_count=0;
return_key_last;
}
}
}
}
returnKEY_NULL;
}
// 在主循環(huán)中調(diào)用此函數(shù)
voidKeypadPoll(void)
{
staticunsignedchartemp=0;
temp=_keypad_scan();
if(temp==KEY_NULL)
{
return;
}
p_Key_Down(_hex_to_ascii(temp));
switch(temp)
{
caseKEY_NULL:break;
case0xEB:p_Key_0();break;
case0x77:p_Key_1();break;
case0x7B:p_Key_2();break;
case0x7D:p_Key_3();break;
case0xB7:p_Key_4();break;
case0xBB:p_Key_5();break;
case0xBD:p_Key_6();break;
case0xD7:p_Key_7();break;
case0xDB:p_Key_8();break;
case0xDD:p_Key_9();break;
case0x7E:p_Key_A();break;
case0xBE:p_Key_B();break;
case0xDE:p_Key_C();break;
case0xEE:p_Key_D();break;
case0xE7:p_Key_Xing();break;// *
case0xED:p_Key_Jin();break;// #
case0x3E:p_Key_A_B();break;// A + B 組合鍵
// 此處添加其它組合鍵
default:break;
}
}
評論