找回密码
 立即注册
查看: 90|回复: 2

8 x 8 (或A x B?) 矩阵按键 按键处理 单击或长按?

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:347
  • 最近打卡:2025-05-01 08:57:33
已绑定手机

30

主题

111

回帖

1659

积分

荣誉版主

Rbowlystar

积分
1659
发表于 4 天前 | 显示全部楼层 |阅读模式

8 x 8 (或A x B?) 矩阵按键 按键处理 单击&长按

目录:【虹星宝典】记录单片机学习之旅——目录

注:从本例程起,使用USB-CDC模式进行程序下载。

矩阵按键原理

image.png

以这个8x8的矩阵按键为例:

image.png

如何实现64个按键的扫描?

试想一下,当我们给KA通电时,对K1-K8的状态进行读取,如果有按键按下,那么对应的端口就会由低电平变成高电平,由此即可判断哪一个按键按下了。

如此反复对K1-KH端口置高电平,读取K1-K8端口的状态,便可以实现8x8矩阵按键的扫描,一般会对置高电平的端口配置为推挽输出模式,对读取的端口设置为高阻输入+下拉的模式。

如此便可写一个扫描按键是否按下的函数,对与N x N的矩阵按键原理也是大同小异的。

image.png

image.png

如何实现按键状态的判断?

一般的,按键分为 ”未按下“ ”消抖“ ”单击“ ”长按“等多种状态,为了更好的区分当按键按下时处于什么状态,确定一个时基便十分重要了,例如我以10ms为一次扫描时间间隔基准,即每10ms扫描一次按键状态,并保存这个按键按下的时长,通过判断按下的时长,即可推断出按键为何种状态。

案例中以按下到松开的时长在2s内时,判断为单击动作。按下超过2s时,判断为长按动作。

image.png

实例展示(仅展示部分代码)

这里以10ms作为扫描时基,如果A1为单击操作则打印“A1 Press!”,其他按键同理。

image.png

演示视频:

2 喜欢他/她就送朵鲜花吧,赠人玫瑰,手有余香!
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:347
  • 最近打卡:2025-05-01 08:57:33
已绑定手机

30

主题

111

回帖

1659

积分

荣誉版主

Rbowlystar

积分
1659
发表于 4 天前 | 显示全部楼层
4-Key.zip (335.5 KB, 下载次数: 1)



2025-04-29:
推出支持自定义行列引脚模式的矩阵按键扫描函数,真正实现任意AxB行列式矩阵按键扫描
欢迎小伙伴们体验测试 4-Key(AxB).zip (366.44 KB, 下载次数: 0)
截图202504292348292304.jpg

回复 支持 反对

使用道具 举报 送花

3

主题

1160

回帖

1031

积分

等待验证会员

积分
1031
发表于 4 天前 | 显示全部楼层
矩阵按键扫描与状态判断的实现

矩阵按键扫描原理

在嵌入式系统中,矩阵按键是一种常见的输入设备,通过减少I/O引脚的使用数量,实现多按键的检测。以8x8矩阵按键为例,其基本原理如下:

1. 硬件连接:矩阵按键通常由行和列组成,例如8行8列共64个按键。每一行和每一列分别连接到微控制器的I/O引脚。
  
2. 扫描方法:
行扫描:将某一行置为高电平(推挽输出模式),其余行置为低电平。
列检测:读取每一列的状态(高阻输入+下拉模式)。如果某一列检测到高电平,说明该列与当前行的交叉点有按键按下。
循环扫描:依次对每一行进行上述操作,完成整个矩阵的扫描。

3. 状态判断:
消抖处理:按键在按下和释放时可能会产生抖动,需要通过软件消抖算法来消除抖动影响。
时基确定:以10ms为扫描间隔,记录按键按下的时长。
状态分类:根据按下的时长,将按键状态分为“未按下”、“消抖”、“单击”和“长按”等。

按键状态判断的实现

1. 时基与扫描:
以10ms为时基,每隔10ms进行一次按键扫描。
记录每个按键按下的时长,通过判断时长来区分不同的按键状态。

2. 状态分类:
单击:按键按下到松开的时长在2秒内。
长按:按键按下超过2秒。

实例代码展示

以下是一个简化的按键扫描与状态判断的代码示例:
  1. c
  2. include
  3. include
  4. include
  5. define ROWS 8
  6. define COLS 8
  7. define DEBOUNCETIME 20 // 消抖时间20ms
  8. define LONGPRESSTIME 2000 // 长按时间2000ms
  9. uint8t keymatrix[ROWS][COLS] = {0}; // 按键矩阵状态
  10. uint16t keypresstime[ROWS][COLS] = {0}; // 按键按下时长
  11. void scankeys() {
  12.     static uint16t debouncecounter[ROWS][COLS] = {0};
  13.     for (uint8t row = 0; row < ROWS; row++) {
  14.         // 设置当前行为高电平
  15.         setrowhigh(row);
  16.         for (uint8t col = 0; col < COLS; col++) {
  17.             // 读取列状态
  18.             bool keystate = readcol(col);
  19.             if (keystate) {
  20.                 if (debouncecounter[row][col] < DEBOUNCETIME) {
  21.                     debouncecounter[row][col]++;
  22.                 } else {
  23.                     keypresstime[row][col]++;
  24.                 }
  25.             } else {
  26.                 if (debouncecounter[row][col] > 0) {
  27.                     debouncecounter[row][col]--;
  28.                 } else {
  29.                     if (keypresstime[row][col] > 0) {
  30.                         if (keypresstime[row][col] < LONGPRESSTIME) {
  31.                             printf("Key [%d][%d] Press!\n", row, col);
  32.                         } else {
  33.                             printf("Key [%d][%d] Long Press!\n", row, col);
  34.                         }
  35.                         keypresstime[row][col] = 0;
  36.                     }
  37.                 }
  38.             }
  39.         }
  40.         // 恢复当前行为低电平
  41.         setrowlow(row);
  42.     }
  43. }
  44. int main() {
  45.     while (1) {
  46.         scankeys();
  47.         delayms(10); // 10ms时基
  48.     }
  49.     return 0;
  50. }
复制代码

总结

通过上述方法,可以实现对8x8矩阵按键的扫描与状态判断。关键在于合理设置时基、消抖处理以及按键状态的分类。这种方法同样适用于其他规模的矩阵按键,只需调整行和列的数量即可。在实际应用中,还需根据具体硬件和需求进行优化和调整。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-1 19:44 , Processed in 0.118351 second(s), 64 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表