矩阵键盘源程序(详细)

//头文件
#include //特殊功能寄存器定义

//端口定义:
sbit LED1 = P1^0; //LED1 <--> P1口0引脚, 低电平亮
sbit BUZZER = P2^5; //蜂鸣器,低电平鸣叫


//四联体7段数码显示器
//连线:段 ==> P0, 位选 ==> P2^0.1.2.3
unsigned char code NumTable[16]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共阳,0~F,无小数点
#define numValue P0
sbit numcom1 = P2^0;
sbit numcom2 = P2^1;
sbit numcom3 = P2^2;
sbit numcom4 = P2^3;
sbit dpPin = P0^7; //小数位引脚
unsigned char NumBuffer[4]= {1,2,3,4}; //四联体数码显示缓存
unsigned char dpLocation = 9; //小数点位置,非0~3时不显示


//按键矩阵4*4
//★★★★★★★★★★★★★注意:将J2断路帽跳接到"KBD"★★★★★★★★★
//连线:Row_0.1.2.3 => P3^0.1.2.3; Col_0.1.2.3 => P3^7.6.5.4
#define KEY_PORT P3 //按键接口
bit bKeyPressed; //是否有键按下
unsigned char KeyValue; //键值


//函数申明
void delay(unsigned int n);
void kbdScan(void); //按键矩阵扫描子程序
unsigned char kbdKeyRead(void); //读键值子程序
bit kbdIsKeyDown(void); //是否有键按下
void NumDisplay(void); //四联体数码管动态扫描显示子程序

//主程序
void main()
{
//端口初始化
P0=0xFF;
P1=0xFF;
P2=0xFF;
P3=0xFF;

while(1)
{
kbdScan(); //矩阵按键扫描
LED1 = ~kbdIsKeyDown();

NumDisplay(); //四联体数码动态扫描显示

delay(2); //延时2ms
}
}


//延时子程序
//12MHz晶振,AT89S52 : 1ms
//测试结果:n=1, 1.015ms; n=10, 10.006ms;
void delay(unsigned int n)
{
unsigned int i,j;
for(i=0;i{
for(j=0;j<123;j++)
{
;
}
}

}


//四联体数码管动态扫描显示子程序
void NumDisplay(void)
{
static unsigned char NumDisplayIndex = 0; //显示指针
switch(NumDisplayIndex)
{
case 0: //左起第1位
numcom4 = 1;
numcom1 = 0;
numValue = NumTable[NumBuffer[0]];
if(dpLocation==0){dpPin=0;} //小数点
NumDisplayIndex++;
break;

case 1: //左起第2位
numcom1 = 1;
numcom2 = 0;
numValue = NumTable[NumBuffer[1]];
if(dpLocation==1){dpPin=0;} //小数点
NumDisplayIndex++;
break;

case 2: //左起第3位
numcom2 = 1;
numcom3 = 0;
numValue = NumTable[NumBuffer[2]];
if(dpLocation==2){dpPin=0;} //小数点
NumDisplayIndex++;
break;

case 3: //左起第4位
numcom3 = 1;
numcom4 = 0;
numValue = NumTable[NumBuffer[3]];
if(dpLocation==3){dpPin=0;} //小数点
NumDisplayIndex=0;
break;

default:
NumDisplayIndex=0;

}
}


//按键矩阵扫描子程序
void kbdScan(void)
{
#define keypad_0 kbdIsKeyDown() //定义端口
#define keypad_0_DOWN 1 //定义按键"按下"时的电平
#define keypad_0_UP 0 //定义按键"释放"时的

电平

static unsigned char mKey0SwapTask=0; //定义按键过程状态标记
static unsigned char mKey0Value=0;

switch(mKey0SwapTask) //按键iKey7检测 mKey0SwapTask:按键过程状态标记
{
case 0: //有按键按下吗?
if(keypad_0==keypad_0_DOWN)
{
mKey0SwapTask=1;
mKey0Value=kbdKeyRead(); //读键值
}
break;

case 1: //键按下去抖延时
mKey0SwapTask=2; //延时一个系统时间
break;

case 2: //键值判断
if(keypad_0==keypad_0_DOWN && kbdKeyRead()==mKey0Value)//"按下"有效
{
//////////////////////////////////////////

//这里执行按键"按下"时要做的事情
KeyValue = mKey0Value;
if(KeyValue<16)
{
NumBuffer[0]= KeyValue;
}

//////////////////////////////////////////
mKey0SwapTask=3;
}
else mKey0SwapTask=0; //抖动
break;

case 3: //有松开吗?
if(keypad_0==keypad_0_UP)//判断按键是否松开
{
mKey0SwapTask=4;
}

//////////////////////////////////////////

//这里执行按键"按住"时要做的事情

//////////////////////////////////////////

break;


case 4: //键松开去抖延时
mKey0SwapTask=5; //延时一个系统时间
break;

case 5: //键值判断
if(keypad_0==keypad_0_UP) //"释放"有效
{
//////////////////////////////////////////

//这里执行按键"释放"时要做的事情

//////////////////////////////////////////
mKey0SwapTask=0; //去按键检测开始
}
else mKey0SwapTask=3; //抖动
break;

default:
mKey0SwapTask = 0;
}
}


//读键值(高四位代表行,低四位代表列)
unsigned char kbdKeyRead(void)
{
unsigned char keycode;

KEY_PORT = 0x0F; //列置低,行置高
keycode = KEY_PORT & 0x0F; //扫描行
//NumBuffer[2]=((KEY_PORT & 0x0F)^0x0F);
NumBuffer[3]=((KEY_PORT & 0x0F));

KEY_PORT = 0xF0; //列置高,行置低
keycode |= KEY_PORT & 0xF0; //扫描列
//NumBuffer[3]=(((KEY_PORT & 0xF0)^0xF0)>>4);
NumBuffer[2]=(((KEY_PORT & 0xF0))>>4);

switch(keycode)
{
case 0x7E: keycode=0; break;
case 0xBE: keycode=1; break;
case 0xDE: keycode=2; break;
case 0xEE: keycode=3; break;

case 0x7D: keycode=4; break;
case 0xBD: keycode=5; break;
case 0xDD: keycode=6; break;
case 0xED: keycode=7; break;

case 0x7B: keycode=8; break;
case 0xBB: keycode=9; break;
case 0xDB: keycode=10; break;
case 0xEB: keycode=11; break;

case 0x77: keycode=12; break;
case 0xB7: keycode=13; break;
case 0xD7: keycode=14; break;
case 0xE7: keycode=15; break;

default:keycode=0xFF;
}
return(keycode);
}

//判断是否有键

按下
bit kbdIsKeyDown(void)
{
KEY_PORT = 0x0F; //扫描码:列置低,行置高
if(0x0F==KEY_PORT)
{
return(0); //无键按下
}
else
{
return(1); //有键按下
}
//return(0x0F==KEY_PORT);
}

相关文档
最新文档