STM32F103 实现 4x4 矩阵键盘的扫描

直接放一个实物图在这里 接线放在这里~

直接放一个实物图在这里实物图 接线放在这里~

STM32F103C8T64x4
A0C4
A1C3
A2C2
A3C1
A4R1
A5R2
A6R3
A7R4

实现原理

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

源代码

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) // 定义行引脚为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

 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); // 使能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 中调用

 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:
      // TODO
      break;
  }
}

int main(void) {
  Init_Matrix_Key(); // 初始化	
  while (1) {
    Scan_Matrix_Key(Matrix_Key_Callback);
  }
}

你可以在串口中输出按键的号码~

昵称
邮箱
网址
0/500
  • OωO
  • |´・ω・)ノ
  • ヾ(≧∇≦*)ゝ
  • (☆ω☆)
  • (╯‵□′)╯︵┴─┴
  •  ̄﹃ ̄
  • (/ω\)
  • ∠( ᐛ 」∠)_
  • (๑•̀ㅁ•́ฅ)
  • →_→
  • ୧(๑•̀⌄•́๑)૭
  • ٩(ˊᗜˋ*)و
  • (ノ°ο°)ノ
  • (´இ皿இ`)
  • ⌇●﹏●⌇
  • (ฅ´ω`ฅ)
  • (╯°A°)╯︵○○○
  • φ( ̄∇ ̄o)
  • ヾ(´・ ・`。)ノ"
  • ( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
  • (ó﹏ò。)
  • Σ(っ °Д °;)っ
  • ( ,,´・ω・)ノ"(´っω・`。)
  • ╮(╯▽╰)╭
  • o(*////▽////*)q
  • >﹏<
  • ( ๑´•ω•) "(ㆆᴗㆆ)
  • 😂
  • 😀
  • 😅
  • 😊
  • 🙂
  • 🙃
  • 😌
  • 😍
  • 😘
  • 😜
  • 😝
  • 😏
  • 😒
  • 🙄
  • 😳
  • 😡
  • 😔
  • 😫
  • 😱
  • 😭
  • 💩
  • 👻
  • 🙌
  • 🖕
  • 👍
  • 👫
  • 👬
  • 👭
  • 🌚
  • 🌝
  • 🙈
  • 💊
  • 😶
  • 🙏
  • 🍦
  • 🍉
  • 😣
  • 颜文字
  • Emoji
  • Bilibili
0 条评论
没有评论
  • 今日访客数 5
  • |
  • 今日浏览量 5
  • |
  • 昨日访客数 38
  • |
  • 昨日浏览量 38
  • |
  • 总访浏览量 2591