📄 key_scan.c
字号:
// 现在由本机判断按下-〉释放为一个完整的击键后报告给MAIN MCU
//------------------------------------------------------------------------------------
//
// FILE NAME : KEY_SCAN.c
// TARGET DEVICE : C8051F314
// CREATED ON : 07/14/06
// CREATED BY : Jzp
//
// Revision 1.0
//
//------------------------------------------------------------------------------------
// 键盘扫描程序
// - Pinout:
// P1.0 -> 键盘矩阵列选线0
// P1.1 -> 键盘矩阵列选线1
// P1.2 -> 键盘矩阵列选线2
// P1.3 -> 键盘矩阵列选线3
// P1.4 -> 键盘矩阵行选线0
// P1.5 -> 键盘矩阵行选线1
// P1.6 -> 键盘矩阵行选线2
// P1.7 -> 键盘矩阵行选线3
// P2.0 -> 键盘矩阵行选线4
// P2.1 -> 键盘矩阵行选线5
// P2.2 -> 键盘矩阵行选线6
// P2.3 -> 键盘矩阵行选线7
// P2.4 -> 键盘矩阵行选线8
// P2.5 -> 键盘矩阵行选线9
// P2.6 -> 键盘矩阵行选线10
// P2.7 -> alpha LED
// P0.6 -> 键盘中断请求线
//
//------------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------------
#include <c8051f310.h> // SFR declarations
#include <math.h>
#include "..\\inc\\DEFINE.H"
#define KEY_SCAN_GLOBALS
#include "..\\inc\\key_scan.h"
//------------------------------------------------------------------------------------
// 全局变量
//------------------------------------------------------------------------------------
UCHAR KbIsPressed; //=0 表示有键值MAIN MCU未读取
UCHAR PreKeyValue; //当次扫描前的按键键值
//=0x00 表示无按键
//=0xff 表示为无效值
// 键盘状态变量
UCHAR AltKeyOn; //=1 表示当前ALT键切换为ON状态,键值转义
UCHAR AlfaKeyOn; //=1 表示当前alpha键切换为ON状态,键值转义
UCHAR CtlKeyOn; //=1 表示当前ctrl键切换为ON状态,键值转义
UCHAR CapsKeyOn; //=1 表示当前Caps键切换为ON状态,键值转义
UCHAR ShiftKeyOn; //=1 表示当前Caps键切换为ON状态,键值转义
UCHAR KbIsValid; //=1 表示缓冲当前为有效值
UCHAR xdata KeyBlOn_Count; //键盘背光打开计时
UCHAR xdata second; // 秒计时
UCHAR xdata intcount; // 10ms interrupt counter
UCHAR xdata KeyDelayCount;
//UCHAR KeyBuffer[8]; //记录按键扫描码,当按键为通码时,第二个字节放扫描码,第一个
//字节放0xd0,该字节是内部标识符,iic发送程序通过它判断需发送机个字节
extern UINT Tmr0Reload;
extern UCHAR Tmr0High;
extern UCHAR Tmr0Low;
//------------------------------------------------------------------------------------
// 函数原型声明
//------------------------------------------------------------------------------------
UCHAR GetKeyMatrix(void);
void KEY_ROW_LOW(UCHAR index);
//SCHAR OutputPortBit(char PortNum, char Bit, char Value);
//------------------------------------------------------------------------------------
// 常量定义
//------------------------------------------------------------------------------------
#define COLNUM 4
#define ROWNUM 11
//------------------------------------------------------------------------------------
// 键码表
//------------------------------------------------------------------------------------
UCHAR code key_table[][2] = {
0x01, '1',//0x31,
0x02, '2',//0x32,
0x04, '3',//0x33,
0x08, '4',//0x34,
0x11, '5',//0x35,
0x12, '6',//0x36,
0x13, '7',//0x37,
0x14, '8',//0x38,
0x21, '9',//0x39,
0x22, ':',//0x3a,
0x24, ';',//0x3b,
0x28, '<',//0x3c,
0x31, '=',//0x3d,
0x32, '>',//0x3e,
0x34, '?',//0x3f,
0x38, '@',//0x40,
0x41, 'A',//0x41,
0x42, 'B',//0x42,
0x44, 'C',//0x43,
0x48, 'D',//0x44,
0x51, 'E',//0x45,
0x52, 'F',//0x46,
0x54, 'G',//0x47,
0x58, 'H',//0x48,
0x61, 'I',//0x49,
0x62, 'J',//0x4a,
0x64, 'K',//0x4b,
0x68, 'L',//0x4c,
0x71, 'M',//0x4d,
0x72, 'N',//0x4e,
0x74, 'O',//0x4f,
0x78, 'P',//0x50,
0x81, 'Q',//0x51,
0x82, 'R',//0x52,
0x84, 'S',//0x53,
0x88, 'T',//0x54,
0x91, 'U',//0x55,
0x92, 'V',//0x56,
0x94, 'W',//0x57,
0x98, 'X',//0x58,
0xa1, 'Y',//0x59,
0xa2, 'Z',//0x5a,
0xa4, '[',//0x5b,
0xa8, '\\',//0x5c,
0xff, 0
};
//UCHAR code key_table[][2] = {
// 0x01, 1,
// 0x02, 2,
// 0x04, 3,
// 0x08, 4,
// 0x11, 5,
// 0x12, 6,
// 0x13, 7,
// 0x14, 8,
// 0x21, 9,
// 0x22, 10,
// 0x24, 11,
// 0x28, 12,
// 0x31, 13,
// 0x32, 14,
// 0x34, 15,
// 0x38, 16,
// 0x41, 17,
// 0x42, 18,
// 0x44, 19,
// 0x48, 20,
// 0x51, 21,
// 0x52, 22,
// 0x54, 23,
// 0x58, 24,
// 0x61, 25,
// 0x62, 26,
// 0x64, 27,
// 0x68, 28,
// 0x71, 29,
// 0x72, 30,
// 0x74, 31,
// 0x78, 32,
// 0x81, 33,
// 0x82, 34,
// 0x84, 35,
// 0x88, 36,
// 0x91, 37,
// 0x92, 38,
// 0x94, 39,
// 0x98, 40,
// 0xa1, 41,
// 0xa2, 42,
// 0xa4, 43,
// 0xa8, 44,
// 0xff, 0
// };
/************************************************************
-----键盘扫描及取键值程序-----
功能: 扫描键盘
入口参数: 无
出口参数:有按键则键值=阵列号,无按键则键值=0xff
//UCHAR GetKeyMatrix(void)
*************************************************************/
UCHAR GetKeyMatrix(void)
{
UCHAR i;//,j;
UCHAR ColValue = 0; //列线0-3的读取电平存储值
UCHAR CurKeyValue; //初始化无按键
// 扫描开始
CurKeyValue = PreKeyValue;
KEY_ROW_ALL_LOW; //初始行线全部行线输出低电平,试探有无按键
ColValue = P1&0x0f; //读取列线电平
if(ColValue == 0x0f) //当前无按键
{
if(KbIsPressed == 0) //之前无按键
{
CurKeyValue = 0xff; //=0x00 表示无按键
PreKeyValue = 0xff;
return CurKeyValue; //返回无效键值
}
else //有按键释放
{
KbIsPressed = 0;
KbIsValid = 1; //等待MAIN MCU读取
return CurKeyValue;
}
}
//开始逐行扫描
for(i = 0; i < ROWNUM; i++)
{
KEY_ROW_LOW(i); //驱动第i列行线
ColValue = P1&0x0f; //读取列线电平
if(ColValue != 0x0f)
{
KeyDelayCount = 2; //防抖动20ms
while(KeyDelayCount == 0);
ColValue = P1&0x0f; //读取列线电平
if(ColValue != 0x0f) //确实有键按下
{
KeyBlOn_Count = 4; // 背光延时重新计数
KbBlCtl = 1; // 点亮键盘背光
CurKeyValue = ((i << 4)&0xf0) + (~ColValue&0x0f);
KbIsPressed = 1;
break;
} //end if(ColValue != 0x0f) 2
} //end if(ColValue != 0x0f) 1
} //end for
PreKeyValue = CurKeyValue; // 替换原键值
return CurKeyValue;
}
/************************************************************
-----键值转换为扫描码处理程序-----
功能:对特殊功能键作相应处理
入口参数:GetKeyMatrix函数取得的键值
影响:根据键值将相应的特殊键状态赋值,处理有优先级
//void SpeKeyDeal(UCHAR key)
*************************************************************/
void SpeKeyDeal(UCHAR key)
{
switch(key){
case 0x21: // 有CTRL键切换动作
if(CtlKeyOn == 1)
CtlKeyOn = 0;
else
CtlKeyOn = 1;
break;
case 0x22: // 有ALT键切换动作
if(AltKeyOn == 1)
AltKeyOn = 0;
else
AltKeyOn = 1;
break;
case 0x24: // 有ALPHA键切换动作
if(AlfaKeyOn == 1)
AlfaKeyOn = 0;
else
AlfaKeyOn = 1;
break;
case 0x88: // 有SHIFT键切换动作
if(ShiftKeyOn == 1)
ShiftKeyOn = 0;
else
ShiftKeyOn = 1;
break;
default: // 其他键不做处理
break;
}
}
/************************************************************
键值转换为扫描码处理程序
//void PutKbBuff(UCHAR KeyVal)
功能:将键值转换为扫描码,及其无效键处理。
*************************************************************/
/************************************************************
-----键值转换为扫描码处理程序-----
功能:将键值转换为扫描码,及其无效键处理
入口参数:查键值转换表所得扫描码
影响:将扫描码填入KeyBuffer[],等待主机查询
//void SpeKeyDeal(UCHAR key)
*************************************************************/
void PutKbBuff(UCHAR KeyVal)
{
if((AltKeyOn == 1) || (AlfaKeyOn == 1) || (ShiftKeyOn == 1) || (CtlKeyOn == 1))
{
if(AltKeyOn == 1) // ALT组合键
{
KeyBuffer[0] = '!';//0x21;//0xb0;
KeyBuffer[1] = KeyVal;
}
else if(AlfaKeyOn == 1) // 字母键
{
if(ShiftKeyOn == 1)
{
KeyBuffer[0] = '"';//0x22;//0xc0; // 大写
KeyBuffer[1] = KeyVal;
}
else
{
KeyBuffer[0] = '#';//0x23;//0xd0; // 小写
KeyBuffer[1] = KeyVal;
}
}
else if(ShiftKeyOn == 1) // shift组合键
{
KeyBuffer[0] = '$';//0x24;//0xe0;
KeyBuffer[1] = KeyVal;
}
else if(CtlKeyOn == 1) // ctrl组合键
{
KeyBuffer[0] = '%';//0x25; //0xf0;
KeyBuffer[1] = KeyVal;
}
}
else
{
KeyBuffer[0] = '&';//0x26;//0xa0; // 常规按键
KeyBuffer[1] = KeyVal;
}
}
/************************************************************
-----查表程序-----
功能: 通过行列号查找键号
参数: 行列号(ex。0x31 表示第3行第1列)
//说明:
//UCHAR lookup_table(UCHAR matrix)
*************************************************************/
UCHAR lookup_table(UCHAR matrix)
{
UCHAR i;
UCHAR ret_key;
for(i = 0; ((i < 44) && (key_table[i][0] != 0xff)); i++)
{
if(key_table[i][0] == matrix )
{
ret_key = key_table[i][1]; // 找到行列号,转换成键号
break;
}
}
return ret_key;
}
/************************************************************
-----键扫描任务-----
功能: 主程序调用该任务
参数: 行列号(ex。0x31 表示第3行第1列)
//说明:
//void task_keyscan(void)
*************************************************************/
void task_keyscan(void)
{
UCHAR i;
UCHAR temp_mat,temp_code;
temp_mat = 0;
temp_code = 0;
temp_mat = GetKeyMatrix(); //取得键盘阵列号
if(KbIsValid == 1)
{
SpeKeyDeal(temp_mat);
temp_code = lookup_table(temp_mat); //转换为键号
PutKbBuff(temp_code);
KbIrqOut = 0; // 发起中断
for(i = 0; i < 10; i++);
KbIrqOut = 1;
}
}
/************************************************************
-----键扫描相关变量初始化-----
功能: 主程序调用该函数
参数:
//说明:
//void init_keyscan(void)
*************************************************************/
void init_keyscan(void)
{
UCHAR i;
for(i = 0; i < 2; i++)
KeyBuffer[i] = 0;
KbIsPressed = 0;
AltKeyOn = 0; //=1 表示当前ALT键切换为ON状态,键值转义
AlfaKeyOn = 0; //=1 表示当前alpha键切换为ON状态,键值转义
CtlKeyOn = 0; //=1 表示当前ctrl键切换为ON状态,键值转义
CapsKeyOn = 0; //=1 表示当前Caps键切换为ON状态,键值转义
ShiftKeyOn = 0; //=1 表示当前Caps键切换为ON状态,键值转义
KbIsValid = 0; //=1 表示缓冲当前为有效值
KbBlCtl = 1; //复位时点亮背光
KeyBlOn_Count = 4; //背光点亮定时4秒
}
/************************************************************
-----行线输出扫描程序-----
说明: 根据index,将指定行线驱动低电平,其余为高电平
//void KEY_ROW_LOW(UCHAR index)
*************************************************************/
void KEY_ROW_LOW(UCHAR index)
{
// UCHAR i;
UCHAR p1_shift;
UCHAR p2_shift;
UCHAR p2_bit7;
UCHAR temp;
p2_bit7 = P2&0x80; // 暂存P2^7电平
p1_shift = 0x10; // 初始化p1移位初始值
p2_shift = 0x01; // 初始化p2移位初始值,因为P2.7为LED驱动,所以要保持他的值不变
// for(i = 0; i < index; i++)
// {
if(index < 4)
{
p1_shift = p1_shift << index;
p1_shift = ~p1_shift;
P1 = p1_shift;
P2 = (P2&0x80)|0x7f;
}
else //if((i >= 4) && (i < 7))
{
temp = index;
temp = ~(~temp + 4); // 作减4求绝对值运算
// p2_shift <<= abs(4 - index);
p2_shift <<= temp;
P2 = (~p2_shift) | p2_bit7;
P1 = 0xff;
}
// }
}
void Timer0_ISR (void) interrupt 1
{
TR0 = 0;
// TMR0 = Tmr0Reload;
TH0 = Tmr0High;
TL0 = Tmr0Low;
if(KeyDelayCount != 0) KeyDelayCount--;
if(++intcount == 100)
{
intcount = 0;
// if(KeyBlOn_Count != 0) KeyBlOn_Count--;
// if(KeyBlOn_Count != 0)
// {
// KbBlCtl = 1; // 点亮背光
// }
// else
// {
// KbBlCtl = 0; // 关闭背光
// }
// KbBlCtl = ~KbBlCtl;
AlphaLed = ~AlphaLed;
}
TF0 = 0;
TR0 = 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -