单片机STM32入门——(3)矩阵按键

article/2025/1/17 6:14:43

单片机STM32入门——(3)矩阵按键

  • 1.理论分析
    • 1.1键盘扫描方式
    • 1.2行扫描逻辑
    • 1.3列扫描逻辑
  • 2.程序编写
    • 2.1按键扫描程序
      • 2.1.1按键初始化
      • 2.1.2按键扫描程序头文件
      • 2.1.3行扫描函数
      • 2.1.3列扫描函数
    • 2.2主程序

1.理论分析

1.1键盘扫描方式

我们所用到的键盘为4×4矩阵键盘,先分析矩阵键盘的电路连接方式及其扫描方式。根据电路可知

  • 第1 ~ 4行按键的一端分别为P30 ~ P33引脚
  • 第1 ~ 4列按键的另一端分别为P34 ~ P37引脚

4×4矩阵键盘电路
我们将矩阵键盘的接口分别定义为GPIO端口

  • P30-P33(行)引脚分别定义为PD8-PD11(GPIOD端口),且模式为上拉输入(即有按键按下时为0,没有按键按下时为1)
  • P34-P37(列)引脚分别定义为PB12-PB15(GPIOB端口),且模式为推挽输出

我们这里采用将列置0,然后扫描行,当哪一行被按下后,对应的电平置0,此时该按键导通,即可读取到按键值。

1.2行扫描逻辑

首先我们需要定义一个数组用来存放行扫描的结果。
分别存放PD8~PD11的电平值

  • 从GPIOD端口获取行扫描值
  • 判断行扫描值的二进制数
  • 返回对应是第几行按键按下

行扫描程序执行流程

Created with Raphaël 2.2.0 Start 行扫描值 0111 ? return 1 end 1011 ? return 2 1101 ? return 3 1110 ? return 4 return 0 yes no yes no yes no yes no

其中该程序在进行按键扫描时,同样需要进行按键消抖,已经在前一篇中说明,这里就不再赘述。
行扫描结果对应的按键值

PD 8PD 9PD10PD11按键结果
0111第一行被按下
1011第二行被按下
1101第三行被按下
1110第四行被按下

1.3列扫描逻辑

列扫描的执行过程

  • 将每一列依次置0
  • 将行扫描函数返回值赋值给定义的变量key_row_num
  • 判断该变量是否为0
  • 得出按键值

列扫描程序执行流程

Created with Raphaël 2.2.0 Start key_row_num=key_row_scan key_row_num = 0 ? End key_num= X +key_row_num yes no

2.程序编写

2.1按键扫描程序

2.1.1按键初始化

void key_init(){GPIO_InitTypeDef GPIO_InitStruture;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//打开PB时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);//打开PD时钟//定义PB12、PB13、PB14、PB15为推挽输出、分别定义为列GPIO_InitStruture.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStruture.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStruture);//定义PD8、PD9、PD10、PD11为上拉输入、分别定义为四行GPIO_InitStruture.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStruture.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11;GPIO_Init(GPIOD,&GPIO_InitStruture);
}

2.1.2按键扫描程序头文件

头文件中我们编写了按键的行引脚分别对应P8 ~ P11端口,以及按键列引脚的高低电平,分别对应PB12 ~ PB15端口。

#ifndef _KEY16_H
#define _KEY16_H#include "sys.h"
#include "stm32f10x.h"
#include <string.h>//定义行按键的引脚
#define key_row0_Pin GPIO_Pin_8//定义P8为行1
#define key_row1_Pin GPIO_Pin_9//定义P9为行2
#define key_row2_Pin GPIO_Pin_10//定义P10为行3
#define key_row3_Pin GPIO_Pin_11//定义P11为行4//行扫描函数、列扫描函数、初始化函数声明
void key_init();
char key_row_scan(void);
char key_scan(void);//定义列的低电平输出
#define KEY_CLO0_OUT_LOW  GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_RESET) 
#define KEY_CLO1_OUT_LOW  GPIO_WriteBit(GPIOB,GPIO_Pin_13,Bit_RESET)
#define KEY_CLO2_OUT_LOW  GPIO_WriteBit(GPIOB,GPIO_Pin_14,Bit_RESET)
#define KEY_CLO3_OUT_LOW  GPIO_WriteBit(GPIOB,GPIO_Pin_15,Bit_RESET)//定义列的高电平输出
#define KEY_CLO0_OUT_HIGH  GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_SET) 
#define KEY_CLO1_OUT_HIGH  GPIO_WriteBit(GPIOB,GPIO_Pin_13,Bit_SET)
#define KEY_CLO2_OUT_HIGH  GPIO_WriteBit(GPIOB,GPIO_Pin_14,Bit_SET)
#define KEY_CLO3_OUT_HIGH  GPIO_WriteBit(GPIOB,GPIO_Pin_15,Bit_SET)#endif

2.1.3行扫描函数

