Intro to Keypad#
原理#
两种扫描方法,一种是扫描法,另一种是反转法。反转法更好理解,程序也更为简单,但需要行线与列线均可带上拉电阻作为输入。
反转法#
分为两个可以交换顺序的步骤:
确定按键列线
确定按键行线
确定按键列线#
将行线配置为输入(全0),列线配置为输出。当没有任何按键按下时,列线输出为常1。
此时,在某一列中,如(从左到右)第1列中的某个键被按下(行不定),都会导致所在列线1的读数为0,而其它列线的读数仍然为1,不受影响。这样就检测出了被按下的键的所在列 (?,y) ,但无法检测出所在行。
确定按键行线#
如果我们再用同样的方法,确定被按下的键的所在行 (x,?),那么与上一步组合,就可以确定按键的坐标 (x,y)。
当键盘的硬件设计合理,我们从逻辑上交换行与列,即将列线为作输入(全0),行线配置为输出。当没有任何按键按下时,行线输出为常1。注意:因为单片机的引脚可切换输入/输出功能,所以连线并不需要改变,只需修改配置即可。
此时,在某一行中,如(从左到右)第1列中的某个键被按下(行不定),都会导致所在行线1的读数为0,而其它行线的读数仍然为1,不受影响。这样就检测出了被按下的键的所在行 (x,?),但无法检测出所在列。
将这一步确定的按键所在行 (x, ?) 与上一步确定的所在列 (?,y) 组合,就确定按键的坐标 (x,y)。
Reference#
图片来自 中国大学幕课 Arduino 课程。
扫描法#
反转法的一个小问题在于8个IO口都要可以作为输出和输出,且作为输入时,要上拉电阻。反转换则不需要在第2步时切换I/O引脚的输入与输出功能。下面分析其原理。
扫描法的第一步与反转法的第一步相同,在反转法的第1步结束时,确定了列线,但没有确定所在行。
此时假定不能像反转法那些将输入与输出对换,那么能做的只有变换输入信号的组合,测试输出结果。因为一般情况下,不同的输入会对应不同的输出图案。如果能找到一个按键按下去的输入输出可解出的对应关系表,那么就可以实现行的检测。例如:
假设(1,2)位置的按键被按下,输入输出关系有:
Input |
Output |
Function |
---|---|---|
0000 |
0111 |
确定了列为 1 |
1000 |
0111 |
|
0100 |
1111 |
确定了行为 2 |
0010 |
0111 |
|
0001 |
0111 |
从上面的输入输出关系可以看出,当输入为 1000,输出为 1111 时。其它输入时,输出为 0111。这样就只需要检测输出为4个1时的输入是什么,由此确定行。于是,第2步可以归纳为:
输入1000,如果输出为1111,则确定行为1;
输入0100,如果输出为1111,则确定行为2;
输入0010,如果输出为1111,则确定行为3;
输入0001,如果输出为1111,则确定行为4。
Arduino Keypad 库介绍#
利用 keypad 库驱动#
How to Set Up a Keypad on an Arduino - Circuit Basics
应该是反转法的应用
In-Depth: Interface 4x3 & 4x4 Membrane Keypad with Arduino
应用的好像是扫描法
手写驱动试验#
开脑洞#
能不能不用8根线,只用一根线搞定4x4按键接入?
如果将16个键分别连接到16个电位等级的电位器,当哪个按键按下时,对应测得该等级的电位,并传给单片机的模拟输入口。似乎只要电位器的精等还行,就可行。
需要战占用的是模拟引脚,而不是数字引脚。
这种方法接线简单,易于理解,可能可用于儿童版单片机编程应用。