【开源免费】STM32矩阵键盘驱动程序:从零搭建4×4键盘扫描与消抖完整实战项目分享

项目概述

在嵌入式系统开发中,输入设备是人机交互的关键一环。相较于独立按键,矩阵键盘在引脚资源紧张的应用场景中显得尤为重要——例如计算器、密码锁、工业仪表、智能家居控制面板等。一个 4×4 矩阵键盘只需要 8 个 I/O 引脚就能扫描 16 个按键,比起 16 个独立按键节省了一半的引脚开销,对于 STM32 这类资源相对宝贵的 MCU 来说极具吸引力。

本项目”STM32矩阵键盘驱动程序”基于 STM32F103C8T6(也兼容 STM32F4 系列),实现了完整的 4×4 矩阵键盘扫描驱动,主要特点包括:

  • 支持行列扫描法反转扫描法两种实现,可以根据应用场景灵活选择
  • 支持软件消抖机制,避免按键抖动导致的多次误触发
  • 支持短按、长按、连按三种按键事件
  • 提供回调函数注册接口,方便上层应用集成
  • 模块化设计,方便二次开发,兼容 HAL 库与标准外设库两种开发模式
  • 提供完整源码

通过本项目,你将掌握矩阵键盘扫描、GPIO 输入输出配置、消抖算法的基本原理、开发流程以及实际应用方法。

完整源码下载

源码已打包,包含完整工程、配套资料及相关资源。

本站服务器维护不易,但我深知资料对大家的重要性。因此,我决定放弃向其他博主那样收费,转而选择免费开放全部资源。

下载源码压缩包

项目原理

矩阵键盘的核心思想是把按键排列成 M 行 N 列的矩阵,每个按键位于行线和列线的交点。当按下某个按键时,对应的行线和列线被短接。MCU 通过依次拉低(或拉高)一行,再读取列线状态,就能判断该行哪一个按键被按下。

整个扫描流程如下:系统上电后先完成 GPIO 初始化——行线配置为推挽输出并全部置高,列线配置为上拉输入。然后启动一个 10ms 周期的定时器中断,每次中断到来时依次将 ROW0~ROW3 拉低,读取 COL0~COL3 的电平状态。如果检测到某根列线为低电平,说明当前拉低的行与该列交点处的按键被按下,由此可计算出按键的行列索引并映射为 KeyCode。读取到的键值进入消抖流程:消抖计数器累加,只有连续 3 次(30ms)扫描结果一致才认为是有效按键。有效按键后与上次键值比较,若不一致则触发 PRESS 事件;若一致且按下时长超过 1s 则触发 LONG_PRESS 事件,之后每 200ms 触发一次 REPEAT 事件。当按键释放时触发 RELEASE 事件。所有事件均通过用户注册的回调函数通知上层应用。

整个驱动以 10ms 为扫描周期,配合 30ms 软件消抖窗口,可以稳定识别人手按键的所有典型操作。

硬件(或开发环境)

本项目采用 STM32F103C8T6 最小系统板,开发环境为 STM32CubeIDE 或 Keil MDK,依赖 STM32 HAL 库。矩阵键盘行列接线如下:

信号STM32 引脚方向说明
ROW0PA0推挽输出第 1 行
ROW1PA1推挽输出第 2 行
ROW2PA2推挽输出第 3 行
ROW3PA3推挽输出第 4 行
COL0PA4上拉输入第 1 列
COL1PA5上拉输入第 2 列
COL2PA6上拉输入第 3 列
COL3PA7上拉输入第 4 列

为了避免按键悬空时输入不确定,列线必须使用 STM32 内部上拉电阻或外接 4.7kΩ 上拉电阻。

【开源免费】STM32矩阵键盘驱动程序:从零搭建4x4键盘扫描与消抖完整实战项目分享

实现说明

初始化流程

驱动初始化时先开启 GPIOA 时钟,然后将 PA0~PA3 配置为推挽输出模式并初始置高电平,将 PA4~PA7 配置为上拉输入模式。行线置高是为了在空闲状态下所有按键都处于断开状态,避免误触发。初始化完成后注册用户回调函数指针,供后续事件通知使用。

核心扫描算法

扫描采用行列扫描法:每次扫描时先将所有行线置高,然后依次将 ROW0~ROW3 逐行拉低。每拉低一行后,短暂等待电平稳定(通过空循环延时),再读取 COL0~COL3 的状态。如果某根列线读到低电平,说明该行该列交点的按键被按下,通过二维查找表 key_map 即可将行列索引映射为对应的键值(如 ‘1’、’A’ 等)。如果四行全部扫描完毕均未检测到低电平,则返回 KEY_NONE 表示无按键。

消抖处理

机械按键在按下和释放瞬间会产生 5~20ms 的电平抖动,如果不做消抖,单次按键可能被识别为多次触发。本驱动采用计数法消抖:维护一个消抖计数器,每次扫描到相同键值时计数器加 1,只有连续 3 次(即 30ms)扫描结果一致才认为是有效按键。相比传统的 delay() 阻塞式消抖,计数法不会阻塞 CPU,适合在定时器中断中使用。此外还维护了上次键值变量,用于判断按键状态变化(按下/释放)。

长按与连按机制

长按是嵌入式输入设备常见需求(例如长按 3s 进入配置菜单)。驱动通过一个 press_tick 计数器累加扫描周期数实现:当按键稳定按下超过 100 个周期(1s)时触发 LONG_PRESS 事件;此后每 20 个周期(200ms)触发一次 REPEAT 事件,可用于音量加减、数字递增等连续调节场景。按键释放时触发 RELEASE 事件,同时清零所有计数器,回到初始状态。

中断驱动 vs 轮询驱动

本驱动采用 TIM 定时器中断 + 函数回调的方式,10ms 扫描一次,CPU 占用率极低(实测 < 0.5%)。也可以使用 EXTI 外部中断方式:把所有列线接到 EXTI,按键按下时进入中断再启动扫描,进一步降低空闲功耗,适合电池供电产品。

开发注意事项

  • HAL_Delay 不能在中断中使用:扫描函数内部的电平稳定延时必须使用空循环或 __NOP(),不能调用 HAL_Delay。
  • IO 复用问题:PA4~PA7 默认为 SPI1 引脚,使用前注意关闭 SPI 时钟或选择其它 GPIO。
  • 键值映射可配置:key_map 是一个二维数组,根据实际按键丝印灵活修改即可。
  • 抗干扰措施:在工业环境中可以在每根列线上并联 100nF 电容到 GND,进一步过滤高频干扰。

项目扩展

  • OLED/LCD12864 配合实现密码输入界面
  • 接入 FreeRTOS,把按键事件发送到队列,多任务消费
  • 用于电子琴项目,每个按键对应一个音符,配合 PWM 输出方波
  • 改造为 USB HID 键盘,让 STM32 变身机械键盘控制器
  • 门禁系统中作为密码输入面板,配合 RFID 实现双因子认证

总结

本项目完整实现了一个工业级可用的 STM32 矩阵键盘驱动功能,涵盖了 GPIO 配置、行列扫描算法、软件消抖、按键事件抽象、回调注册 等核心内容,代码结构清晰,可直接应用于实际项目,也方便根据需求继续扩展。希望本文能够帮助大家快速掌握 嵌入式矩阵键盘驱动开发 的方法。

声明:本站全部项目均免费开源。部分项目来源于开源项目二改、改进、整合,仅供学习与交流,版权归原作者所有。如有侵权,请联系删除。Email: hai52ca@qq.com

正文完
 0