📄 key_board.c
字号:
/**************************************
** Filename: key_board.c
** Describe: 矩阵键盘程序
** Author : 古欣 www.avrvi.com
** Time : 2007-2-15
**************************************/
#include "..\config.h"
const uint8 key_board_table[]={0,1,2,3,
4,5,6,7,
8,9,10,11,
12,13,14,15};
//键值可以任意设定,请不要使用0xFF
//const uint8 key_board_table[]={0,1,2,3,4,5,6,7,8,9,10,11,'A','B','C','D'};
//如果使用中断
#if KEY_USE_INT==1
volatile uint8 KEY_FLAG=0,key=0xff; //加 volatile 允许在中断中修改
#pragma interrupt_handler int_isr:IV_number
void int_isr(void)
{
KEY_FLAG = 1; //中断中标记已经产生按键中断,由于使用低电平触发方式,不用再考虑防抖问题
key = key_board_get_key(); //读取键值
}
#endif
/***********************************************************
** 函数名称: void key_board_int(void)
** 功能描述: 中断脚初始化
** 输 入: 无
** 输出 : 无
** 全局变量: 无
** 调用模块:
** 说明:输入,并使能内部上拉
** 注意:
**********************************************************/
void key_int_init(void)
{
KEY_INT_DDR &=~ (1<<KEY_INT);
KEY_INT_RORT |= (1<<KEY_INT);
GICR |= (1<<INT_BIT); //中断允许位,如INT0
}
/***********************************************************
** 函数名称: void key_board_int(void)
** 功能描述: 矩阵键盘扫描初始化
** 输 入: 无
** 输出 : 无
** 全局变量: 无
** 调用模块:
** 说明:默认初始化为行输出低,列输入,并使能内部上拉
** 注意:
**********************************************************/
void key_board_int(void)
{
KEY_DDR_ROW |= KEY_ROW_ALL; //行输出,低
KEY_PORT_ROW &=~ KEY_ROW_ALL;
KEY_DDR_COL &=~ KEY_COL_ALL; //列输入,并使能内部上拉
KEY_PORT_COL |= KEY_COL_ALL;
#if BEEP_EN ==1
BEEP_DDR |= (1<<BEEP_BIT);
BEEP_PORT &=~ (1<<BEEP_BIT);
#endif
}
/***********************************************************
** 函数名称: uint8 key_board_get_key(void)
** 功能描述: 矩阵键盘扫描并读取键值
** 输 入: 无
** 输出 : 按键的键值,在key_board_table[]定义,无按键返回0xFF
** 全局变量: 无
** 调用模块: void key_board_int(void)
** 说明:通过预定义#define WAIT_KEY_UP设置等待按键抬起(1),不等待按键抬起(0)
** 注意:如果不等待按键抬起,很容易产生粘贴键,注意在程序中处理。
**********************************************************/
uint8 key_board_get_key(void)
{
uint8 key_i=0,temp_key=0;
if(HAVE_KEY_DOWN)
{
#if KEY_USE_INT==0
Delay100us(1); //使用中断进行扫描不加延时
#endif
if(HAVE_KEY_DOWN)
{
#if BEEP_EN ==1
BEEP_PORT |= (1<<BEEP_BIT); //蜂鸣器响
#endif
temp_key = ( KEY_COL_ALL & KEY_PIN_COL ); //读取键值
switch(temp_key)
{
case (KEY_COL_ALL&(~(1<<KEY_COL_0))):
key_i = 0;
break;
case (KEY_COL_ALL&(~(1<<KEY_COL_1))):
key_i = 1;
break;
case (KEY_COL_ALL&(~(1<<KEY_COL_2))):
key_i = 2;
break;
case (KEY_COL_ALL&(~(1<<KEY_COL_3))):
key_i = 3;
break;
// 扩展
#if PER_COL>4
case (KEY_COL_ALL&(~(1<<KEY_COL_4))):
key_i = 4;
break;
#endif
#if PER_COL>5
case (KEY_COL_ALL&(~(1<<KEY_COL_5))):
key_i = 5;
break;
#endif
#if PER_COL>6
case (KEY_COL_ALL&(~(1<<KEY_COL_6))):
key_i = 6;
break;
#endif
#if PER_COL>7
case (KEY_COL_ALL&(~(1<<KEY_COL_7))):
key_i = 7;
break;
#endif
default:break;
}//end switch
//翻转,与初始化恰好相反
KEY_DDR_ROW &=~ KEY_ROW_ALL; //行输入,并使能内部上拉
KEY_PORT_ROW |= KEY_ROW_ALL;
KEY_DDR_COL |= KEY_COL_ALL; //列输出,低
KEY_PORT_COL &=~ KEY_COL_ALL;
NOP(); //等待啊你家安稳定,此步骤不能少
temp_key = ( KEY_ROW_ALL & KEY_PIN_ROW ); //读取翻转后键值
switch(temp_key)
{
case (KEY_ROW_ALL&(~(1<<KEY_ROW_0))):
// key_i += 0; //加零,直接省掉
break;
case (KEY_ROW_ALL&(~(1<<KEY_ROW_1))):
key_i += PER_POW;
break;
case (KEY_ROW_ALL&(~(1<<KEY_ROW_2))):
key_i += PER_POW*2;
break;
case (KEY_ROW_ALL&(~(1<<KEY_ROW_3))):
key_i += PER_POW*3;
break;
// 扩展 PER_POW 最大值为8
#if PER_POW>4
case (KEY_ROW_ALL&(~(1<<KEY_ROW_4))):
key_i += PER_POW*4;
break;
#endif
#if PER_POW>5
case (KEY_ROW_ALL&(~(1<<KEY_ROW_5))):
key_i += PER_POW*5;
break;
#endif
#if PER_POW>6
case (KEY_ROW_ALL&(~(1<<KEY_ROW_6))):
key_i += PER_POW*6;
break;
#endif
#if PER_POW>7
case (KEY_ROW_ALL&(~(1<<KEY_ROW_7))):
key_i += PER_POW*7;
break;
#endif
default:break;
}//end switch
//检测按键抬起
#if WAIT_KEY_UP==1
while((KEY_ROW_ALL & KEY_PIN_ROW)!=KEY_ROW_ALL)
;
#endif
key_board_int(); //恢复键盘IO口的初时状态
}//end if have key
return key_board_table[key_i]; //返回键值
}
else
return 0xFF;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -