单片机控制的矩阵键盘扫描程序集
各种各样的矩阵键盘扫描程序集
矩阵键盘的扫描对初学者来说是不可避免的,然而也相对来说有点难度.
鉴于此,我整理了一下,我所遇到的矩阵键盘扫描程序集,将相继贴上来,供大家参考!
说明:这些大多都是网上转贴来的,其所有权归原作者!
谢谢合作.
最简单矩阵键盘扫描程序
key:MOVp0,#00001111b;上四位和下四位分别为行和列,所以送出高
低电压检查有没有按键按下
jmpk10;跳到K10处开始扫描,这里可以改成其它条件转移指令来决
定本次扫描是否要继续,例如减1 为0 转移或者位为1 或0 才转移,这主 |
到程序尾部,不要浪费CPU的时间
k10:jbp0.0,k20;扫描正式开始,先检查列1四个键是否有键按下,
如果没有,则跳到K20检查列2
k11:MOVp0,#11101111b;列1有键按下时,P0.0变低,到底是那一个键
按下?现在分别输出各行低电平
jbp0.0,k12;该行的键不按下时,p0.0为高电平,跳到到K12,检查其
它的行
MOVr1,#1;如果正好是这行的键按下,将寄存器R0写下1,表示1号键
按下了
k12:MOVp0,#11011111b
jbp0.0,k13
MOV r1,#2;如果正好是这行的键按下,将寄存器R0写下2,表示2号键
按下了
k13:MOVp0,#10111111b
jbp0.0,k14
MOVr1,#3;如果正好是这行的键按下,将寄存器R0写下3,表示3号键
按下了
k14:MOVp0,#01111111b
jbp0.0,kend;如果现在四个键都没有按下,可能按键松开或干扰,
退出扫描(以后相同)
MOVr1,#4如果正好是这行的键按下,将寄存器R0写下4,表示4号键
按下了
jmpkend;已经找到按下的键,跳到结尾吧
k20:jbp0.1,k30;列2检查为高电平再检查列3、4
k21:MOVp0,#11101111b;列2有健按下时,P0.0会变低,到底是那一
行的键按下呢?分别输出行的低电平
jb p0.1,k22;该行的键不按下时p0.0 为高电平,跳到到K22,检查另 |
MOVr1,#6
k23:MOVp0,#10111111b
jbp0.1,k24
MOVr1,#7
k24:MOVp0,#01111111b
jbp0.1,kend
MOVr1,#8
jmpkend;已经找到按下的键,跳到结尾吧(以后相同,不要重复了
)
k30:jbp0.2,k40
k31:MOVp0,#11101111b
jbp0.2,k32
MOV r1,#9 | |
MOVr1,#10
k33:MOVp0,#10111111b
jbp0.2,k34
MOVr1,#11
k34:MOVp0,#01111111b
jbp0.2,kend
MOVr1,#12
jmpkend
k40:jbp0.3,kend
k41:MOVp0,#11101111b
jbp0.3,k42
MOVr1,#13
k42:MOVp0,#11011111b
jbp0.3,k43
MOVr1,#14
k43:MOVp0,#10111111b
jbp0.3,k44
MOVr1,#15
k44:MOV p0,#01111111b |
#include<reg52.h>
#define ulong #define uint | unsigned long |
externvoid delay(unsigned int x);
unsignedchar Tab_key[]= //行列式键盘映射
{0x00, //无键按下
’’7’’,’’8’’,’’9’’,’’/’’,
’’4’’,’’5’’,’’6’’,’’*’’,
’’1’’,’’2’’,’’3’’,’’-’’,
’’C’’,’’0’’,’’=’’,’’+’’,
//下面为按’’C’’同时再按的键: ’’7’’,’’8’’,’’9’’,’’/’’, | |
’’1’’,’’2’’,’’3’’,’’-’’,
’’0’’,’’=’’,’’+’’,};
// P1口行列式键盘 //
#defineKEYPIN_L P1 //定义键扫描列端口为P1
低四位输入 //
#defineKEYPIN_H P1 //定义键扫描行端口为P1高
四位扫描输出 //
// P1口行列式键盘 //
//公用函数
unsigned char KeysCAN(void); | // 键扫描函数 | // |
//内部私有函数
unsignedchar fnKeycode(unsigned char key); // 根据键盘
映射表输出顺序键值 //
/*
// P1口行列式键盘 //
extern unsigned char KeysCAN(void); | ||
unsigned char KeysCAN(void) | // 键扫描 | |
函数 | // |
{
unsignedchar sccode,recode,keytemp = 0;
KEYPIN_L = KEYPIN_L|0x0f; | // P1 低四 // P1 高四 | |
位为列线输入 | // | |
KEYPIN_H = KEYPIN_H&0x0f; |
位为行线发全零扫描码//
if((KEYPIN_L&0x0f) != 0x0f)
{
delay(10); | // 延时 | | |
10 MS 消抖 | // | ||
if ((KEYPIN_L&0x0f) != 0x0f) | |
{
sccode= 0xef; // 逐行扫
描码初值(11101111) //
while(sccode!= 0xff) //将扫描4次
,keytemp为每次键值相或的值//
{
行扫描码 | KEYPIN_H = sccode; | // 输出 |
// | ||
键按下 | if ((KEYPIN_L&0x0f) != 0x0f) | // 本行有 |
// |
{
recode= (KEYPIN_L&0x0f)|0xf0; // 只
要低位,高位置1 //
keytemp |= (~sccode)+(~recode); | //特 |
征码(高位为列P3,低位为行KEYPIN_H) // } sccode = (sccode << 1)|0x01; // 扫描码0 |
}
KEYPIN_H= KEYPIN_H|0xf0;
return(fnKeycode(keytemp));
}
//---------------------------------------------------------
------------------//
unsignedchar 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; | ||
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;
case | break; | // 16 键 // | |
0x88: | |||
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 | 0x: | // ’’C’’ +4 键 // |
key= 0x14;
break;
case | 0x1A: | // ’’C’’ +5 键 // |
key= 0x15;
break;
case | 0x2A: | // ’’C’’ +6 键 // |
key= 0x16;
break; |
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; | // ’’C’’ +14 键 // | ||
// | break; | |||
case | 0x38: | |||
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]);
}
矩键查寻键值44程序与显示
#include<reg52.h>
//#include<math.h>
#include<intrins.h>
#define uchar unsigned char |
/************主程序*************/
voidmain(void)
{
void tkey(void);
void led(void);
void delay(int);
SCON=0x00;
TI=0;
while(TURE)
{
Tkey(); | |
}
}
/********矩键查寻键值4*4程序******/按键为P1.0---P1.7
voidTkey(void)
{
uchar readkey;//rereadkey;
uchar x_temp,y_temp;
P1=0x0f;
x_temp=P1&0x0f;
if(x_temp==0x0f) goto keyout;
P1=0xf0;
y_temp=P1&0xf0;
readkey=x_temp|y_temp; readkey=~readkey; | |
switch(readkey) |
case 0x41:key=2; break;
case 0x81:key=3; break;
case0x12:key=4; break;
case 0x22:key=5; break;
case0x42:key=6; break;
case 0x82:key=7; break;
case0x14:key=8; break;
case 0x24:key=9; break;
case0x44:key=10;break;
case 0x84:key=11;break;
case0x18:key=12;break;
case 0x28:key=13;break;
case0x48:key=14;break;
case 0x88:key=15;break;
default: key=16;break; }
keyout:_nop_();
}
/************显示程序*************/
voidled(void)
{ucharcode LEDValue[]=
{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //0-9
uchar data num[6];
uchar k;
num[0]=0;
num[1]=0;
num[2]=0;
num[3]=0;
num[4]=key/10;
num[5]=key-(key/10)*10;
for(k=0;k<=5;k++) |
/************延时程序*************/
voiddelay(del)
{
for(del;del>0;del--);
;伪定义
KEYBUF EQU 30H ;键值暂存单元,查表时用
;*************************************
;* | * | | ||
;* | 主程序和中断程序入口 | * | ||
;* | * | |||
;************************************* | ||||
ORG | 0000H | ;程序执行开始地址 |
AJMP | MAIN | ;跳至MAIN 执行 |
;*************************************
;* | 主程序 | * |
;* | * | |
;* | * |
;*************************************
ORG | 0040H | |||
MAIN: MOV | P1,#0FFH | |||
MOV | P3,#0FFH | |||
LCALL KEYSCAN | ;主体程序。调用查键子程序 | |||
LJMP MAIN | ;转MAIN 循环 | |||
NOP | ;软件陷阱 |
NOP
NOP
LJMP MAIN
;*************************************
;* | * |
;* 键盘工作子程序(4 * 5 阵列) | * |
;* 接口为2051 的P3 和P1 口 | * |
;************************************* |
MOV A,P1
ANL A,#0FH
XRL A,#0FH
JZ NOKEY1 ;是干扰则转下一行键值处理程序
MOV A,P1
ANL A,#0FH ;保留低四?
KB1:CJNE A,#0EH,KB2 ;如果值为#0E则为P1.4与P1.0组合的键 MOV KEYBUF,#0 ;赋键值
LJMP KEYWORK ;转键处理
KB2: CJNE A,#0DH,KB3 ;如果值为#0D则为P1.4与P1.1组合的键 MOV KEYBUF,#1
LJMP KEYWORK
KB3: CJNE A,#0BH,KB4 ;如果值为#0B则为P1.4与P1.2组合的 MOV KEYBUF,#2
LJMP KEYWORK | |
LJMP KEYWORK
KB5: NOP
;
NOKEY1:MOV P3,#0FFH
CLR P3.3
MOV A,P1
ANL A,#0FH
XRL A,#0FH
JZ NOKEY2
LCALL DL10MS
MOV A,P1
ANL A,#0FH
XRL A,#0FH
JZ NOKEY2
MOV A,P1
ANL A,#0FH
CJNE A,#0EH,KB6
MOV KEYBUF,#4
LJMP KEYWORK
KB6: CJNE A,#0DH,KB7 |
LJMP KEYWORK
KB9: NOP
;
NOKEY2:MOV P3,#0FFH
CLR P3.4
MOV A,P1
ANL A,#0FH
XRL A,#0FH
JZ NOKEY3
LCALL DL10MS
MOV A,P1
ANL A,#0FH
XRL A,#0FH
JZ NOKEY3
MOV A,P1 | |
MOV KEYBUF,#8
LJMP KEYWORK
KB10: CJNE A,#0DH,KB11
MOV KEYBUF,#9
LJMP KEYWORK
KB11: CJNE A,#0BH,KB12
MOV KEYBUF,#10
LJMP KEYWORK
KB12: CJNE A,#07H,KB13
MOV KEYBUF,#11
LJMP KEYWORK
KB13: NOP
;
NOKEY3:MOV P3,#0FFH
CLR P3.5
MOV A,P1
ANL A,#0FH
XRL A,#0FH
JZ NOKEY4
LCALL DL10MS |
MOV KEYBUF,#12
LJMP KEYWORK
KB14: CJNE A,#0DH,KB15
MOV KEYBUF,#13
LJMP KEYWORK
KB15: CJNE A,#0BH,KB16
MOV KEYBUF,#14
LJMP KEYWORK
KB16: CJNE A,#07H,KB17
MOV KEYBUF,#15
LJMP KEYWORK
KB17: NOP
;
NOKEY4:MOV P3,#0FFH
CLR P3.7 | |
XRL A,#0FH
JZ NOKEY5
LCALL DL10MS
MOV A,P1
ANL A,#0FH
XRL A,#0FH
JZ NOKEY5
MOV A,P1
ANL A,#0FH
CJNE A,#0EH,KB18
MOV KEYBUF,#16
LJMP KEYWORK
KB18: CJNE A,#0DH,KB19
MOV KEYBUF,#17
LJMP KEYWORK
KB19: CJNE A,#0BH,KB20
MOV KEYBUF,#18
LJMP KEYWORK
KB20: CJNE A,#07H,KB21
MOV KEYBUF,#19 |
MOVC A,@A+DPTR ;查行键值送ACC
MOV P0,A
;
WAITFREE:
MOV A,P1 ;以下程序等待键释放
MOV KEYBUF,#00H
ANL A,#0FH
XRL A,#0FH
JNZ WAITFREE
RET
;
;*************************************
;* | * | | |
;* | 延时513 us | * | |
;* | * | ||
;************************************* ; |
;513微秒延时程序
DELAY:MOV R2,#0FEH
DELAY1:DJNZ R2,DELAY1
RET
;
;*************************************
;* | 延时10ms | * |
;* | * | |
;* | * |
;*************************************
;
;10毫秒延时程序
DL10MS:MOV R3,#14H
DL10MS1:LCALL DELAY
DJNZR3,DL10MS1
RET
;
TABLE: ;七段显示器数据定义
DB 0C0H, 0F9H, 0A4H, 0B0H, 99H ; 01234
DB 92H, 82H, 0F8H, 80H, 90H ; 567 |
KEYBUFEQU 30H
ORG00H
START: MOVKEYBUF,#2
WAIT:
MOVP3,#0FFH
CLRP3.4
MOVA,P3
ANLA,#0FH
XRLA,#0FH
JZNOKEY1
LCALLDELY10MS
MOVA,P3
ANLA,#0FH
XRL A,#0FH | |
ANLA,#0FH
CJNEA,#0EH,NK1
MOVKEYBUF,#0
LJMPDK1
NK1: CJNEA,#0DH,NK2
MOVKEYBUF,#1
LJMPDK1
NK2: CJNEA,#0BH,NK3
MOVKEYBUF,#2
LJMPDK1
NK3: CJNEA,#07H,NK4
MOVKEYBUF,#3
LJMPDK1
NK4: NOP
DK1:
MOVA,KEYBUF
MOVDPTR,#TABLE
MOVCA,@A+DPTR
MOVP0,A
DK1A: ANL A,#0FH XRL A,#0FH MOV A,P3 |
MOVA,P3
ANLA,#0FH
XRLA,#0FH
JZNOKEY2
LCALLDELY10MS
MOVA,P3
ANLA,#0FH
XRLA,#0FH
JZNOKEY2
MOVA,P3
ANLA,#0FH
CJNEA,#0EH,NK5
MOVKEYBUF,#4
LJMPDK2
NK5: | CJNE A,#0DH,NK6 | |
MOV KEYBUF,#5 | ||
LJMP DK2 | |
NK6: | CJNE A,#0BH,NK7 |
MOVKEYBUF,#6
LJMPDK2
NK7: CJNEA,#07H,NK8
MOVKEYBUF,#7
LJMPDK2
NK8: NOP
DK2:
MOVA,KEYBUF
MOVDPTR,#TABLE
MOVCA,@A+DPTR
MOVP0,A
DK2A: MOVA,P3
ANLA,#0FH
XRLA,#0FH
JNZDK2A
NOKEY2:
MOVP3,#0FFH
CLR P3.6 |
XRLA,#0FH
JZNOKEY3
MOVA,P3
ANLA,#0FH
CJNEA,#0EH,NK9
MOVKEYBUF,#8
LJMPDK3
NK9:
CJNEA,#0DH,NK10 MOVKEYBUF,#9
LJMPDK3
NK10: CJNEA,#0BH,NK11
MOVKEYBUF,#10
LJMPDK3
NK11: | CJNE A,#07H,NK12 | |
MOV KEYBUF,#11 | ||
LJMP DK3 | ||
NK12: | NOP | |
DK3:
MOVA,KEYBUF
MOVDPTR,#TABLE
MOVCA,@A+DPTR
MOVP0,A
DK3A: MOVA,P3
ANLA,#0FH
XRLA,#0FH
JNZDK3A
NOKEY3:
MOVP3,#0FFH
CLRP3.7
MOVA,P3
ANLA,#0FH
XRLA,#0FH
JZNOKEY4
LCALLDELY10MS
MOVA,P3
ANL A,#0FH | |
NK13: | CJNE A,#0DH,NK14 |
MOVKEYBUF,#13
LJMPDK4
NK14: CJNEA,#0BH,NK15
MOVKEYBUF,#14
LJMPDK4
NK15: CJNEA,#07H,NK16
MOVKEYBUF,#15
LJMPDK4
NK16: NOP
DK4:
MOVA,KEYBUF
MOVDPTR,#TABLE
MOVCA,@A+DPTR
DK4A: | MOV P0,A | |
MOV A,P3 | |
ANLA,#0FH
XRLA,#0FH
JNZDK4A
NOKEY4:
LJMPWAIT
DELY10MS:
MOVR6,#10
D1:
MOVR7,#248 DJNZR7,$
DJNZR6,D1
RET
TABLE: DB3FH,06H,5BH,4FH,66H,6DH,7DH,07H
DB7FH,6FH,77H,7CH,39H,5EH,79H,71H
END
MOVR3,#F7H ;扫描初始值
MOV R1,#00H | ; 取码指标 |
SCAN1: MOV A,R3 | |
INC R1 | ; 将指标值加 1, 继续扫描下一行 |
DJNZR5,L1 &
nbsp; | ; 扫描四行 | ; 载入扫描值 ; 消除弹跳 |
MOV A,R3 KEYIN: MOV R7,#10 |
D2:MOV R6,#248
DJNZ R6,$ | ; 读入 P1 | |
DJNZ R7,D2 | ||
D3: MOV A,P1 | |
XRLA,R4
JZ D3
MOV A,R1
MOV DPTR,#TABLE
MOVC A,@A+DPTR
Table:
db0c0h,0f9h,0a4h,0b0h,099h;0-4
db092h,082h,0f8h,080h,090h;5-9
db088h,083h,0a7h,0a1h,086h;A-E
db08eh;F
end
Copyright © 2019- huatuo9.cn 版权所有 赣ICP备2023008801号-1
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务