587 字
3 分钟
STM32F103 实现 4x4 矩阵键盘的扫描
直接放一个实物图在这里
接线放在这里~
| STM32F103C8T6 | 4x4 |
|---|---|
| A0 | C4 |
| A1 | C3 |
| A2 | C2 |
| A3 | C1 |
| A4 | R1 |
| A5 | R2 |
| A6 | R3 |
| A7 | R4 |
实现原理
遍历矩阵的每一行,开始时将当前遍历的行设置为 低电平,再扫描每一列并判断找出为低电平的列号,符合要求时记录行号和列号 结束当前行时再将当前行设置为 高电平
源代码
MATRIX_KEY_Sx 的编号由行号和列号组成 matrix_key.h
#ifndef __MATRIX_KEY__#define __MATRIX_KEY__
#include <stm32f10x.h>
#define ROW_PINS (GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7) // 定义行引脚为GPIOA的4、5、6、7#define COL_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3) // 定义列引脚为GPIOA的0、1、2、3
// 第1行#define MATRIX_KEY_S1 0x18 // 0001 1000#define MATRIX_KEY_S2 0x14 // 0001 0100#define MATRIX_KEY_S3 0x12 // 0001 0010#define MATRIX_KEY_S4 0x11 // 0001 0001// 第2行#define MATRIX_KEY_S5 0x28 // 0010 1000#define MATRIX_KEY_S6 0x24 // 0010 0100#define MATRIX_KEY_S7 0x22 // 0010 0010#define MATRIX_KEY_S8 0x21 // 0010 0001// 第3行#define MATRIX_KEY_S9 0x48 // 0100 0100#define MATRIX_KEY_S10 0x44 // 0100 0100#define MATRIX_KEY_S11 0x42 // 0100 0010#define MATRIX_KEY_S12 0x41 // 0100 0001// 第4行#define MATRIX_KEY_S13 0x88 // 1000 1000#define MATRIX_KEY_S14 0x84 // 1000 0100#define MATRIX_KEY_S15 0x82 // 1000 0010#define MATRIX_KEY_S16 0x81 // 1000 0001
void Init_Matrix_Key(void);
void Scan_Matrix_Key(void (*Call_Back)(uint8_t));
#endifmatrix_key.c
#include <stm32f10x.h>#include <Delay.h>#include <matrix_key.h>
void Init_Matrix_Key(void) { GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIOA时钟
// 设置行引脚为推挽输出 GPIO_InitStructure.GPIO_Pin = ROW_PINS; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);
// 设置列引脚为上拉输入 GPIO_InitStructure.GPIO_Pin = COL_PINS; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStructure);}
void Scan_Matrix_Key(void (*Call_Back)(uint8_t)) { uint8_t row, col; uint8_t keyDetected = 0;
for (row = 0; row < 4; row++) { // 遍历行 GPIO_ResetBits(GPIOA, 1 << (row + 4)); // 将当前行置为低电平,注意这里使用1 << (row + 4)来选中行 Delay_us(10); // 短暂延时以稳定电平
for (col = 0; col < 4; col++) { // 遍历列 if (GPIO_ReadInputDataBit(GPIOA, 1 << col) == Bit_RESET) { // 判断该列是否为低电平 Delay_ms(100); // 延时去抖动 if (GPIO_ReadInputDataBit(GPIOA, 1 << col) == Bit_RESET) { // 再次检查,确认按键被按下 keyDetected = (1 << col) | (1 << (row + 4)); // 记录按键位置 Call_Back(keyDetected); break; // 跳出列循环,因为同一时间只能有一个按键被按下 } while(GPIO_ReadInputDataBit(GPIOA, 1 << col) == Bit_RESET);// 等待弹起 } } GPIO_SetBits(GPIOA, 1 << (row + 4)); // 恢复该行至高电平 if (keyDetected) { break; // 如果检测到按键,跳出行循环 } }}在 main 中调用
void Matrix_Key_Callback(uint8_t key) { switch(key) { case MATRIX_KEY_S1: // TODO break; }}
int main(void) { Init_Matrix_Key(); // 初始化 while (1) { Scan_Matrix_Key(Matrix_Key_Callback); }}你可以在串口中输出按键的号码~
STM32F103 实现 4x4 矩阵键盘的扫描
https://memo.moieo.net/2024/07/09/194457/