直接放一个实物图在这里![实物图](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=)
接线放在这里~
STM32F103C8T6 |
4x4 |
A0 |
C4 |
A1 |
C3 |
A2 |
C2 |
A3 |
C1 |
A4 |
R1 |
A5 |
R2 |
A6 |
R3 |
A7 |
R4 |
实现原理
遍历矩阵的每一行,开始时将当前遍历的行设置为 低电平,再扫描每一列并判断找出为低电平的列号,符合要求时记录行号和列号
结束当前行时再将当前行设置为 高电平
源代码
MATRIX_KEY_Sx 的编号由行号和列号组成
matrix_key.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #ifndef __MATRIX_KEY__ #define __MATRIX_KEY__
#include <stm32f10x.h>
#define ROW_PINS (GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7) #define COL_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3)
#define MATRIX_KEY_S1 0x18 #define MATRIX_KEY_S2 0x14 #define MATRIX_KEY_S3 0x12 #define MATRIX_KEY_S4 0x11
#define MATRIX_KEY_S5 0x28 #define MATRIX_KEY_S6 0x24 #define MATRIX_KEY_S7 0x22 #define MATRIX_KEY_S8 0x21
#define MATRIX_KEY_S9 0x48 #define MATRIX_KEY_S10 0x44 #define MATRIX_KEY_S11 0x42 #define MATRIX_KEY_S12 0x41
#define MATRIX_KEY_S13 0x88 #define MATRIX_KEY_S14 0x84 #define MATRIX_KEY_S15 0x82 #define MATRIX_KEY_S16 0x81
void Init_Matrix_Key(void);
void Scan_Matrix_Key(void (*Call_Back)(uint8_t));
#endif
|
matrix_key.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #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);
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)); 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 中调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void Matrix_Key_Callback(uint8_t key) { switch(key) { case MATRIX_KEY_S1: break; } }
int main(void) { Init_Matrix_Key(); while (1) { Scan_Matrix_Key(Matrix_Key_Callback); } }
|
你可以在串口中输出按键的号码~
![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=)
![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII=)