ai8051U矩阵按键--打卡9
矩阵按键原理
分行端口和列端口。当行端口为高电平时,列端口为低电平,按键按下会将按下行的高电平改为低电平,确认按键所在行;当行端口为低电平时,列端口为高电平,按键会将按下的列的高电平改为低电平,确认按键所在列。行号和列号确认即可找到对应的按键。
缺点:只能有一个按键按下,检测一个按钮被按下。不支持多按键按下。


按键内容
第一种写法:顺序操作判断每个端口
// 键号
unsigned char keyNum = 0xFF;
// 行号
#define ROW1 端口号(例如P00)
#define ROW2
// 列号
#define COLUMN1 端口号(例如P05)
#define COLUMN2
#define COLUMN3
#define COLUMN4
void matrixButtons(){
// 1.先确认行号,行端口:高电平,列端口:低电平,行端口判断低电平
COLUMN1 = 0;
COLUMN2 = 0;
COLUMN3 = 0;
COLUMN4 = 0;
ROW1= 1;
ROW2= 1;
if((ROW1 == 0) || (ROW2 == 0)){
if(ROW1 == 0) && (ROW2 ==0)){
ROW1 = 1;
ROW2 = 1;
keyNum = 0;
printf_usb(" 非法操作,有多个按键被按下 \r\n");
}else if((ROW1 == 0) &&(ROW2 == 1)) || ((ROW1 == 1) &&(ROW2 == 0)){
// 2.确认列号,行端口:低电平,列端口:高电平,列端口判断低电平
COLUMN1 = 1;
COLUMN2 = 1;
COLUMN3 = 1;
COLUMN4 = 1;
ROW1= 0;
ROW2= 0;
if(ROW1 == 0){
// 行按键起始号
keyNum = 1;
if((COLUMN1 == 0) && (COLUMN2 == 1) && (COLUMN3 == 1) && (COLUMN4 == 1){
keyNum = keyNum + 1;
printf_usb(" 按键位置:第1行第1列 \r\n");
}else if(COLUMN1 == 1) && (COLUMN2 == 0) && (COLUMN3 == 1) && (COLUMN4 == 1){
keyNum = keyNum + 2;
printf_usb(" 按键位置:第1行第2列 \r\n");
}else if(COLUMN1 == 1) && (COLUMN2 == 1) && (COLUMN3 == 0) && (COLUMN4 == 1){
keyNum = keyNum + 3;
printf_usb(" 按键位置:第1行第3列 \r\n");
}else if(COLUMN1 == 1) && (COLUMN2 == 1) && (COLUMN3 == 1) && (COLUMN4 == 0){
keyNum = keyNum + 4;
printf_usb(" 按键位置:第1行第4列 \r\n");
}
}else if(ROW2 == 0){
// 行按键起始号
keyNum = 4;
if((COLUMN1 == 0) && (COLUMN2 == 1) && (COLUMN3 == 1) && (COLUMN4 == 1){
keyNum = keyNum + 1;
printf_usb(" 按键位置:第2行第1列 \r\n");
}else if(COLUMN1 == 1) && (COLUMN2 == 0) && (COLUMN3 == 1) && (COLUMN4 == 1){
keyNum = keyNum + 2;
printf_usb(" 按键位置:第2行第2列 \r\n");
}else if(COLUMN1 == 1) && (COLUMN2 == 1) && (COLUMN3 == 0) && (COLUMN4 == 1){
keyNum = keyNum + 3;
printf_usb(" 按键位置:第2行第3列 \r\n");
}else if(COLUMN1 == 1) && (COLUMN2 == 1) && (COLUMN3 == 1) && (COLUMN4 == 0){
keyNum = keyNum + 4;
printf_usb(" 按键位置:第2行第4列 \r\n");
}
}
// 3.恢复初始值,过滤闪烁问题,行端口:高电平,列端口:低电平
COLUMN1 = 0;
COLUMN2 = 0;
COLUMN3 = 0;
COLUMN4 = 0;
ROW1= 1;
ROW2= 1;
}else if((ROW1 == 1) && (ROW2 == 1)){
// 清空键值
keyNum = 0xFF;
}
}
}
第二种写法:使用十六进制数表示端口,端口组合模式判断匹配
低位:行,高位:列
例如第一行第一列
0x0F = 0000 1111
ROW = P1 & 0x0F = 0000 1110 & 0000 1111 = 0000 1110
0xF0 = 1111 0000
COLUMN = P1 & 0xF0 = 1110 0000 & 1111 0000 = 1110 0000
ROW + COLUMN = 0000 1110 + 1110 0000 = 1110 1110 = 0xEE
所以第一行第一列的按键可以用0xEE来指向。
按位与(&):只有两个数的二进制同时为1,结果才为1,否则为0。(负数按补码形式参加按位与运算)
按位或(|):参加运算的两个数只要两个数中的一个为1,结果就为1。
按位异或(^):参加运算的两个数,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。
即 0 ^ 0=0 , 0 ^ 1= 1 , 1 ^ 0= 1 , 1 ^ 1= 0 。