Skip to content

Commit

Permalink
STM32F103 实现 4x4 矩阵键盘的扫描
Browse files Browse the repository at this point in the history
  • Loading branch information
moieo committed Jul 9, 2024
1 parent d444dd4 commit 12193eb
Showing 1 changed file with 144 additions and 0 deletions.
144 changes: 144 additions & 0 deletions source/_posts/STM32F103-实现-4x4-矩阵键盘的扫描.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
---
title: STM32F103 实现 4x4 矩阵键盘的扫描
date: 2024-07-09 19:44:57
cover:
categories:
- STM32
- 嵌入式
tags:
- STM32
- 单片机
- MCU
- 嵌入式
---


直接放一个实物图在这里![实物图](https://preview.cloud.189.cn/image/imageAction?param=2561B53DE643174BDEFD95D5816918035E7CEE4FB9690172962BEE3D133D3A4677095922A1CD95EF9231E68A982630E65999F3E3914ECF3773AB80EFC6D9CA05FCBA6ED09C3D60D069AC63C13E6959AC6E539287EEC71656C2BDC15EBB8147A6BD5ED6E01E46E8E24E25C38B65B7A2A8103B5057)
接线放在这里~

| STM32F103C8T6 | 4x4 |
| --- | --- |
| A0 | C4 |
| A1 | C3 |
| A2 | C2 |
| A3 | C1 |
| A4 | R1 |
| A5 | R2 |
| A6 | R3 |
| A7 | R4 |

## 实现原理
遍历矩阵的每一行,开始时将当前遍历的行设置为 低电平,再扫描每一列并判断找出为低电平的列号,符合要求时记录行号和列号
结束当前行时再将当前行设置为 高电平

## 源代码
MATRIX_KEY_Sx 的编号由行号和列号组成
matrix_key.h
```c
#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));

#endif
```

matrix_key.c
```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 中调用
```c
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);
}
}
```

你可以在串口中输出按键的号码~
![](https://preview.cloud.189.cn/image/imageAction?param=E8D28D4DD8268574D1B55EEB925E126321B71374462A2471B6A5E5CE9F5FE78EC23D621BD9E573D40AA8B476CD5C165F61ED90ACC51C792099A082BA3BF677B37748CF1A6C5E7B2DCABD897D8999C6822F878C924EE235B32B22F4043F79785FEEB213769A4FFA6EA1FC82529384364E46C9F9D4)
![](https://preview.cloud.189.cn/image/imageAction?param=B10247C30F3C971823503110465F4537D8A07C9CE3C43FE2B051347C66F2D57D00307D4103E6D9F8774472465E64F29F2DA7C33880D311B33148E8A12CDAB7557D800A1BF9C5B5FDA9FD8DFD55A30FC6BABA801914D35FDCA54F8F0EC502A109BFB42942C381899E0E7720D001BDF289B24B718A)

0 comments on commit 12193eb

Please sign in to comment.