char key_row_scan(void){key_row[0] = GPIO_ReadInputDataBit(GPIOD, key_row0_Pin)<<3;//读取PD8/第1行key_row[0] = key_row[0] | (GPIO_ReadInputDataBit(GPIOD, key_row1_Pin)<<2);//读取PD9/第2行key_row[0] = key_row[0] | (GPIO_ReadInputDataBit(GPIOD, key_row2_Pin)<<1);//读取PD10/第3行key_row[0] = key_row[0] | (GPIO_ReadInputDataBit(GPIOD, key_row3_Pin));//读取PD11/第4行if(key_row[0] != 0x0f){delay_ms(10);if(key_row[0] != 0x0f){switch(key_row[0]){case 0x07:	//0111 第1行被按下return 1;	case 0x0b:	//1011 第2行被按下return 2;	case 0x0d:	//1101 第3行被按下return 3;case 0x0e:	//1110 第4行被按下return 4;default	:return 0; //没有按键被按下}		}else return 0;	}else return 0;	
} 

2.1.3列扫描函数

char key_scan(void){char key_num=0;       //1-16对应的按键数char key_row_num=0;        //行扫描结果记录KEY_CLO0_OUT_LOW;        if( (key_row_num=key_row_scan()) != 0 ){ while(key_row_scan() != 0);  //消抖key_num = 0 + key_row_num;}KEY_CLO0_OUT_HIGH;KEY_CLO1_OUT_LOW;        if( (key_row_num=key_row_scan()) != 0 ){ while(key_row_scan() != 0);key_num = 4 + key_row_num;//printf("Key_Clo_2\r\n");}KEY_CLO1_OUT_HIGH;KEY_CLO2_OUT_LOW;    if( (key_row_num=key_row_scan()) != 0 ){ while(key_row_scan() != 0);key_num = 8 + key_row_num;//printf("Key_Clo_3\r\n");}KEY_CLO2_OUT_HIGH;KEY_CLO3_OUT_LOW;    if( (key_row_num=key_row_scan()) != 0 ){while(key_row_scan() != 0);key_num = 12 + key_row_num;}KEY_CLO3_OUT_HIGH;return key_num;
}

2.2主程序

主程序通过调用行扫描函数和列扫描函数来输出按键值。

#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
#include "key16.h"
#include "stdio.h"
#include "usart.h"int main(void)
{char key_num_end;delay_init();key_init();NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);uart_init(115200);//波特率while(1){key_num_end = key_scan();if(key_num_end>0&&key_num_end<17){printf("Key_NUM = %d \r\n",key_num_end); //按下1-16个按键的操作printf("= = = = = = = = = = = \r\n");		}	}	
}

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

相关文章

51单片机之按键(独立按键矩阵按键)

难的东西学不会是因为简单的知识没学好 基础不牢&#xff0c;地动山摇 按键 1.1基础温习 &#xff08;1&#xff09;按键的物理结构 &#xff08;2&#xff09;单片机引脚有两种状态&#xff08;I/O&#xff09;输入【读】或者输出【写】 &#xff08;3&#xff09;上拉电阻…

51学习-矩阵按键篇

使用并行接口方式连接键盘&#xff0c;对独立式键盘而言&#xff0c;8根I/O口线可以接 **8** 个按键&#xff0c;而对矩阵式键盘而言&#xff0c;8根I/O口线最多可以接 **64** 个按键。 项目(工程)的时候&#xff0c;我们经常要用到比较多的按键&#xff0c;而且IO资源紧张&am…

4x4矩阵按键应用详解

一.简介 4x4矩阵按键是单片机外部设备中所使用的排布类似于矩阵的按键组。显然矩阵按键的使用要比独立按键要复杂一些&#xff0c;编程也要复杂一些&#xff0c;但可以单片机IO资源。4x4矩阵按键即分为4组列线&#xff0c;4组行线&#xff0c;并将行线所接的单片机的I/O口作为…

独立按键和矩阵按键c语言,第八章 独立按键和矩阵按键

我们和单片机之间进行信息交互,主要包含两大类,输入设备和输出设备。前边讲的LED小灯、数码管、点阵都是输出设备,这节课我们学习一下最常用的输入设备——按键。在本节课的学习过程中我们还会穿插介绍一点硬件设计的基础知识。 8.1单片机最小系统电路解析 8.1.1电源 我们在…

单片机 矩阵式按键

单片机 矩阵式按键 一、简述 在单片机应用系统中&#xff0c;通过按键实现数据输入及功能控制是非常普遍的&#xff0c;通常在所需按键数量不多时&#xff0c;系统常采用独立式按键。需要按键数量比较多&#xff0c;为了减少I/O口的占用&#xff0c;通常将按键排列成矩阵。测…

矩阵按键原理和BUG

当我们的电路有很多按键时&#xff0c;一般会采用矩阵方式与单片机相连来减少对单片机IO的浪费&#xff0c;如下图方式。 这个电路的原理: 1、比如检测S13是否按下&#xff0c;单片机把Line4设为输出&#xff0c;并输出低电平&#xff0c;而Line3、Line2、Line1设为开路输入&…

