Bootstrap

【51单片机入门】矩阵键盘


前言

在嵌入式系统设计中,键盘输入是一种常见的人机交互方式。其中,矩阵键盘因其简单、方便和易于扩展的特性,被广泛应用于各种设备中。本文将介绍如何使用51单片机来实现矩阵键盘的设计,包括硬件连接、键盘扫描算法以及按键处理等内容。希望通过本文的学习,读者能够掌握矩阵键盘的基本原理和设计方法,为自己的项目提供强大的输入功能。


矩阵键盘介绍与检测原理

矩阵键盘是一种常见的输入设备,它由多个按键组成,通常是以矩阵的形式排列。每个按键都有一个唯一的行和列位置,通过检测行和列的电平变化来确定按下的是哪个按键。

在嵌入式系统设计中,矩阵键盘是一种常见的人机交互方式。矩阵键盘的本质是使用8个IO口来进行16个按键的控制读取,可以减小IO口的使用。它用4条I/O线作为行线,4条I/O线作为列线组成的键盘。在行线和列线的每个交叉点上,设置一个按键。这样键盘中按键的个数是4×4个。这种行列式键盘结构能够有效地提高单片机系统中I/O口的利用率。

其工作原理是:先从P1口的高四位(四个行)输出高电平,低四位(四个列)输出低电平,假设有按键按下,从P1口的高四位读取键盘状态。判断高四位的四行哪一行变成了低电平,就知道是第几行,再从P1口的低四位(四个列)输出高电平,高四位(四个行)输出低电平,从P1口的低四位读取键盘状态。判断低四位的四列哪一行变成了低电平,就知道是第几列,将两次读取结果组合起来就可以得到当前按键的特征编码。

矩阵键盘通常用于嵌入式系统中,例如家用电器、手机、计算器等设备。希望这个介绍能帮助你更好地理解矩阵键盘的工作原理和应用。

比如下面的这个也是矩阵键盘:
在这里插入图片描述

原理图

矩阵键盘的元件名称:KEY-PAD-PHONE
在这里插入图片描述

在这里插入图片描述

代码讲解

总体代码如下所示:

#include <REGX51.H>

// ????????
#define KEYPAD_ROW P1
#define KEYPAD_COL P3

void delay(unsigned int ms) {
    unsigned int i, j;
    for(i = ms; i > 0; i--)
        for(j = 120; j > 0; j--);
}

// ??????
char keys[4][3] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

// ????
char scan_keypad(void);

void main() {
  char key;
  while(1) {
    key = scan_keypad();  // ????????
    if(key != 0xFF) {     // ????????
      // ?????????????????
      // ??:?????????LCD??
    }
  }
}

char scan_keypad(void) {
  int row, col;
  KEYPAD_COL = 0xFF;
  for(row = 0; row < 4; row++) {
    KEYPAD_ROW = ~(1 << row);
    for(col = 0; col < 3; col++) {
      if(!(KEYPAD_COL & (1 << col))) {
        while(!(KEYPAD_COL & (1 << (col))));
        return keys[row][col];
      }
    }
  }
  return 0xFF;
}

这段代码的实现基于矩阵键盘的工作原理。矩阵键盘是由行和列组成的,每个按键位于特定的行和列的交叉点。当某个按键被按下时,对应的行和列就会被连接起来。

在这段代码中,我们首先将所有的行设置为输出,并将所有的列设置为输入。然后,我们逐行扫描键盘:将当前行设置为低电平,其他行保持高电平。然后读取所有的列,如果某一列的电平为低,那么就说明当前行的这一列的按键被按下。

这样,我们就可以通过行号和列号确定哪个按键被按下。在代码中,我们使用一个二维数组keys来存储每个按键的值,通过行号和列号就可以从数组中取出对应的按键值。

核心代码:

char scan_keypad(void) {
  int row, col;
  KEYPAD_COL = 0xFF;
  for(row = 0; row < 4; row++) {
    KEYPAD_ROW = ~(1 << row);
    for(col = 0; col < 3; col++) {
      if(!(KEYPAD_COL & (1 << col))) {
        while(!(KEYPAD_COL & (1 << (col))));
        return keys[row][col];
      }
    }
  }
  return 0xFF;
}

这段代码的主要目标是扫描矩阵键盘并返回被按下的键。下面是这段代码的二进制解释:

  1. KEYPAD_COL = 0xFF;:这行代码将所有列设置为输入。在二进制中,0xFF表示1111 1111,这意味着所有的列线都被设置为高电平。

  2. KEYPAD_ROW = ~(1 << row);:这行代码将当前行设置为低电平,其他行保持高电平。1 << row将1向左移动row位,然后~操作符取反。例如,如果row为2,那么1 << row就是0000 0100,取反后就变成1111 1011,这就将第2行设置为低电平,其他行保持高电平。

  3. !(KEYPAD_COL & (1 << col))这段代码我们通过下面二进制解释:

===没有按下
col = 0
1 << col =>0000,0001
1111,1111
0000,0001
&
0000,0001
!
1111,1110

===按下
col = 0
1 << col =>0000,0001
1111,1110
0000,0000
&
0000,0000
!
1111,1111
  1. return keys[row][col];:这行代码返回被按下的键的值。keys是一个二维数组,存储了每个按键的值,通过行号和列号就可以从数组中取出对应的按键值。

  2. return 0xFF;:如果没有按键被按下,那么函数就返回0xFF。在二进制中,0xFF表示1111 1111


总结

通过本文的学习,我们了解了矩阵键盘的工作原理,学习了如何使用51单片机实现矩阵键盘的硬件连接和软件设计。我们还探讨了一些常见的问题,如按键抖动和多键按下的处理。希望这些知识能够帮助你在实际的项目中更好地使用矩阵键盘。记住,理论知识的学习是重要的,但实践才能使理论知识得以应用。因此,我鼓励你动手实践,尝试设计和制作自己的矩阵键盘,通过实践来提高自己的技能和理解。

;