当前位置:首页 > 每日看点 > 正文内容

如何按下一个矩阵键盘,松开后直到按下另个键盘之前,显示不消失?

卡卷网1年前 (2024-11-30)每日看点208

矩阵键盘本质:

矩阵键盘本质是使用8个IO口来进行16个按键的控制读取,可以减小IO口的使用,用4条I/O线作为行线,4条I/O线作为列线组成的键盘。在行线和列线的每个交叉点上,设置一个按键。而这样的按键中按键的个数是4 X 4个。

这样的行列式键盘结构能够有效地提高单片机系统中I/O口的利用率。节约单片机的资源,其本质和独立按键类似,就是进行逐行扫描和逐列扫描,然后判断是第几行的第几列的按键,进而进行整体按键值得确定。

具体实物图如下:

如何按下一个矩阵键盘,松开后直到按下另个键盘之前,显示不消失?  第1张

矩阵键盘扫描的方式有两种: 1.行列扫描,2.逐行/逐列扫描

行列扫描:适用于8个IO口接到了单片机8个连续的IO口,可以使用行列扫描

逐行/逐列扫描:适用于矩阵键盘接到了任意的IO口,则使用逐行,逐列扫描

本文主要说明逐行扫描的方式

逐行/列扫描:

逐行,逐列扫描的本质和行列扫描比较类似,本质是给某一行/某一列,低电平,其余七个全部为高电平,这时候读取电平变换,有电平变低表示按键按下,即可读取按键数据。

逐行扫描:

  1. 置第1行为低电平,其余N-1行和N列为高电平,
  2. 读取列线数据,列线有低电平表示此行有按键按下,比如按下的是1行三列(1x3),那么第三列的列线IO口就为低电平。
  3. 置第2行为低电平,其余N-1行和N列为高电平,,读取列线数据,列线有低电平表示此行有按键按下。
  4. 以此类推,进行逐行扫描。
  5. 根据行线列线的电平不同可以识别是否有按键按下,哪一个按键按下,获取按键号。(N) 根据按键号跳转至对应的按键处理程序。

如何按下一个矩阵键盘,松开后直到按下另个键盘之前,显示不消失?  第2张

硬件连接

行线与列线:在硬件上,4条行线连接到微控制器的输出引脚,而4条列线连接到微控制器的输入引脚。

按键位置:每个按键位于行线和列线的交叉点上。

如何按下一个矩阵键盘,松开后直到按下另个键盘之前,显示不消失?  第3张

GPIO初始化

行线:

通常设置为输出模式,用于向列线发送扫描信号。

扫描信号:

行线的主要功能是向列线发送扫描信号。当某一行线被设置为低电平时,与之相交的列线会被检测(若相对应的按键被按下,列线被检测为低电平)以判断是否有按键被按下。

确定按键行

通过依次将每一行线设置为低电平(可以逐行扫描键盘)。当检测到列线上有低电平时,可以确定被按下的按键位于当前选中的行上。若列线上无低电平,那么将此行线设置为高电平,下一行设置为低电平,进行新一轮按键检测。

列线

设置为输入模式,用于读取按键状态。

读取按键状态

列线的主要功能是读取按键状态。(STM32就靠列线来确认按键状态)当某一行线被选中(设置为低电平)时,微控制器会读取所有列线的电平状态,以判断是否有按键被按下。

注意事项

在实际应用中,还需要考虑去抖处理、中断处理等因素,以确保按键检测的准确性和稳定性。

Cube MX配置GPIO

使用stm32CubeMX软件配置GPIO:

PA0-PA3的配置是一样的(做行线,设置为输出模式)

如何按下一个矩阵键盘,松开后直到按下另个键盘之前,显示不消失?  第4张

PA4-PA7的配置是一样的(做列线,设置为输入模式)

如何按下一个矩阵键盘,松开后直到按下另个键盘之前,显示不消失?  第5张

有用到OLED模块,故配置SCL,SDA,做通讯线

如何按下一个矩阵键盘,松开后直到按下另个键盘之前,显示不消失?  第6张

时钟频率的话,可以选择默认的

如何按下一个矩阵键盘,松开后直到按下另个键盘之前,显示不消失?  第7张

如何按下一个矩阵键盘,松开后直到按下另个键盘之前,显示不消失?  第8张

配置完GPIO的相关资源后,就可以在Keil5软件里编写功能模块

(代码中用到的Delay模块和OLED模块是外部导入的)

(Delay也可以用HAL库自带的,OLED可以网上找找)