关于矩阵按键

前段时间老师讲了矩阵按键&#xff0c;就把程序的理解写下来 看图片&#xff0c;只有主函数和串口。串口在此用来发送我们的按键值&#xff0c;波特率9600&#xff0c;频率11.0592。 我们用的是4*4矩阵按键 我们的矩阵按键连在了单片机的P0口&#xff08;stc15f2k60s2&#xf…

独立按键和矩阵按键c语言,单片机独立按键与矩阵按键原理图

当前位置:电工之家 > 电工知识 > 单片机 > 正文 单片机独立按键与矩阵按键原理图 时间:2017-02-22 12:40 来源:电工之家 单片机独立按键与矩阵按键原理图 独立按键 通常的按键分为独立式按键和矩阵式按键两种,独立式按键比较简单,并且与独立的输入线相连接,如图13…

【按键扫描】矩阵按键之多按键扫描

前言 上一章我们介绍了经典矩阵键盘的实现方法&#xff0c;但是示例程序中仅实现了单按键检测功能。虽说单按键已经基本可以覆盖矩阵键盘的常见需求&#xff0c;但在一些特殊应用场合&#xff0c;我们仍然需要多按键识别操作&#xff0c;或者一些类似电脑组合按键的功能支持。…

STM32矩阵按键

矩阵按键原理 本实验使用STM32F103单片机&#xff0c;主题代码通用的。 如果每个按键占用一个GPIO引脚&#xff0c;对于使用多个按键来说就是一种资源的浪费&#xff0c;因此当我们在设计时&#xff0c;可以考虑矩阵这种方式。本实验使用4*4也就是16个按键。 矩阵按键相对于独立…

【按键扫描】独立按键与矩阵按键

按键介绍 我们通常提到按键&#xff0c;一般是指按键开关&#xff0c;也称为轻触开关。轻触开关是最常用的几种电子元器件之一&#xff0c;被各种电子产品广泛使用。 轻触开关与普通开关类似&#xff0c;但又略有不同。普通开关有闭合与断开两种状态&#xff0c;切换后状态会…

矩阵按键实验

矩阵按键简介 以 4*4 矩阵键盘为例。 16 个按键被排成 4 行 4 列&#xff0c;第一行将每个按键的一端连接在一起构成行线&#xff0c;第一列将每个按键的另一端连接在一起构成列线&#xff0c;这样便一共有 4 行 4 列共 8 根线&#xff0c;如图所示&#xff1a; 将这 8 根线连接…

51单片机学习记录(五)矩阵按键

文章目录 1、矩阵按键的控制原理2、矩阵按键实现1、行列式法实现矩阵按键2、线翻转法实现矩阵按键3、按键实战 1、矩阵按键的控制原理 独立按键与单片机连接时&#xff0c; 每一个按键都需要单片机的一个 I/O 口&#xff0c; 若某单片机系统需较多按键&#xff0c; 如果用独立…

51单片机矩阵键盘扫描及使用方法

一、矩阵键盘简介 矩阵键盘&#xff0c;也称矩阵按键&#xff0c;是为了节约单片机IO口占用所引入的一种外设。 &#xff08;图片截取至普中A2开发板原理图&#xff09; &#xff08;图片截取至普中A2开发板实物图&#xff09; 我们知道&#xff0c;一个独立按键需要1个IO口。但…

单片机编辑库四之矩阵按键

单片机编辑库一之延时与led灯 单片机编辑库二之按键 单片机编辑库三之蜂鸣器 单片机编辑库四之矩阵按键 之前为大家介绍了独立按键的原理和使用方法&#xff0c;这一章给大家带来一个升级体验——矩阵按键&#xff0c;话不多说&#xff0c;直接开始今天的内容。 一、矩阵按键…

51单片机——矩阵按键实验,小白讲解,相互学习

矩阵按键介绍&#xff1a; 独立按键与单片机连接时&#xff0c;每一个按键都需要单片机的一个I/O 口&#xff0c;若某单片机系统需较多按键&#xff0c;如果用独立按键便会占用过多的I/O 口资源.单片机系统中I/O 口资源往往比较宝贵&#xff0c;当用到多个按键时为了减少I/O 口…

STM32----矩阵按键

一、实物图 二、开发流程 分析&#xff1a;对于矩阵按键&#xff0c;我们一般采用行列扫描反转的方法进行开发&#xff0c;分别把每一个引脚连接一个GPIO口并设置一半成通用推挽输出模式&#xff0c;一半为上拉输入模式&#xff0c;行列扫描反转进行判断按击的按键来判断行列从…

(五)矩阵按键

本章我们主要是写矩阵键盘的内容&#xff0c;矩阵键盘的原理和独立按键的按键原理基本是类似的&#xff0c;只是关于整个的原理还是要有些介绍&#xff0c;本章我们通过矩阵按键的某个按键按下&#xff0c;然后在数码管上输出对应的按键值。 1.关于按键 可以看前面按键的内容…

【STM32 基础实验矩阵按键】

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

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

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