Intro to Keypad#

原理#

两种扫描方法,一种是扫描法,另一种是反转法。反转法更好理解,程序也更为简单,但需要行线与列线均可带上拉电阻作为输入。

反转法#

分为两个可以交换顺序的步骤:

  1. 确定按键列线

  2. 确定按键行线

确定按键列线#

将行线配置为输入(全0),列线配置为输出。当没有任何按键按下时,列线输出为常1。

image-20230623184558115

此时,在某一列中,如(从左到右)第1列中的某个键被按下(行不定),都会导致所在列线1的读数为0,而其它列线的读数仍然为1,不受影响。这样就检测出了被按下的键的所在列 (?,y) ,但无法检测出所在行。

确定按键行线#

如果我们再用同样的方法,确定被按下的键的所在行 (x,?),那么与上一步组合,就可以确定按键的坐标 (x,y)。

当键盘的硬件设计合理,我们从逻辑上交换行与列,即将列线为作输入(全0),行线配置为输出。当没有任何按键按下时,行线输出为常1。注意:因为单片机的引脚可切换输入/输出功能,所以连线并不需要改变,只需修改配置即可。

image-20230623185240300

此时,在某一行中,如(从左到右)第1列中的某个键被按下(行不定),都会导致所在行线1的读数为0,而其它行线的读数仍然为1,不受影响。这样就检测出了被按下的键的所在行 (x,?),但无法检测出所在列。

将这一步确定的按键所在行 (x, ?) 与上一步确定的所在列 (?,y) 组合,就确定按键的坐标 (x,y)。

Reference#

图片来自 中国大学幕课 Arduino 课程。

扫描法#

反转法的一个小问题在于8个IO口都要可以作为输出和输出,且作为输入时,要上拉电阻。反转换则不需要在第2步时切换I/O引脚的输入与输出功能。下面分析其原理。

image-20230623184558115

扫描法的第一步与反转法的第一步相同,在反转法的第1步结束时,确定了列线,但没有确定所在行。

此时假定不能像反转法那些将输入与输出对换,那么能做的只有变换输入信号的组合,测试输出结果。因为一般情况下,不同的输入会对应不同的输出图案。如果能找到一个按键按下去的输入输出可解出的对应关系表,那么就可以实现行的检测。例如:

假设(1,2)位置的按键被按下,输入输出关系有:

Input

Output

Function

0000

0111

确定了列为 1

1000

0111

0100

1111

确定了行为 2

0010

0111

0001

0111

从上面的输入输出关系可以看出,当输入为 1000,输出为 1111 时。其它输入时,输出为 0111。这样就只需要检测输出为4个1时的输入是什么,由此确定行。于是,第2步可以归纳为:

  1. 输入1000,如果输出为1111,则确定行为1;

  2. 输入0100,如果输出为1111,则确定行为2;

  3. 输入0010,如果输出为1111,则确定行为3;

  4. 输入0001,如果输出为1111,则确定行为4。

image-20230623215504127

Arduino Keypad 库介绍#

Arduino - Keypad | Arduino Tutorial

利用 keypad 库驱动#

How to Set Up a Keypad on an Arduino - Circuit Basics

应该是反转法的应用

In-Depth: Interface 4x3 & 4x4 Membrane Keypad with Arduino

应用的好像是扫描法

手写驱动试验#

How to Add a Keypad to an Arduino Project

开脑洞#

能不能不用8根线,只用一根线搞定4x4按键接入?

如果将16个键分别连接到16个电位等级的电位器,当哪个按键按下时,对应测得该等级的电位,并传给单片机的模拟输入口。似乎只要电位器的精等还行,就可行。

需要战占用的是模拟引脚,而不是数字引脚。

这种方法接线简单,易于理解,可能可用于儿童版单片机编程应用。

参考#

一文带你详解矩阵键盘工作原理