AVR 矩阵键盘程序源代码V3.5(有连续按键功能,有组合键功能)
1.有连续按键功能
2.有组合键功能
3.连续按键起始时间和间隔时间自定义
4.可根据需要扩展组合键
使用方法:
将文件"Keypad.h"和"Keypad.c"放入您的工程,将按键需要执行的函数赋值给对应的函数指针
注:需要执行的函数必须为无参数,无返回值
例:您按下A时需要执行以下函数:
voidfun(void)
{
printf("我按下了A");
}
只需执行下列语句
p_Key_A=MenuExit;
并在主循环中调用
KeypadPoll();
以下是两个文件源码
Keypad.h
/******** AVR 4*4矩阵键盘扫描程序 ********
* 版本.........: 3.5
* 作者.........: 陈利栋
* 目标.........: AVR
* 文件名.......: Keypad.h
* 编译器.......: IAR for AVR V5.5
* 创建时间.....: 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个值根据实际情况调整 */
#define KEY_READY_COUNT 2000// 检测按键稳定持续的次数
#define KEY_CONTINUE_START_COUNT 40000// 检测连续按键开始需要的次数
#define KEY_CONTINUE_RUNNING_COUNT 3000// 连续按键间隔检测次数
#define KEY_NULL 0xff
inlinevoidNullFunction(void){}// 空函数
#define NULL_FUNC NullFunction// 空函数宏定义
#define NULL_FUNC2 ((void(*)(unsigned char))NULL_FUNC)
// 矩阵键盘函数指针声明(一个按键一个指针)
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的组合键
// 任意按键按下或弹起的函数指针声明(参数为按键值的ascii字符)
externvoid(*p_Key_Down)(unsignedcharc);
externvoid(*p_Key_Up)(unsignedcharc);
// 连续按键的标记
externvolatileunsignedcharkey_continue_flag;
// 在主循环中调用此函数
externvoidKeypadPoll(void);
#endif/* __KEYPAD_H__ */
Keypad.c
/******** AVR 4*4矩阵键盘扫描程序 ********
* 版本.........: 3.5
* 作者.........: 陈利栋
* 目标.........: AVR
* 文件名.......: Keypad.c
* 编译器.......: IAR for AVR V5.5
* 创建时间.....: 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;
// 矩阵键盘函数指针(一个按键一个指针)
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的组合键
// 任意按键按下或弹起的函数指针(参数为按键值的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 ;
}
}
// 内部函数
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;
}
// 在主循环中调用此函数
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;
}
}
AVR矩阵键盘连续按键组合 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)