;用p1口与4×4键盘相接,横的是p10、p11、p12、p13,纵的扫描线是p14、p15、p16、p17
;扫描结果是0,1,2,3,
; 4,5,6,7,
; 8,9,a,b,
; c,d,e,f
#include<reg51.h>
#include<intrins.h>
#include<absacc.h>
#define uchar unsigned char
uchar rr;
uchar k;
uchar keydata;
void key_scan(void); //键盘函数定义段;
uchar key_tab(uchar k);
void delay(void);
void key_in(uchar k);
//---------------------------------------------------------------
void main(void)
{
while(1)
{
key_scan();
}
}//---------------------------------------------------------------------------------------------
void key_scan(void)
{ uchar sccode,recode,i;
P1=0xf0;
if((P1&0xf0)!=0xf0)
{
delay();
if((P1&0xf0) !=0xf0)
{
sccode=0xfe;
for(i=0;i<4;i++)
{
P1=sccode;
if((P1&0xf0) !=0xf0)
{
recode=(P1&0xf0)|0x0f;
k=(~recode)+(~sccode);
rr=P1;
key_in(k);
break;
}
else
sccode=(sccode<<1)|0x01;
}
}
}
//do {ta=P2;}while(ta==rr);
}
void delay() //去抖动
{int a=2500;
while(--a);
}
void key_in(uchar k)
{ uchar ta;
//uchar keydata;
do {ta=P1;}while(ta==rr);
keydata=key_tab(k);
}
//-------------------------------------------------------------
uchar key_tab(uchar k)
{ uchar kb;
switch(k)
{ case 0x11:kb=0x00;break;
case 0x21:kb=0x01;break;
case 0x41:kb=0x02;break;
case 0x81:kb=0x03;break;
case 0x12:kb=0x04;break;
case 0x22:kb=0x05;break;
case 0x42:kb=0x06;break;
case 0x82:kb=0x07;break;
case 0x14:kb=0x08;break;
case 0x24:kb=0x09;break;
case 0x44:kb=0x0a;break;
case 0x84:kb=0x0b;break;
case 0x18:kb=0x0c;break;
case 0x28:kb=0x0d;break;
case 0x48:kb=0x0e;break;
case 0x88:kb=0x0f;break;
default :kb=0x00;break;
}
return kb;
}
这是汇编语言的4×4矩阵式键盘程序
;用p1口与4×4键盘相接,横的是p10、p11、p12、p13,纵的扫描线是p14、p15、p16、p17
;扫描结果是0,1,2,3,
; 4,5,6,7,
; 8,9,a,b,
; c,d,e,f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;检测按键子程序;;;;;;;;;;;;;;;;;
BUTTON_NUMBER EQU 55H ;键盘扫描结果
KEY_TEST:
MOV P1,#0F0H;
MOV A,P1
ORL A,#0FH
CPL A
JNZ PRESS_BUTTON
AJMP BACK1
PRESS_BUTTON:
CALL DELAY_20MS
MOV R2,#0;存放按键值,从0开始
MOV R4,#4;列扫描次数
MOV R1,#11111110B;扫描第一行
MOV A,R1
L1:
MOV R3,#4
MOV P1,A
MOV A,P1
RRC A;先右循环移动4次,使高四位变成第四位
RRC A
RRC A
RRC A
L2:
RRC A
JNC FIND
INC R2;在1列内没找到,使数字加1
DJNZ R3,L2;判断4列扫描完了没
;MOV A,R2
;ADD A,#4;在1行上没找到,使数字加4
;MOV R2,A
MOV A,R1
RL A;左移扫描下一行
MOV R1,A
DJNZ R5,L1;判断4行扫描完了没
AJMP BACK1
FIND:
CHECK_LOOSE:
MOV P1,#0F0H
MOV A,P1
ORL A,#0FH
CPL A
JNZ CHECK_LOOSE
CALL DELAY_20MS
MOV BUTTON_NUMBER,R2
AJMP BACK1
DELAY_20MS:
MOV R1,#0C8H
L4: MOV R3,#018H
L3: NOP
NOP
DJNZ R3,L3
DJNZ R1,L4
BACK1:
RET