【STM32 基础实验矩阵按键】

article/2025/1/17 14:02:19

文章目录

    • 一、元器件矩阵键盘说明
    • 二、基于stm32f10c8t6 基础实验矩阵按键
      • (1)实验功能实现说明
      • (2)矩阵键盘原理
      • (3)代码部分
      • (4)效果展示
    • 三、总结与扩展
      • 附上参考文献链接与视频链接出处

一、元器件矩阵键盘说明

本次实验采用4*4矩阵键盘进行应用,矩阵键盘为了节约引脚的占用,提供了多行多列的排列组合为矩形的按键,所以为矩阵按键或矩阵键盘。如图所示:
矩阵键盘

二、基于stm32f10c8t6 基础实验矩阵按键

(1)实验功能实现说明

本实验通过stm32和矩阵按键实现点亮LED,以二进制的方式显示。如二进制的0000,对应四颗LED都熄灭;二进制的0001,对应第四颗LED点亮,其余三颗熄灭,以此类推;即1亮0灭。0.96寸OLED显示反馈的键值(以两个单位),如key1—01,key5----05,key11—11…;以按键响应对应的键值和二进制显示的LED。矩阵按键实现方法:1.响应对应中断的方法。2.行列扫描的方法。本实验主要是采用第二种方法,更容易理解。

(2)矩阵键盘原理

原理图

在这里插入图片描述

行列扫描法:
矩阵按键扫描方式理解图如下:
矩阵按键
解释说明:左边的填充以横向理解,右边的填充以竖向理解。
首先可以看到0x00ff,表示行列的按键均未接触,0x00fe 竖向1110表示第一行接触,那么等待第一行的第几列进行下一步接触,当第一行的第一列同时响应接触,那么表示第一行第一列对应的LED以二进制0001的方式进行显示,即点亮第四颗灯。
0x00fd 竖向1101表示第二行接触,那么等待第二行的第几列进行下一步接触,当第二行的第三列同时响应接触,那么表示第二行第三列对应的LED以二进制1101的方式进行显示,即点亮第一、二、四颗灯。
0x00fb 竖向1011表示第三行接触,那么等待第三行的第几列进行下一步接触,当第三行的第一、三列同时响应接触,那么表示第三行第一、三列对应的LED以二进制0101的方式进行显示,即点亮第二、四颗灯。
第四行同理可得。

(3)代码部分

keys.c


