单片机矩阵键盘实现指南:源码详解与操作指南

单片机:实现矩阵键盘

1. 项目背景与目标

矩阵键盘(Matrix Keyboard)是一种广泛应用于嵌入式系统中的输入设备。它通过将多个按钮布置成行列结构来实现按键输入。相较于独立按键,矩阵键盘的优势在于节省了GPIO引脚,可以通过较少的引脚控制多个按键。常见的矩阵键盘包括4×4、4×3、3×3等格式。

本项目的目标是使用单片机(如STM32、8051、AVR等)实现一个4×4矩阵键盘的扫描和按键输入检测。通过矩阵键盘的按键输入,我们可以触发相关操作或输出信息。

2. 硬件设计
2.1 硬件组件
  1. 单片机:可使用STM328051AVR等系列的单片机。
  2. 矩阵键盘:选择一个标准的4×4矩阵键盘,包含16个按键,排列成4行4列。
  3. LED显示屏(可选):用于显示按下的按键或操作结果。
  4. 电源:为单片机和外部设备提供电源。
2.2 硬件连接
  1. 矩阵键盘:矩阵键盘有8个引脚,分别连接到单片机的GPIO口。每一行连接一个GPIO输出端口,每一列连接一个GPIO输入端口。

  2. 行(Row):连接到单片机的输出引脚。
  3. 列(Column):连接到单片机的输入引脚,并且使用上拉电阻。
  4. LED显示(可选):可连接LED或数码管来显示按键的状态。

3. 软件设计
3.1 矩阵键盘工作原理

矩阵键盘通常由两部分组成:行(Rows)和列(Columns)。每个按键都是行和列交点上的一个开关。通过逐行扫描的方式,当某一行输出低电平时,读取每一列的状态。如果某一列检测到低电平,则表明该列的某个按键被按下。

扫描步骤

  1. 按顺序将行引脚设置为低电平,其他行保持高电平(或不驱动)。
  2. 检测所有列的状态。如果某一列为低电平,则表示按键被按下。
  3. 确定按下的是哪个按键,读取该列和行的交点。
3.2 程序设计思路
  1. 矩阵键盘扫描:设置GPIO口作为行和列的输入输出。逐行扫描并检测按键状态。
  2. 按键去抖动:按键会产生抖动信号,因此需要去抖动处理,通常使用延时或软件算法进行去抖。
  3. 按键映射:根据矩阵按键的位置确定每个按键的对应值(如数字、字符等)。
  4. 显示或响应:根据按键输入进行操作,如显示数字、触发相应的动作等。
3.3 代码实现

以下是基于STM32单片机的4×4矩阵键盘扫描代码实现:

#include "stm32f4xx_hal.h"

#define ROW_COUNT   4  // 行数
#define COL_COUNT   4  // 列数

// 矩阵键盘的行和列引脚
#define ROW_PIN1     GPIO_PIN_0
#define ROW_PIN2     GPIO_PIN_1
#define ROW_PIN3     GPIO_PIN_2
#define ROW_PIN4     GPIO_PIN_3

#define COL_PIN1     GPIO_PIN_4
#define COL_PIN2     GPIO_PIN_5
#define COL_PIN3     GPIO_PIN_6
#define COL_PIN4     GPIO_PIN_7

GPIO_TypeDef* ROW_PORT = GPIOA;  // 假设行连接在GPIOA
GPIO_TypeDef* COL_PORT = GPIOB;  // 假设列连接在GPIOB

// 行列按键映射表
char keymap[ROW_COUNT][COL_COUNT] = {
    {'1', '2', '3', 'A'},
    {'4', '5', '6', 'B'},
    {'7', '8', '9', 'C'},
    {'*', '0', '#', 'D'}
};

// GPIO初始化
void GPIO_Init(void) {
    __HAL_RCC_GPIOA_CLK_ENABLE();  // 使能GPIOA时钟
    __HAL_RCC_GPIOB_CLK_ENABLE();  // 使能GPIOB时钟

    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // 初始化行引脚为输出模式
    GPIO_InitStruct.Pin = ROW_PIN1 | ROW_PIN2 | ROW_PIN3 | ROW_PIN4;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(ROW_PORT, &GPIO_InitStruct);

    // 初始化列引脚为输入模式,并启用上拉电阻
    GPIO_InitStruct.Pin = COL_PIN1 | COL_PIN2 | COL_PIN3 | COL_PIN4;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(COL_PORT, &GPIO_InitStruct);
}

// 扫描矩阵键盘
char scan_keypad(void) {
    for (int row = 0; row < ROW_COUNT; row++) {
        // 设置当前行输出低电平,其他行输出高电平
        for (int i = 0; i < ROW_COUNT; i++) {
            if (i == row) {
                HAL_GPIO_WritePin(ROW_PORT, (1 << i), GPIO_PIN_RESET);  // 当前行低电平
            } else {
                HAL_GPIO_WritePin(ROW_PORT, (1 << i), GPIO_PIN_SET);  // 其他行高电平
            }
        }

        // 检测列的状态
        for (int col = 0; col < COL_COUNT; col++) {
            if (HAL_GPIO_ReadPin(COL_PORT, (1 << (col + 4))) == GPIO_PIN_RESET) {
                // 按键被按下,返回对应的字符
                return keymap[row][col];
            }
        }
    }
    return 0;  // 如果没有按键按下,返回0
}

// 主程序
int main(void) {
    HAL_Init();  // 初始化HAL库
    GPIO_Init();  // 初始化GPIO

    char key;  // 存储按键值

    while (1) {
        key = scan_keypad();  // 扫描按键
        if (key != 0) {
            // 输出按下的键值或执行相关操作
            // 例如:通过串口输出或在LED上显示
            // 这里的代码可以根据需求修改
            HAL_Delay(200);  // 防止重复触发,增加按键去抖动
        }
    }
}
3.4 代码解释
  1. GPIO初始化GPIO_Init()函数初始化矩阵键盘的行和列引脚。行引脚设置为输出模式,列引脚设置为输入模式,并启用上拉电阻。
  2. 矩阵键盘扫描scan_keypad()函数负责扫描矩阵键盘。每次扫描时,将一行设置为低电平,其他行保持高电平。然后检测所有列的电平状态。如果某一列为低电平,则表示对应的按键被按下。
  3. 按键映射keymap数组定义了矩阵按键的位置与按键值之间的对应关系。
  4. 按键去抖动:每次扫描完毕后,使用HAL_Delay(200)延时200ms来避免按键抖动产生的错误读取。
4. 仿真与测试
4.1 电路设计
  1. 在Proteus中创建STM32单片机的仿真项目,并添加4×4矩阵键盘模块。
  2. 连接行和列引脚到STM32单片机的GPIO端口。
4.2 仿真步骤
  1. 编译并上传代码到仿真环境。
  2. 模拟按下矩阵键盘上的各个按键,观察是否能正确识别按下的按键,并进行相应处理。
5. 总结

本项目成功实现了基于矩阵键盘的按键扫描功能。通过扫描行列的方式,检测按键的输入,配合按键映射表,能够正确识别按下的按键并进行相应的处理。该方案适用于需要节省GPIO引脚并支持多个按键输入的嵌入式系统中。矩阵键盘的应用非常广泛,如控制面板、密码输入、计算器等系统中都能看到其身影。

作者:Katie。

物联沃分享整理
物联沃-IOTWORD物联网 » 单片机矩阵键盘实现指南:源码详解与操作指南

发表回复