#include <main.h> #include "Delay.h" /** * @brief 矩阵键盘读取按键键码 * @param 无 * @retval KeyNumber 按下按键的键码值 如果按键按下不放,程序会停留在此函数,松手的一瞬间,返回按键键码,没有按键按下时,返回0 */ void GPIOAallset() { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET); } uint8_t MatrixKey(void) { uint8_t KeyNumber=0; GPIOAallset(); //把PA0-PA7全置为高电平 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); //PA0置0,开始检测第一行 if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4)==0) { Delay_ms(10); while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4)); //当按钮处于被按下的状态的时候,程序一直卡在循环读取按钮的状态,避免多按钮同时按下时读取错误 Delay_ms(10); KeyNumber=1; } if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5)==0) { Delay_ms(10); while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5)); Delay_ms(10); KeyNumber=2; } if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6)==0) { Delay_ms(10); while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6)); Delay_ms(10); KeyNumber=3; } if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7)==0) { Delay_ms(10); while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7)); Delay_ms(10); KeyNumber=4; } GPIOAallset(); //把PA0-PA7全置为高电平 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); //PA1置0,开始检测第二行 if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4)==0) { Delay_ms(10); while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4)); //当按钮处于被按下的状态的时候,程序一直卡在循环读取按钮的状态,避免多按钮同时按下时读取错误 Delay_ms(10); KeyNumber=5; } if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5)==0) { Delay_ms(10); while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5)); Delay_ms(10); KeyNumber=6; } if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6)==0) { Delay_ms(10); while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6)); Delay_ms(10); KeyNumber=7; } if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7)==0) { Delay_ms(10); while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7)); Delay_ms(10); KeyNumber=8; } GPIOAallset(); //把PA0-PA7全置为高电平 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); //PA2置0,开始检测第三行 if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4)==0) { Delay_ms(10); while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4)); //当按钮处于被按下的状态的时候,程序一直卡在循环读取按钮的状态,避免多按钮同时按下时读取错误 Delay_ms(10); KeyNumber=9; } if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5)==0) { Delay_ms(10); while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5)); Delay_ms(10); KeyNumber=10; } if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6)==0) { Delay_ms(10); while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6)); Delay_ms(10); KeyNumber=11; } if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7)==0) { Delay_ms(10); while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7)); Delay_ms(10); KeyNumber=12; } GPIOAallset(); //把PA0-PA7全置为高电平 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); //PA3置0,开始检测第四行 if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4)==0) { Delay_ms(10); while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4)); //当按钮处于被按下的状态的时候,程序一直卡在循环读取按钮的状态,避免多按钮同时按下时读取错误 Delay_ms(10); KeyNumber=13; } if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5)==0) { Delay_ms(10); while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5)); Delay_ms(10); KeyNumber=14; } if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6)==0) { Delay_ms(10); while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6)); Delay_ms(10); KeyNumber=15; } if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7)==0) { Delay_ms(10); while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7)); Delay_ms(10); KeyNumber=16; } return KeyNumber; }

主函数部分:

while (1) { OLED_ShowString(2, 1,"NUM:"); num = MatrixKey(); if(num) { OLED_ShowNum(2, 5, num, 2); } }

仿真图片:

如何按下一个矩阵键盘,松开后直到按下另个键盘之前,显示不消失?  第9张

扫描二维码推送至手机访问。

版权声明:本文由卡卷网发布,如需转载请注明出处。

本文链接:https://www.kajuan.net/ttnews/2024/11/2236.html

分享给朋友:

相关文章

短视频如何快速变现?

短视频如何快速变现?

单人日产200条视频,一晚狂赚上千元,过程却简单到荒唐。只要你像这只猥琐的海鸥一样,做到这3点就行↓↓点开有惊喜速度快、不讲武德、不被发现那做短视频如何做到这3点?答案是养一只会叼视频的海鸥不是让你养真的海鸥而是用 ai 运营方法,类似于“...

B 站上有哪些很好的学习资源?

B 站上有哪些很好的学习资源?

前!方!高!能!精选了多位学习Up主,不乏百万粉丝的大V,还有超多珍贵的学习资源推荐。进了小破站,完全不用担心学完了该怎么办?因为根本学不完啊!!!B站的学习干货实在太多了!语言学习葉子先生酱https://space.bilibili.c...

小米15就要来了,不知道小米15值不值得买?

小米15就要来了,不知道小米15值不值得买?

俗话说得好,好饭不怕晚,看似有点姗姗来迟的小米15系列,一官宣就迅速登上热搜。在此次小米14发布会上,雷军曾说过小米14将是最后一代3999起的旗舰,那么这一次涨价了的小米15,值不值得买呢?下面为大家总结一下小米15将会有哪些升级点:软件...

想学习Linux下的ELF文件有什么好书推荐吗?

想学习Linux下的ELF文件有什么好书推荐吗?

大家好,这里是物联网心球。 今天我们来聊聊ELF文件,了解一下Linux如何创建进程以及ELF文件如何转变成Linux进程?1.什么是ELF文件? ELF(Executable and Linkable Format)文...

什么样的网站能快速捕获你的心?

什么样的网站能快速捕获你的心?

大家好,我是程序员鱼皮。大家如果平时使用网站或产品时出现了问题,一般都会去寻找 “联系客服” 的位置,从而获得人工的帮助。我们团队的面试刷题产品 - 面试鸭最近就遇到了这样一个难题:明明我们网站右下角就有联系客服按钮、而且我们每道面试题目下...

常微分方程的理论对偏微分方程的研究有没有帮助?

常微分方程的理论对偏微分方程的研究有没有帮助?

之前看到过一句话,好像是 Bourgain 说的,大意是做 ode 的做到深处就到了 pde,做 pde 的做到深处就到了 ode,ode 和 pde 最后是相通的。以我目前有限的知识,只知道下面两个方向:1. Hamilton 系统在现代...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。