各种各样的矩阵键盘扫描程序集
最简单矩阵键盘扫描程序
key:mov p0,#00001111b;上四位和下四位分别为行和列,所以送出高
低电压检查有没有按键按下
jmp k10;跳到K10处开始扫描,这里可以改成其它条件转移指令来决
定本次扫描是否要继续,例如减1为0转移或者位为1或0才转移,这主
要用来增加功能,确认上一按键功能是否完成?是否相当于经过了延
时?是否要封锁键盘?
goend:jmp kend;如果上面判断本次不执行键盘扫描程序,则立即转
到程序尾部,不要浪费CPU的时间
k10:jb p0.0,k20;扫描正式开始,先检查列1四个键是否有键按下,
如果没有,则跳到K20检查列2
k11:mov p0,#11101111b;列1有键按下时,P0.0变低,到底是那一个键
按下?现在分别输出各行低电平
jb p0.0,k12;该行的键不按下时,p0.0为高电平,跳到到K12,检查其
它的行
mov r1,#1;如果正好是这行的键按下,将寄存器R0写下1,表示1号键
按下了
k12:mov p0,#11011111b
jb p0.0,k13
mov r1,#2;如果正好是这行的键按下,将寄存器R0写下2,表示2号键
按下了
k13:mov p0,#10111111b
jb p0.0,k14
mov r1,#3;如果正好是这行的键按下,将寄存器R0写下3,表示3号键
按下了
k14:mov p0,#01111111b
jb p0.0,kend;如果现在四个键都没有按下,可能按键松开或干扰,
退出扫描(以后相同)
mov r1,#4如果正好是这行的键按下,将寄存器R0写下4,表示4号键
按下了
jmp kend;已经找到按下的键,跳到结尾吧
k20:jb p0.1,k30;列2检查为高电平再检查列3、4
k21:mov p0,#11101111b;列2有健按下时,P0.0会变低,到底是那一
行的键按下呢?分别输出行的低电平
jb p0.1,k22;该行的键不按下时p0.0为高电平,跳到到K22,检查另
外三行
mov r1,#5;如果正好是这行的键按下,将寄存器R0写下5,表示5号键
按下了(以后相同,不再重复了)
k22:mov p0,#11011111b
jb p0.1,k23
mov r1,#6
k23:mov p0,#10111111b
jb p0.1,k24
mov r1,#7
k24:mov p0,#01111111b
jb p0.1,kend
mov r1,#8
jmp kend;已经找到按下的键,跳到结尾吧(以后相同,不要重复了
)
k30:jb p0.2,k40
k31:mov p0,#11101111b
jb p0.2,k32
mov r1,#9
k32:mov p0,#11011111b
jb p0.2,k33
mov r1,#10
k33:mov p0,#10111111b
jb p0.2,k34
mov r1,#11
k34:mov p0,#01111111b
jb p0.2,kend
mov r1,#12
jmp kend
k40:jb p0.3,kend
k41:mov p0,#11101111b
jb p0.3,k42
mov r1,#13
k42:mov p0,#11011111b
jb p0.3,k43
mov r1,#14
k43:mov p0,#10111111b
jb p0.3,k44
mov r1,#15
k44:mov p0,#01111111b
jb p0.3,kend
mov r1,#16
kend: ret
行列扫描键盘可检测出双键按下
#include
#define ulong unsigned long
#define uint unsigned int
#define uchar unsigned char
extern void delay(unsigned int x);
unsigned char 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高
四位扫描输出 //
// P1口行列式键盘 //
//公用函数
unsigned char KeysCAN(void); // 键扫描函数 //
//内部私有函数
unsigned char fnKeycode(unsigned char key); // 根据键盘
映射表输出顺序键值 //
/*
// P1口行列式键盘 //
extern unsigned char KeysCAN(void); // 键扫描函数
//
*/
// P1口行列式键盘 //
//---------------------------------------------------------
------------------//
unsigned char KeysCAN(void) // 键扫描
函数 //
{
unsigned char sccode,recode,keytemp = 0;
KEYPIN_L = KEYPIN_L|0x0f; // P1低四
位为列线输入 //
KEYPIN_H = KEYPIN_H&0x0f; // P1高四
位为行线发全零扫描码 //
if ((KEYPIN_L&0x0f) != 0x0f)
{
delay(10); // 延时
10 MS 消抖 //
if ((KEYPIN_L&0x0f) != 0x0f)
{
sccode = 0xef; // 逐行扫
描码初值(1110 1111) //
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));
}
//---------------------------------------------------------
------------------//
unsigned char fnKeycode(unsigned char key) // 根据键盘