#include "stm32f10x.h"
#include "keys.h"
#include "delay.h"
//	 //********************************************************************************
u8 FLAG = 0;void KEY_4x4_Init(void) //IO初始化
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitStructure.GPIO_Pin  = KEY_HANG;  //行  0123GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(KEY_PROT, &GPIO_InitStructure);GPIO_SetBits(KEY_PROT,KEY_HANG);//init GPIOA	  上拉输入GPIO_InitStructure.GPIO_Pin  = KEY1|KEY2|KEY3|KEY4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(KEY_PROT, &GPIO_InitStructure);GPIO_SetBits(KEY_PROT,KEY1|KEY2|KEY3|KEY4);}void KEY_Scan(u8 *key) 
{	 GPIO_Write(KEY_PROT,0x00fe);//第一行if((KEY1_Input==RESET)||(KEY2_Input==RESET)||(KEY3_Input==RESET)||(KEY4_Input==RESET))   {delay_ms(10);//去抖动 if(KEY1_Input==RESET){FLAG = 1;*key = 1;while(!GPIO_ReadInputDataBit(KEY_PROT,KEY1));}else if(KEY2_Input==RESET){FLAG = 1;*key = 2;while(!GPIO_ReadInputDataBit(KEY_PROT,KEY2));}else if(KEY3_Input==RESET){FLAG = 1;*key = 3;while(!GPIO_ReadInputDataBit(KEY_PROT,KEY3));}else if(KEY4_Input==RESET){FLAG = 1;*key = 4;while(!GPIO_ReadInputDataBit(KEY_PROT,KEY4));}else {FLAG = 0;GPIO_Write(KEY_PROT,0x00ff);}}GPIO_Write(KEY_PROT,0x00fd);//第二行if((KEY1_Input==RESET)||(KEY2_Input==RESET)||(KEY3_Input==RESET)||(KEY4_Input==RESET)){delay_ms(10);//去抖动 if(KEY1_Input==RESET){FLAG = 1;*key = 5;while(!GPIO_ReadInputDataBit(KEY_PROT,KEY1));}else if(KEY2_Input==RESET){FLAG = 1;*key = 6;while(!GPIO_ReadInputDataBit(KEY_PROT,KEY2));}else if(KEY3_Input==RESET){FLAG = 1;*key = 7;while(!GPIO_ReadInputDataBit(KEY_PROT,KEY3));}else if(KEY4_Input==RESET){FLAG = 1;*key = 8;while(!GPIO_ReadInputDataBit(KEY_PROT,KEY4));}else {FLAG = 0;GPIO_Write(KEY_PROT,0x00ff);}}GPIO_Write(KEY_PROT,0x00fb);//第三行if((KEY1_Input==RESET)||(KEY2_Input==RESET)||(KEY3_Input==RESET)||(KEY4_Input==RESET)){delay_ms(10);//去抖动 if(KEY1_Input==RESET){FLAG = 1;*key = 9;while(!GPIO_ReadInputDataBit(KEY_PROT,KEY1));}else if(KEY2_Input==RESET){FLAG = 1;*key = 10;while(!GPIO_ReadInputDataBit(KEY_PROT,KEY2));}else if(KEY3_Input==RESET){FLAG = 1;*key = 11;while(!GPIO_ReadInputDataBit(KEY_PROT,KEY3));}else if(KEY4_Input==RESET){FLAG = 1;*key = 12;while(!GPIO_ReadInputDataBit(KEY_PROT,KEY4));}else {FLAG = 0;GPIO_Write(KEY_PROT,0x00ff);}}GPIO_Write(KEY_PROT,0x00f7);//第四行if((KEY1_Input==RESET)||(KEY2_Input==RESET)||(KEY3_Input==RESET)||(KEY4_Input==RESET)){delay_ms(10);//去抖动 if(KEY1_Input==RESET){FLAG = 1;*key = 13;while(!GPIO_ReadInputDataBit(KEY_PROT,KEY1));}else if(KEY2_Input==RESET){FLAG = 1;*key = 14;while(!GPIO_ReadInputDataBit(KEY_PROT,KEY2));}else if(KEY3_Input==RESET){FLAG = 1;*key = 15;while(!GPIO_ReadInputDataBit(KEY_PROT,KEY3));}else if(KEY4_Input==RESET){FLAG = 1;*key = 16;while(!GPIO_ReadInputDataBit(KEY_PROT,KEY4));}else {FLAG = 0;GPIO_Write(KEY_PROT,0x00ff);}}}

keys.h

#ifndef __KEYS_H
#define __KEYS_H	 
//	 //********************************************************************************
//V1.1修改说明
//修改按键扫描函数,使整个代码可以支持SWD下载。
//	 
#include "stm32f10x.h"#define KEY_HANG 0x000f   //0123
#define KEY1 GPIO_Pin_4   
#define KEY2 GPIO_Pin_5	   
#define KEY3 GPIO_Pin_6	 
#define KEY4 GPIO_Pin_7   #define KEY1_Input GPIO_ReadInputDataBit(KEY_PROT,KEY1)
#define KEY2_Input GPIO_ReadInputDataBit(KEY_PROT,KEY2)
#define KEY3_Input GPIO_ReadInputDataBit(KEY_PROT,KEY3)
#define KEY4_Input GPIO_ReadInputDataBit(KEY_PROT,KEY4)#define KEY_PROT GPIOAextern u8 FLAG;void KEY_4x4_Init(void);//IO初始化
//u8 KEY_Scan(void);
void KEY_Scan(u8 *key);  //按键扫描函数		#endif

main.c

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "keys.h"
//#include "usart.h"
#include "OLED.h"/*接线说明
PA0~PA3-------R4~R1   //行
PA4~PA7-------C4~C1   //列
*/u8 key = 0;u8 i;int main(void){LED_Init(); 	delay_init();KEY_4x4_Init();//uart_init(115200);OLED_Init();/*OLED初始化界面*/OLED_ShowChar(1, 1, 'A');OLED_ShowString(1, 3, "HelloWorld!");OLED_ShowNum(2, 1, 12345, 5);OLED_ShowSignedNum(2, 7, -66, 2);OLED_ShowHexNum(3, 1, 0xAA55, 4);OLED_ShowBinNum(4, 1, 0xAA55, 16);while(1){   KEY_Scan(&key);   //获取键值keyif(FLAG == 1)    //按键按下{FLAG = 0;OLED_Clear();OLED_ShowNum(2, 1, key, 2);   //显示键值key//Printf("KEY = %d\r\n",key);if(key==1)  //0001{GPIO_SetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14);GPIO_ResetBits(GPIOB,GPIO_Pin_15);	}				if(key==2)  //0010{GPIO_SetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_15);GPIO_ResetBits(GPIOB,GPIO_Pin_14);	}								if(key==3)  //0011{GPIO_SetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13);GPIO_ResetBits(GPIOB,GPIO_Pin_14|GPIO_Pin_15);	}				if(key==4)  //0100{GPIO_SetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_14|GPIO_Pin_15);GPIO_ResetBits(GPIOB,GPIO_Pin_13);	}		if(key==5)  //0101{GPIO_SetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_14);GPIO_ResetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_15);	}				if(key==6)  //0110{GPIO_SetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_15);GPIO_ResetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14);	}		 if(key==7)  //0111{GPIO_SetBits(GPIOB,GPIO_Pin_12);GPIO_ResetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);	}				if(key==8)  //1000{GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);GPIO_ResetBits(GPIOB,GPIO_Pin_12);	}		if(key==9)  //1001{GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14);GPIO_ResetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_15);	}				if(key==10)  //1010{GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_15);GPIO_ResetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_14);	}		if(key==11) //1011{GPIO_SetBits(GPIOB,GPIO_Pin_13);GPIO_ResetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_14|GPIO_Pin_15);	}				if(key==12)  //1100{GPIO_SetBits(GPIOB,GPIO_Pin_14|GPIO_Pin_15);GPIO_ResetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13);	}		if(key==13)  //1101{GPIO_SetBits(GPIOB,GPIO_Pin_14);GPIO_ResetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_15);	}				if(key==14)  //1110{GPIO_SetBits(GPIOB,GPIO_Pin_15);GPIO_ResetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14);	}		if(key==15)  //1111{GPIO_ResetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);	}				if(key==16)  //来回闪烁4次{for(i=0;i<4;i++){GPIO_ResetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13);GPIO_SetBits(GPIOB,GPIO_Pin_14|GPIO_Pin_15);	delay_ms(1000);					GPIO_SetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13);GPIO_ResetBits(GPIOB,GPIO_Pin_14|GPIO_Pin_15);	delay_ms(1000);	}						}				//LCD12864_Write_Number(0x8d,key);}}}

(4)效果展示

矩阵按键实验效果:

矩阵按键

三、总结与扩展

总结:
根据以上内容,学习矩阵按键,跟轻触按键类似还是容易理解的,给输入信号给stm32以驱动LED相应点亮或熄灭。矩阵按键主要是应用需求多数按键解决引脚少的情况。
总结调试代码或硬件中,针对可能出现的问题,说明一下:
(1)出现按键响应慢的情况:因为矩阵按键模块的触发所用的为行列扫描,比中断触发响应的速度较慢;代码部分按键扫描延迟过高,或者去抖动(10ms~20ms)。
(2)出现按键硬件无响应的情况:可能是由于键盘模块引脚与stm32引脚接线错误或接反;也可能是对应引脚冲突占用,需要调用AFIO端口复用转换为普通I/O,也许即可解决;还可能是硬件坏了的问题,或者铜暴露出来导致的短路。
扩展: 可通过矩阵键盘模块可以做简易计算器、密码锁、功能键等实验。那么就分享到这,大胆尝试实践探索吧,欢迎讨论。

今日就分享到此了,要有信心一步步积累理论和实践经验,一起学习加油!

附上参考文献链接与视频链接出处

链接: 参考文献
链接: 参考视频
链接: 矩阵按键视频分享
链接: 源码例程
提取码:3232


http://chatgpt.dhexx.cn/article/BNX13kal.shtml

相关文章

51单片机入门——矩阵按键

文章目录 1.按键1.1.独立按键1.2.矩阵按键 2.按键的扫描与抖动2.1.独立按键的扫描2.2.按键抖动与消抖2.3.矩阵按键的扫描 3.简易计算器 1.按键 1.1.独立按键 常用的按键电路有两种形式&#xff0c;独立式按键和矩阵式按键&#xff0c;独立式按键比较简单&#xff0c;它们各自…

mac怎么给移动硬盘分区

我们经常用Windows系统给移动硬盘分区&#xff0c;对于Windows系统的操作我们是非常熟悉的&#xff0c;但是现在很多人都在使用苹果电脑&#xff0c;那么如何用Mac给硬盘分区呢&#xff1f;这个可是需要技术的。如果我们不会用Mac系统给移动硬盘分区&#xff0c;当我们在Mac上插…

ntfs格式的移动硬盘如何在mac电脑写入?

随着照片视频等技术的进步&#xff0c;这类文件越发清晰的同时&#xff0c;占用内存也越来越大&#xff0c;人们逐渐将其中不常用到的存入移动硬盘中&#xff0c;以此减少电脑空间占用。目前国内大多数移动硬盘均为Windows自研的NTFS格式&#xff0c;对于这类NTFS格式的移动硬盘…

mac怎么删除硬盘里面的东西?为什么苹果电脑无法删除移动硬盘文件?

mac怎么删除硬盘里面的东西&#xff1f;由于移动硬盘的文件系统是NTFS格式的&#xff0c;而这种格式与Mac电脑是不兼容的&#xff0c;Mac电脑没有权限对移动硬盘上的数据进行操作&#xff0c;Mac上不能把移动硬盘的数据删除了&#xff0c;那么&#xff0c;有没有什么操作方法&a…

苹果电脑怎么用移动硬盘ntfs?快速读取和编辑Mac外置移动硬盘

苹果电脑怎么用移动硬盘ntfs&#xff1f;如果你对电脑比较熟悉的话&#xff0c;可能知道NTFS磁盘格式。该格式专门为Windows系统设计的&#xff0c;也称为Windows NT文件系统。从Windows系统迁移到Mac可能是一项相当困难的任务&#xff0c;因为NTFS格式的硬盘在Mac上不能正常工…

如何在Mac上给移动硬盘加密

随着人们的安全意识越来越强&#xff0c;手机加密、Wi-Fi加密&#xff0c;甚至平时工作的U盘、移动硬盘也要加密。在Mac上对移动硬盘加密并不是很难&#xff0c;通过磁盘工具对硬盘进行格式化处理&#xff0c;并重新选择磁盘格式便可实现加密。下面就让我们来看具体的操作吧&am…

mac无法在移动硬盘上新建文件夹 mac如何在移动硬盘新建文件夹

明明是新买的硬盘&#xff0c;为什么把移动硬盘插入Mac后&#xff0c;Mac无法在移动硬盘上新建文件夹呢&#xff1f;相信很多Mac用户都曾遇到过Mac无法在移动硬盘上新建文件夹的问题。为什么会出现这样的问题呢&#xff1f;用户应该怎么解决呢&#xff1f;本文就来为大家介绍ma…

Mac无法写入移动硬盘 这些软件帮你解决

疫情期间因工作需要&#xff0c;从淘宝上买了一个移动硬盘&#xff0c;将公司的文件拷贝到这个移动硬盘上&#xff0c;并没有发现什么问题&#xff0c;一拿回到家里就懵圈了&#xff0c;突然发现里面的文件都无法进行修改或剪切粘贴。 一番百度之后&#xff0c;我找到了原因&a…

Mac如何拷贝文件到移动硬盘

haha~ 看到这个标题不要以为博主这是傻了: “切, 往移动硬盘拷文件谁不会啊~”, “又在故弄玄虚, 就这也写博客~” … 确实, 我要把这个写成博客了. 因为今天要拷贝MacOS Sierra安装包到另外一台电脑上, 安装包有4.7个G, U盘果断不行, 于是换上移动硬盘, 连上电脑, 将安装包拖入…

Mac下如何把iphone资料备份到移动硬盘

一般的备份方法 首先新系统的iphone备份已经转到了访达 连接iphone后在访达左边栏会看到你的手机 在终端输入下面这段命令行 ln -s /Volumes/Data/ios_backup &#xff5e;/Library/Application\ Support/MobileSync/Backup /Volumes/Data/ios_backup 这行是你想要指定的目…

怎样将iphone照片通过MAC导入移动硬盘?

iMazing是一款第三方的苹果iOS设备管理软件&#xff0c;大家使用数据线或Wi-Fi将苹果设备与电脑进行连接以后&#xff0c;就可以用它进行音乐传输、照片传输和数据备份等操作。 它支持Windows系统和Mac系统&#xff0c;下面通过一篇教程&#xff0c;教大家如何通过Mac系统的iM…

mac怎么用ntfs硬盘 NTFS移动硬盘怎么在mac上使用

品牌型号:MacBook Air 系统:macOS 10.13 软件版本:Tuxera Ntfs for mac 2020 初次接触到Mac电脑的用户&#xff0c;会发现自己的移动硬盘或U盘连接到电脑后仅有只读权限&#xff0c;并不能对其写入数据。这和移动硬盘格式有着密切的关系&#xff0c;NTFS格式在Mac电脑上并不…

mac不识别移动硬盘导致无法拷贝资源

背景 硬盘插入到Mac电脑上之后&#xff0c;mac不识别移动硬盘导致无法拷贝资源。 移动硬盘在Mac上无法被识别的原因可能有很多&#xff0c;多数情况下&#xff0c;是硬盘的格式与Mac电脑不兼容。 文件系统格式不兼容 macOS使用的文件系统是HFS或APFS&#xff0c;如果移动硬盘是…

Mac不能复制拷贝写入文件到移动硬盘/U盘解决办法

1.有的小伙伴把移动硬盘或 U 盘接入到 Mac 电脑上&#xff0c;当把文件拷贝到移动硬盘时&#xff0c;会发现不能复制文件到移动硬盘。这里因为移动硬盘或 U 盘是使用 Windows 系统下的 NTFS 分区格式&#xff0c;而 Mac 系统原生是不支持这种格式的&#xff0c;也就是为什么不能…

windows移动硬盘接到mac上使用(加载ntfs移动硬盘)

也就是将NTFS格式的移动硬盘&#xff0c;连接到mac上进行存储。 目录 步骤如下&#xff1a;1、接入硬盘&#xff0c;查看Device Node2、推出硬盘&#xff0c;一般桌面就有对应图标&#xff0c;右键推出就行3、建个目录&#xff0c;然后把硬盘挂上去就行4、解挂载硬盘 步骤如下…

ntfs硬盘如何在mac上读写移动硬盘文件?

在日常的工作中&#xff0c;总是避免不了跨平台的传输文件、文件共享等&#xff0c;例如一些用户使用Mac电脑修图或者剪辑视频之后需要拷贝到Windows电脑上查看。对于需要同时使用Mac和Windows的用户来说&#xff0c;系统之间不兼容是很大的阻碍&#xff0c;尤其是使用NTFS移动…

Mac 移动硬盘没有推出,再插上不显示移动硬盘解决办法

1.写在前面 你是否遇到移动硬盘读不出来的情况呢&#xff1f; 我们或多或少都有外接存储设备&#xff0c;一般电脑买的存储内存小&#xff0c;或者有拷贝资料需要的时候&#xff0c;我们都需要外接一个移动硬盘。 而作为 iOS 开发&#xff0c;使用的是 Mac 电脑&#xff0c;在…

如何让移动硬盘在Mac和Windows上通用使用

刚入手了一块新的移动硬盘&#xff0c;Mac电脑插上却发现一片空白无法使用&#xff0c;这是什么情况呢&#xff1f; 原来一般一块新的大容量移动硬盘刚入手时&#xff0c;默认是NTFS格式&#xff0c;这是Windows的一种特有硬盘格式&#xff0c;但是Mac上只能读取不能写入。 Ma…

如何在苹果电脑复制文件到移动硬盘或U盘 MAC系统读写NTFS

现在用苹果电脑的用户越来越多&#xff0c;在使用的过程中我们免不了会使用一些硬盘设备来存储文件或者是数据&#xff0c;然而绝大多数的移动硬盘都是在windows系统下创建的ntfs格式。但ntfs格式在苹果Mac OS X 10.3系统后才对NTFS格式只支持读写&#xff0c;不能写入。 就是…

Mac下将文件复制到移动硬盘

现象分析&#xff1a; 如果你在使用Mac系统时&#xff0c;发现Mac系统和移动硬盘之间无法拷贝数据&#xff0c;很有可能你的移动硬盘是NTFS格式的&#xff0c;因为目前苹果系统的硬盘格式暂时不兼容这样的格式拷贝&#xff0c;只能从NTFS格式拷贝到Mac&#xff0c;而不能从Mac…