AVR 矩阵键盘 程序参考
程序特点:
1.有连续按键功能
2.有组合键功能
3.连续按键起始时间和间隔时间自定义
4.可根据需要扩展组合键
使用方法:
将文件"Keypad.h"和"Keypad.c"放入您的工程,将按键需要执行的函数赋值给对应的函数指针
注:需要执行的函数必须为无参数,无返回值
例:您按下A时需要执行以下函数:
void fun(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
inline void NullFunction(void) { } // 空函数
#define NULL_FUNC NullFunction // 空函数宏定义
#define NULL_FUNC2 ((void(*)(unsigned char))NULL_FUNC)
// 矩阵键盘函数指针声明(一个按键一个指针)
extern void (*p_Key_1)(void);
extern void (*p_Key_2)(void);
extern void (*p_Key_3)(void);
extern void (*p_Key_4)(void);
extern void (*p_Key_5)(void);
extern void (*p_Key_6)(void);
extern void (*p_Key_7)(void);
extern void (*p_Key_8)(void);
extern void (*p_Key_9)(void);
extern void (*p_Key_0)(void);
extern void (*p_Key_A)(void);
extern void (*p_Key_B)(void);
extern void (*p_Key_C)(void);
extern void (*p_Key_D)(void);
extern void (*p_Key_Xing)(void); // 星号键
extern void (*p_Key_Jin)(void); // 井号键
extern void (*p_Key_A_B)(void); // A+B的组合键
// 任意按键按下或弹起的函数指针声明(参数为按键值的ascii字符)
extern void (*p_Key_Down)(unsigned char c);
extern void (*p_Key_Up)(unsigned char c);
// 连续按键的标记
extern volatile unsigned char key_continue_flag;
// 在主循环中调用此函数
extern void KeypadPoll(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"
volatile unsigned char key_continue_flag = 0;
static volatile unsigned char _key_last = KEY_NULL;
static volatile unsigned int _key_count = 0;
static volatile unsigned int _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)(unsigned char c) = NULL_FUNC2;
void (*p_Key_Up)(unsigned char c) = NULL_FUNC2;
static unsigned char _hex_to_ascii(unsigned char h)
{
switch (h)
{
case 0xEB : return '0';
case 0x77 : return '1';
case 0x7B : return '2';
case 0x7D : return '3';
case 0xB7 : return '4';
case 0xBB : return '5';
case 0xBD : return '6';
case 0xD7 : return '7';
case 0xDB : return '8';
case 0xDD : return '9';
case 0x7E : return 'A';
case 0xBE : return 'B';
case 0xDE : return 'C';
case 0xEE : return 'D';
case 0xE7 : return '*';
case 0xED : return '#';
default : return ' ';
}
}
// 内部函数
static inline unsigned char _keypad_scan(void)
{
static unsigned char temp = 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;
}
}
}
}
return KEY_NULL;
}
// 在主循环中调用此函数
void KeypadPoll(void)
{
static unsigned char temp = 0;
temp = _keypad_scan();
if (temp == KEY_NULL)
{
return ;
}
p_Key_Down(_hex_to_ascii(temp));
switch (temp)
{
case KEY_NULL: break;
case 0xEB: p_Key_0(); break;
case 0x77: p_Key_1(); break;
case 0x7B: p_Key_2(); break;
case 0x7D: p_Key_3(); break;
case 0xB7: p_Key_4(); break;
case 0xBB: p_Key_5(); break;
case 0xBD: p_Key_6(); break;
case 0xD7: p_Key_7(); break;
case 0xDB: p_Key_8(); break;
case 0xDD: p_Key_9(); break;
case 0x7E: p_Key_A(); break;
case 0xBE: p_Key_B(); break;
case 0xDE: p_Key_C(); break;
case 0xEE: p_Key_D(); break;
case 0xE7: p_Key_Xing(); break; // *
case 0xED: p_Key_Jin(); break; // #
case 0x3E: p_Key_A_B(); break; // A + B 组合键
// 此处添加其它组合键
default : break;
}
}
阅读(2043) | 评论(0) | 转发(0) |