<p>灵活调用各各接口进行使用。</p>
<h1><strong>ai8051U矩阵按键--打卡9</strong></h1>
<h2>矩阵按键原理</h2>
<p>分<strong>行端口</strong>和<strong>列端口</strong>。当行端口为高电平时,列端口为低电平,按键按下会将按下行的高电平改为低电平,确认按键所在行;当行端口为低电平时,列端口为高电平,按键会将按下的列的高电平改为低电平,确认按键所在列。行号和列号确认即可找到对应的按键。<br />
<strong>缺点</strong>:<font color="red">只能有一个按键按下,检测一个按钮被按下。不支持多按键按下。</font></p>
<p><img src="data/attachment/forum/202509/02/084933bf1x8lh1kx49vv9x.png" alt="图片.png" title="图片.png" /></p>
<p><img src="data/attachment/forum/202509/02/085352lzw8oxu38y3r3xwu.png" alt="图片.png" title="图片.png" /></p>
<h2>按键内容</h2>
<p>第一种写法:顺序操作判断每个端口</p>
<pre><code>// 键号
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;
}
}
}
</code></pre>
<p>第二种写法:使用十六进制数表示端口,端口组合模式判断匹配<br />
低位:行,高位:列</p>
<p>例如第一行第一列<br />
0x0F = 0000 1111<br />
ROW = P1 & 0x0F = 0000 1110 & 0000 1111 = 0000 1110<br />
0xF0 = 1111 0000<br />
COLUMN = P1 & 0xF0 = 1110 0000 & 1111 0000 = 1110 0000<br />
ROW + COLUMN = 0000 1110 + 1110 0000 = 1110 1110 = 0xEE<br />
所以第一行第一列的按键可以用0xEE来指向。</p>
<p><strong>按位与(&)</strong>:只有两个数的二进制同时为1,结果才为1,否则为0。(负数按补码形式参加按位与运算)<br />
<strong>按位或(|)</strong>:参加运算的两个数只要两个数中的一个为1,结果就为1。<br />
<strong>按位异或(^)</strong>:参加运算的两个数,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。<br />
即 0 ^ 0=0, 0 ^ 1= 1, 1 ^ 0= 1, 1 ^ 1= 0 。</p>
页:
1
[2]