Arduino 4×4矩阵键盘按键扫描程序原理

下图左是一款常见的薄膜按键模块(hex keypad),有4×4或3×4(少了最右边一行的A,B,C,D键),它的内部如同下图右边的电路所示,是由16个按键(开关)交织而成。有些按键模块直接使用按键(微触)开关组装,连接电路与程序都和本文相同。


4×4按键模块有8个接脚,分成列、行两组,可以接在Arduino的任意8个接脚,笔者将它接在数位6~13脚:


为了简化接线,可以使用「长脚型」排针,将其中两个脚用尖嘴钳稍微折弯,即可插入Arduino的排母:


排针上头的黑色塑料,可以用蛮力让它移到中间的位置,以便衔接两边的排母:

4×4薄膜键盘的Arduino按键侦测程序

撰写Arduino按键侦测程序,最简单也是最好的方式,就是采用既有的程序库。本单元将示范使用Keypad程序库,把侦测到的按键字元显示在序列端口监控视窗。请按此下载Keypad程序库(原始出处在这篇keypad介绍文),解压缩之后,置入Arduino的libraries路径:


底下的程序,修改自Keypad程序库的“HelloKeypad”示例,使用此程序库,我们的代码需要定义按键模块的行(col)、列(row)数、连接Arduino的脚位以及按键所代表的字元

#include <Keypad.h>    // 引用Keypad程式庫



#define KEY_ROWS 4 // 按鍵模組的列數

#define KEY_COLS 4 // 按鍵模組的行數



// 依照行、列排列的按鍵字元(二維陣列)

char keymap[KEY_ROWS][KEY_COLS] = {

  {'1', '2', '3', 'A'},

  {'4', '5', '6', 'B'},

  {'7', '8', '9', 'C'},

  {'*', '0', '#', 'D'}

};



byte colPins[KEY_COLS] = {9, 8, 7, 6};     // 按鍵模組,行1~4接腳。

byte rowPins[KEY_ROWS] = {13, 12, 11, 10}; // 按鍵模組,列1~4接腳。



// 初始化Keypad物件

// 語法:Keypad(makeKeymap(按鍵字元的二維陣列), 模組列接腳, 模組行接腳, 模組列數, 模組行數)

Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, KEY_ROWS, KEY_COLS);



void setup(){

  Serial.begin(9600);

}

   

void loop(){

  // 透過Keypad物件的getKey()方法讀取按鍵的字元

  char key = myKeypad.getKey();

   

  if (key){  // 若有按鍵被按下…

    Serial.println(key);  // 顯示按鍵的字元

  }

}

编译并上传代码,再开启「序列监控视窗」,按下薄膜键盘的任何按键,该字元将显示在序列端口监控视窗。

按键侦测与扫描原理

为了方便解说,笔者把4×4按键简化成3×1,像下图这样串连三个开关,连接到同一个微控制器的输入脚。此外,因为要简化开关电路,所以要启用微控器内部的上拉电阻


假设开关的「行1」~「行3」输入端全都输入高电位,无论开关是否被按下,Arduino将接收到高电位(1)。为了检测到其中按键被按下,程序必须依序将「行1」~「行3」脚位设定成低电位。


轮到「行2」脚输入低电位,此时,微控器的输入脚也将接收到低电位(0),由此可知连接「行2」的「开关B」被按下了


轮到「行3」脚输入低电位,由于「开关C」未被按下,因此微控器的输入脚接收到高电位(1)。


到此,侦测按键的程序必须再次回到「行1」,输入低电位…如此反复循环扫描,才能持续侦测到某个按键是否被按下。实际的程序需要运用双重循环,才能分批扫描每一列:


双重循环的练习,请参阅《超图解Arduino互动设计入门》第8章「LED矩阵动画与多维数组程序设计」一节,8-28页

自行撰写扫描按键的程序

根据以上说明,自行撰写扫描按键的代码:

const byte colPins[4] = {9, 8, 7, 6};     // 設定「行」腳位

const byte rowPins[4] = {13, 12, 11, 10}; // 設定「列」腳位

const char keymap[4][4] = {     // 設定按鍵的「行、列」代表值

    {'1','2','3','A'},

    {'4','5','6','B'},

    {'7','8','9','C'},

    {'*','0','#','D'}

};



byte i, j;      // 暫存迴圈的索引數字

byte scanVal;   // 暫存掃描到的按鍵值



void setup(){

  Serial.begin(9600);



  for (i = 0; i < = 3; i++) {

    pinMode(rowPins[i], INPUT);

    pinMode(colPins[i], OUTPUT);

    digitalWrite(colPins[i], HIGH);

    digitalWrite(rowPins[i], HIGH);

  }

}



void loop() {

  for (i = 0; i <= 3; i++) {

    for (j = 0; j <= 3; j++) {

      digitalWrite(colPins[j], LOW);

      scanVal = digitalRead(rowPins[i]);



      if (scanVal == LOW) {    // 如果輸入值是「低電位」…

        Serial.println(keymap[i][j]);  // 輸出按鍵代表的字元

        delay(200);  // 掃描按鍵的間隔時間

        digitalWrite(colPins[j], HIGH);

        break;       // 跳出迴圈

      }

      digitalWrite(colPins[j], HIGH);

    }

  }

}

Keypad程序库的运作方式大致上面的程序相同,主要是多了消除弹跳(debounce)的程序(相关说明请参阅第四章「解决开关信号的弹跳问题」一节,4-15页),而且按键扫描的间隔时间是透过比对时间差,而非使用delay。上面的程序用于帮助理解扫描按键的原理,在实际项目制作上,请使用Keypad程序库。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在STM32中使用3x4薄膜矩阵按键的方法如下: 1. 首先,连接薄膜矩阵按键到STM32的GPIO引脚。根据薄膜矩阵按键的布局,将行线连接到STM32的输出引脚,将列线连接到STM32的输入引脚。 2. 在STM32的代码中,配置GPIO引脚为输入或输出模式,并设置相应的上拉或下拉电阻。 3. 使用循环扫描的方法读取按键状态。首先,将所有的行线设置为高电平,然后逐个读取每一列的状态。如果某一列的状态为低电平,则表示该列对应的按键被按下。 4. 根据按键的布局,将按键的行列位置映射到具体的按键值。可以使用一个二维数组来存储按键的映射关系。 5. 在代码中处理按键的逻辑。根据按键的状态进行相应的操作,例如触发事件、发送数据等。 下面是一个示例代码,演示了如何在STM32中使用3x4薄膜矩阵按键: ```c #include "stm32f4xx.h" // 定义按键的行列映射关系 char keyMap[3][4] = { {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'} }; int main(void) { // 配置GPIO引脚为输入或输出模式,并设置上拉或下拉电阻 while (1) { // 将所有的行线设置为高电平 // 逐个读取每一列的状态 for (int col = 0; col < 4; col++) { // 如果某一列的状态为低电平,则表示该列对应的按键被按下 if (GPIO_ReadInputDataBit(GPIOx, GPIO_Pin_x) == 0) { // 根据按键的行列位置映射到具体的按键值 char key = keyMap[row][col]; // 处理按键的逻辑 // ... // 延时一段时间,避免按键的抖动 delay_ms(10); } } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值