//--------------------------------------------------------------------------//
// 源程序大公开 //
// (c) Copyright 2001-2005 xuwenjun //
// All Rights Reserved //
// V1.00 //
//--------------------------------------------------------------------------//
//标 题: P1口行列式键盘程序 ? //
//文件名: xwj_hlkey.c //
//版 本: V1.00 //
//修改人: 徐文军 E-mail:xuwenjun@21cn.com //
//日 期: 05-05-13 //
//描 述: P1口行列式键盘程序 ? //
//声 明: //
// 以下代码仅免费提供给学习用途,但引用或修改后必须在文件中声明出处. //
// 如用于商业用途请与作者联系. E-mail:xuwenjun@21cn.com //
// 有问题请mailto xuwenjun@21cn.com 欢迎与我交流! //
//--------------------------------------------------------------------------//
//老版本: 无 老版本文件名: //
//创建人: 徐文军 E-mail:xuwenjun@21cn.com //
//日 期: 05-05-13 //
//描 述: //
// CODE SIZE = 396 ---- //
// CONSTANT SIZE = 32 ---- //
// DATA SIZE = 4 1 //
// BIT SIZE = 1 ---- //
//--------------------------------------------------------------------------//
#include <reg52.h>
#include "xwj_hlkey.h" // P1口行列式键盘 //
//#include "xwj_bp.h" //峰鸣器
#define KEYDELAY 25 /*首键延迟次数*/
#define KEYLOOP 10 /*连续键间隔次数,需小于KEYDELAY*/
unsigned char key_bak;
unsigned char key_temp;
unsigned char key_old;
unsigned char key_data;
bit key_ok;
unsigned char code Tab_key[]= //行列式键盘映射,这个表主要是为了直观
{0x00, //无键按下
'7','8','9','/',
'4','5','6','*',
'1','2','3','-',
'C','0','=','+',
//下面为按'C'同时再按的键:
'7','8','9','/',
'4','5','6','*',
'1','2','3','-',
'0','=','+',};
// P1口行列式键盘 //
#define KEYPIN_L P1 // 定义键扫描列端口为 P1低四位输入 //
#define KEYPIN_H P1 // 定义键扫描行端口为 P1高四位扫描输出 //
//内部私有函数 //
unsigned char fnKeyCode(unsigned char key); // 根据键盘映射表输出顺序键值 //
// P1口行列式键盘 //
//---------------------------------------------------------------------------//
void KeyScan(void) //键扫描
{
unsigned char sccode,recode;
KEYPIN_L = KEYPIN_L|0x0f; // P1低四位为列线输入 //
KEYPIN_H = KEYPIN_H&0x0f; // P1高四位为行线发全零扫描码 //
if ((KEYPIN_L&0x0f) != 0x0f) //有键按下
{
key_temp = 0;
sccode = 0xef; // 逐行扫描码初值(1110 1111) //
while(sccode != 0xff) //将扫描4次,key_temp为每次键值相 或的值 //
{
KEYPIN_H = sccode; // 输出行扫描码 //
if ((KEYPIN_L&0x0f) != 0x0f) // 本行有键按下 //
{
recode = (KEYPIN_L&0x0f)|0xf0; // 只要低位,高位置1 //
key_temp |= (~sccode)+(~recode); //特征码(高位为列P3,低位为行KEYPIN_H) //
}
sccode = (sccode << 1)|0x01; // 扫描码0向高位移动 //
}
if (key_temp == key_bak)
{
key_old++;
if (key_old==KEYDELAY) //连续键,不要则把此if屏蔽
{
key_ok=1;
key_data=fnKeyCode(key_temp); //键解码
key_old=KEYDELAY-KEYLOOP;
}
}
else
{
key_old=0;
key_bak=key_temp;
}
}
else //键抬起
{
if (key_old)
{
key_ok=1;
key_data=fnKeyCode(key_temp); //键解码
/* if (key_old==100) //加上时间,不同时间不同功能,与连续键冲突
{
bp(1);
key_data += 0x10;
}
if (key_old==200)
{
bp(2);
key_data += 0x20;
}
*/
}
key_old=0;
}
KEYPIN_H = KEYPIN_H|0xf0;
}
//---------------------------------------------------------------------------//
unsigned char fnKeyCode(unsigned char key) // 根据键盘映射表输出顺序键值 //
{ //由于我的键盘要考虑多键同时按下,所以这个地方较繁琐,无必要则不必这样解码//
switch(key)
{
case 0x11: // 1 键 //
key = 0x01;
break;
case 0x21: // 2 键 //
key = 0x02;
break;
case 0x41: // 3 键 //
key = 0x03;
break;
case 0x81: // 4 键 //
key = 0x04;
break;
case 0x12: // 5 键 //
key = 0x05;
break;
case 0x22: // 6 键 //
key = 0x06;
break;
case 0x42: // 7 键 //
key = 0x07;
break;
case 0x82: // 8 键 //
key = 0x08;
break;
case 0x14: // 9 键 //
key = 0x09;
break;
case 0x24: // 10 键 //
key = 0x0A;
break;
case 0x44: // 11 键 //
key = 0x0B;
break;
case 0x84: // 12 键 //
key = 0x0C;
break;
case 0x18: // 13 键 //
key = 0x0D;
break;
case 0x28: // 14 键 //
key = 0x0E;
break;
case 0x48: // 15 键 //
key = 0x0F;
break;
case 0x88: // 16 键 //
key = 0x10;
break;
//以下为功能键//
case 0x19: // 'C' +1 键 //
key = 0x11;
break;
case 0x29: // 'C' +2 键 //
key = 0x12;
break;
case 0x49: // 'C' +3 键 //
key = 0x13;
break;
case 0x89: // 'C' +4 键 //
key = 0x14;
break;
case 0x1A: // 'C' +5 键 //
key = 0x15;
break;
case 0x2A: // 'C' +6 键 //
key = 0x16;
break;
case 0x4A: // 'C' +7 键 //
key = 0x17;
break;
case 0x8A: // 'C' +8 键 //
key = 0x18;
break;
case 0x1C: // 'C' +9 键 //
key = 0x19;
break;
case 0x2C: // 'C' +10 键 //
key = 0x1A;
break;
case 0x4C: // 'C' +11 键 //
key = 0x1B;
break;
case 0x8C: // 'C' +12 键 //
key = 0x1C;
break;
// case 0x18: // 'C' +13 键 //
// key = 0x1D;
// break;
case 0x38: // 'C' +14 键 //
key = 0x1D;
break;
case 0x58: // 'C' +15 键 //
key = 0x1E;
break;
case 0x98: // 'C' +16 键 //
key = 0x1F;
break;
default : // 无键 //
key = 0x00;
break;
}
return(Tab_key[key]);
}
unsigned char KeyGetCode(void) //返回按键码
{
key_ok=0;
return(key_data);
}
bit KeyTest(void) //检查有无按键
{
KeyScan(); //键扫描
return(key_ok);
}