欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > 矩阵键盘原理与单片机驱动设计详解—端口反转法(下) | 零基础入门STM32第七十八步

矩阵键盘原理与单片机驱动设计详解—端口反转法(下) | 零基础入门STM32第七十八步

2025/3/30 20:01:15 来源:https://blog.csdn.net/liwangsb2/article/details/146405048  浏览:    关键词:矩阵键盘原理与单片机驱动设计详解—端口反转法(下) | 零基础入门STM32第七十八步
主题内容教学目的/扩展视频
4x4阵列键盘电路连接,电路原理,驱动程序,调用函数。能用程序读出按键值。

师从洋桃电子,杜洋老师


📑文章目录

    • 一、矩阵键盘驱动架构设计
      • 1.1 系统整体架构
      • 1.2 硬件资源配置
    • 二、核心驱动实现分析
      • 2.1 初始化函数解析
      • 2.2 按键扫描流程图
      • 2.3 按键解码算法
    • 三、关键技术创新点
      • 3.1 动态IO模式切换
      • 3.2 复合消抖策略
    • 四、扩展设计指南
      • 4.1 扩展为8x8矩阵
      • 4.2 多按键组合检测
    • 五、性能优化建议
      • 5.1 中断驱动方案
      • 5.2 功耗优化措施
    • 六、工程调试技巧
      • 6.1 示波器诊断法
      • 6.2 调试输出接口
    • 七、相关资源


▲ 回顾上期🔍矩阵键盘原理与单片机驱动设计详解(上) | 零基础入门STM32第七十七步


一、矩阵键盘驱动架构设计

1.1 系统整体架构

系统采用三层架构设计:

+-----------------------+
| 应用层(OLED显示处理)  |
+-----------------------+
| 驱动层(按键扫描逻辑)   |
+-----------------------+
| 硬件层(GPIO端口控制)  |
+-----------------------+

1.2 硬件资源配置

基于STM32F103的4x4矩阵键盘硬件连接:

功能GPIO引脚模式配置
行线PA0-PA3推挽输出/上拉输入
列线PA4-PA7上拉输入/推挽输出

二、核心驱动实现分析

2.1 初始化函数解析

// KEYPAD4x4.c
void KEYPAD4x4_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 列线配置(PA4-PA7)GPIO_InitStructure.GPIO_Pin = KEYa | KEYb | KEYc | KEYd;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  // 上拉输入模式GPIO_Init(KEYPAD4x4PORT, &GPIO_InitStructure);// 行线配置(PA0-PA3)GPIO_InitStructure.GPIO_Pin = KEY1 | KEY2 | KEY3 | KEY4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(KEYPAD4x4PORT, &GPIO_InitStructure);
}

2.2 按键扫描流程图

主程序 驱动层 硬件层 KEYPAD4x4_Read() 行线置低,列线输入 读取列线状态 消抖处理(20ms) 反转IO模式 读取行线状态 合并两次扫描结果 键值解码(switch-case) 返回键值 主程序 驱动层 硬件层

2.3 按键解码算法

// 键值映射表
static const uint8_t keymap[16] = {
/* 0xee */ 16, /* 0xed */15, /* 0xeb */14, /* 0xe7 */13,
/* 0xde */12, /* 0xdd */11, /* 0xdb */10, /* 0xd7 */9,
/* 0xbe */8,  /* 0xbd */7,  /* 0xbb */6,  /* 0xb7 */5,
/* 0x7e */4,  /* 0x7d */3,  /* 0x7b */2,  /* 0x77 */1
};u8 KEYPAD4x4_Read(void){// ...(省略扫描过程)uint8_t keycode = (a | b) ^ 0xFF; // 异或取反得到有效位return keymap[(keycode & 0xF0)>>4 | (keycode & 0x0F)];
}

三、关键技术创新点

3.1 动态IO模式切换

通过两次初始化实现端口角色反转:

void KEYPAD4x4_Init2(void){// 反转行/列配置GPIO_InitStructure.GPIO_Pin = KEY1 | KEY2 | KEY3 | KEY4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  // 改为输入GPIO_InitStructure.GPIO_Pin = KEYa | KEYb | KEYc | KEYd;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 改为输出
}

3.2 复合消抖策略

采用双重检测机制:

  1. 初次电平变化检测
  2. 20ms延时后二次确认
  3. 按键释放检测
if(初次检测到电平变化){delay_ms(20);          // 硬件消抖if(确认电平有效){       // 软件消抖// 执行扫描...while(等待按键释放); // 防粘连处理}
}

四、扩展设计指南

4.1 扩展为8x8矩阵

修改硬件连接与初始化配置:

// 扩展GPIO配置
#define ROW_PORT  GPIOA
#define COL_PORT  GPIOB// 修改初始化函数
void KEYPAD8x8_Init(void){// 行线配置PA0-PA7// 列线配置PB0-PB7
}

4.2 多按键组合检测

增加状态机处理:

typedef struct {uint8_t current;uint8_t last;uint32_t timestamp;
} KeyState;void KeyProcess_FSM(KeyState* state){if(state->current != state->last){if(HAL_GetTick() - state->timestamp > 20){if(state->current) HandleKeyPress(state->current);state->last = state->current;}state->timestamp = HAL_GetTick();}
}

五、性能优化建议

5.1 中断驱动方案

// 配置GPIO中断
void EXTI0_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line0)){KeyScan_Handler();EXTI_ClearITPendingBit(EXTI_Line0);}
}

5.2 功耗优化措施

模式电流消耗实现方法
运行模式8.2mA正常扫描
休眠模式1.5mA关闭未使用外设时钟
深度睡眠模式0.2mA使用外部中断唤醒

六、工程调试技巧

6.1 示波器诊断法

测量典型信号波形

6.2 调试输出接口

添加SWO调试输出:

void KeyScan_Debug(uint8_t key){ITM_SendChar('K');ITM_SendChar('E');ITM_SendChar('Y');ITM_SendChar(':');ITM_SendChar(key + '0');
}

七、相关资源

[1] 洋桃电子B站课程-STM32入门100步
[2] STM32官方文档手册
[3] STM32F103固件函数库用户手册(中文)
[4] 阵列键盘测试程序


💬 技术讨论(请在评论区留言~)

📌 下期预告:下一期将探讨外部中断原理与驱动,欢迎持续关注!

点击查阅🔍往期【STM32专栏】文章

版权声明:本文采用[CC BY-NC-SA 4.0]协议,转载请注明来源
实测开发版:洋桃1号开发版(基于STM32F103C8T6)
更新日志

  • v1.0 初始版本(2025-03-23)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词