你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F103 矩阵键盘4*4 16*16等任意矩阵 按键扫描程序

[复制链接]
STMCU-管管 发布时间:2021-6-7 17:43
基于STM32的按键扫描测试程序(学习记录):
# N( q. N( r6 u4 P
* |5 f6 M* f/ ?7 }2 c9 s# k9 h
, p" U/ ~' Q$ n5 }; L# ^& ~
1、粘贴代码时,粘贴在源文件存放的位置中(如:HARDWARE中的.c和.h文件),用C++编译器打开,而不是kei;最后keil会正常显示中文字符;
# W- G4 x/ K. S2、程序使用嵌套循环实现4x4按键扫描,如果IO口设置过乱时,将循环拆分即可;
3 ?* Q7 l: T' E$ h& ?9 ^key4x4.h源文件
4 ^1 }. i0 k" y9 }! j8 a) |
  1. #ifndef __KEY4x4_H
    7 D9 I2 H( q2 a7 W8 G' T2 l
  2. #define __KEY4x4_H         
    5 x6 G2 {* x" U0 x! X3 U
  3. #include "sys.h"
    ) q0 i1 G4 C) k1 B
  4. ! v, E8 I! @  G7 h, z1 x& n
  5. #define KEY_X(X)        PEin(X)                                // 尽量避免使用PD以上GPIO,便于移植;
    1 E9 a* r7 P0 E9 a" Q" T
  6. #define KEY_Y(Y)        PEout(Y)% c& r2 F! [+ U; I7 h5 s  [

  7. + E$ H! L  O1 M1 C1 D5 N
  8. #define ALL_DOWN_KEY_Y        {        KEY_Y(11) = 0; KEY_Y(12) = 0; KEY_Y(13) = 0; KEY_Y(14) = 0;}
    2 z' L3 c! w) M: Z# D

  9. % [) Q' {9 i  S7 h3 [
  10. void KEY4x4_Init(void);                // IO口初始化/ b, M/ l7 j& c& K
  11. u8 KEY4x4_Scan(void);                  // 矩阵按键反馈函数        // 可配置任意矩阵按键使用!!
    0 j8 |% p( a9 z2 K1 s
  12. u8 KEY16_Scan(void);
    ) W' y5 @$ x( x. _! d- Y2 V
  13. 3 H3 {  g% [) B9 j0 g$ @
  14. /**************. q6 A& m% Y4 x( [$ N1 Y
  15. 按键扫描方案二:2 p; ?3 E: w3 n/ J/ c, K6 c
  16. 按键使用8个输入IO口, 且所有IO口一端接VCC/VSS;
    + M6 H; e6 x7 V0 V) v
  17. 2 u5 F% g+ O4 h( _# n7 X- H
  18. 程序框架:       
    . c; |" x: z! S( a; L+ Z
  19.         扫描检测哪两个IO口输入高/低电平;VCC/VSS; m9 y8 r9 C/ z2 K  j. j
  20.         根据对应坐标,return对应编号;7 V3 S" W7 N0 A, R# V8 B  f2 j
  21. **************/' P" n  o, K; z/ J! {1 [3 \

  22. 4 S! `  m/ x% D/ k4 F3 ~
  23. #endif
    4 P7 o: F/ G/ h
复制代码
key4x4.c源文件! A$ h0 O* D) {
  1. #include "stm32f10x.h"2 y! p; m3 r+ s6 A/ ^, L% _$ \! h8 R
  2. #include "key4x4.h"
    2 d" V$ t1 R3 r. }* ~
  3. #include "sys.h" 9 |  `! R( E6 c$ Q
  4. #include "delay.h"4 ?+ K) a8 F* N( R$ j
  5. #include "usart.h"6 W6 L) t; i8 ~5 V' _/ C" w. ?5 t

  6. ) Q% ]7 r, H0 e- s
  7. 3 m! B# ^" `: U4 V" \" h% L% s2 y
  8. /*************************1 v8 b0 p8 a6 G" F
  9. X:* G6 z. f( k9 M
  10.         PEin        7-10- P3 V) N) f/ Q. k: Z) w
  11. Y:/ l; {& l1 G& R7 r/ }
  12.         PEout        11-14* J' k- U  O: G' v' R
  13. *************************/
    * C% W2 i( x; O& i. z+ j0 ~! N

  14. ; v8 j8 v$ e8 z7 s5 A
  15. % ?# s* u6 F( Q7 B- K* f
  16. // 矩阵按键初始化函数$ F* ?# Z) c3 ?) P) c
  17. void KEY4x4_Init(void)- n3 E- V/ Z% w( _/ Q+ H
  18. {
    1 |- u8 [* h5 e2 P" [* X" q& f8 e
  19.                 GPIO_InitTypeDef GPIO_InitStructure;
    / F% M: l6 f2 a, v& m

  20. + V. h  _" P  l, F+ r* y% F
  21.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
    , ~0 p; p: l! g  k, h) [# [8 l

  22. $ @$ c& i0 o3 n" [2 F  I
  23.                 GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;//KEY0-KEY1
    + V; ^; ]/ q' F: }/ w( ~
  24.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //设置成下拉输入2 \, F# M# K  [9 [+ G! ]
  25.                 GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE% S: f- [* K, t( w) }# f, u

  26.   l0 Q# L& D0 G7 p( O
  27.                 GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14;                                 //LED0-->PB.5 端口配置# E+ k1 \5 Y1 ^4 z8 E0 C1 B
  28.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
    ; E; e& u# s9 v" k9 i  \) z
  29.                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
    % e2 E" N/ G. }: P) L
  30.                 GPIO_Init(GPIOE, &GPIO_InitStructure);                                                         //根据设定参数初始化GPIOE6 F5 K0 n6 e  a- j% V. q' g' ^; g
  31. }9 ~: n3 g0 y6 {* j% e

  32. 4 Q) i* }% W- ^; d
  33. // 使所有输出拉低;初始化;                // 可以使用define宏定义,执行速度更快,不用跳转函数!!
    " P: a% i8 ]1 [
  34. static void KEY_ALL_Pull_Down(void)1 o4 L( x2 k; K0 n# p+ K+ ]
  35. {& [$ G/ m, q* C: l( S% G) T8 `" _
  36.         KEY_Y(11) = 0;5 Y; _& ^- R7 `
  37.         KEY_Y(12) = 0;
    - }7 a+ d2 v- ^4 J
  38.         KEY_Y(13) = 0;8 `$ g4 |/ ]! e
  39.         KEY_Y(14) = 0;
    0 o% Z/ w# @; [- R3 z
  40. }4 |. n$ Z! i( ?0 h; n, K( W

  41. $ X- x. N7 z0 x5 V9 i
  42. // 4x4按键扫描函数
    9 f7 u9 I5 s0 S( \& ^! a1 P
  43. // 使用一个嵌套循环,完成扫描X和Y;
    . |8 W6 }2 Q  _+ L; x8 J8 K
  44. // 原理: 通过Y 依次输出高电平,
    & B, j* H4 H' S2 c# t
  45. //                                扫描X 那个IO口输入高电平;- j# X; N) M/ D3 U+ `
  46. // X轴:输入检查、扫描;
    + R9 [/ n' k# Q, M# a# W5 l
  47. // Y轴:设置输出状态;
    * I" X% O% b4 w! a: c1 S1 l
  48. // 该函数适合任意排列矩阵按键,只需修改循环中对应编号!!
    ! l9 d& l: `' N. x, W7 y2 o# \
  49. // 注意: 1. 改变IO口时,该函数还需要改变循环中IO口编号;(可以定义好IO口编号,便于修改)9 g  }& ?, l  G1 {5 i, g* t
  50. //                                2. 该函数同样有优先级问题! 即同时按下时,只反馈先被扫描到的(0-15标号最小的)
    ( \' b: x/ O) Q4 W& ]' M# j
  51. //                                3. 函数同一坐标轴的IO口编号必须相邻或能有 规律递增可寻;(否则无法用循环判断), c. _) I# E3 F+ B
  52. //                                4. 暂时未添加功能(模式):        按键复用 和 长按;
    , P* K: w/ B: |5 L; c& E' A
  53. // 2020-11-13                返回值调整为:1-16! f% b1 x5 q: ?0 @9 P
  54. // 11/14 不支持连按;解决重复反馈的问题;
    $ N& L: f: ]! Y9 ^
  55. u8 KEY4x4_Scan(void)
    - o; E5 C8 @8 |/ V6 j
  56. {
    3 W5 Q" ~3 ~/ \: K. y
  57.         int i,j;
    ; O8 n) q) o+ ]# n& Z. Q( S! ?( O
  58.         u8 IO_Sign = 0;                                // 很简便的一个IO反馈方式标签!!!  且嵌套循环特有!!  // 能返回0-15,适合任意排列矩阵按键0 Q/ x: H4 l1 u" b
  59.         static key_up = 1;% U" G3 i; y) Z8 I3 j1 q: B( I4 r& U) c: K
  60.        
    % s' h6 P* k) q# Y' k
  61.         //KEY_ALL_Pull_Down();                                                                                // 初始化所有按键输出拉低;
    # s2 G# {8 X) v6 @' \( P# C: ]
  62.         ( ^4 E  ?* G9 E
  63.         for (i = 11; i <= 14; i++)                                                        // Y输出IO口编号;
    ; |3 ^% ~  F* e
  64.                 for (j = 7; j <= 10; j++,IO_Sign++)                // X输出IO口编号;  // 递增IO_Sign,反馈对应值(0-15);
    2 M9 C6 H) U- J' ?; K$ O
  65.                 {5 M1 I$ O% O1 L( Q
  66.                         KEY_Y(i) = 1;                        // 使PEout(i)输出高电平;% `* l! h4 Y; R) N
  67.                         / [# p" P4 g( E8 x( F/ t
  68.                         if (KEY_Y(i))                        // 扫描Y输出高电平, 可以取消此判断; 因为必须输出高电平时,才能正常判断!!0 ?7 A, I% K0 ?* S4 @  n( R
  69.                         {
    - z  `& @3 V$ H8 x. _" ?  [
  70.                                 if (KEY_X(j) && key_up)                // 当输入检查到高电平时;
    - Z* W4 D6 J2 h
  71.                                 {8 C; N& e% V- d. o; q0 s' f$ J
  72.                                         key_up = 0;
    % C& ]5 v2 A8 J. J
  73.                                         printf("按键扫描反馈: %d  \r\n",IO_Sign);' H) b; H' l& I1 Z* W8 v
  74.                                         return IO_Sign;# J- V. \# b2 b8 p6 Q
  75.                                 }$ ^% M1 ]/ r  C) l. W* u5 u) r' v+ H$ o
  76.                                 else if (!KEY_X(7)&&!KEY_X(8)&&!KEY_X(9)&&!KEY_X(10))                        // 当所有输入检测到低电平时,再次使能按键; 防止重复反馈
    , [) ]; ~6 ?" |& D. C9 T
  77.                                 {
    2 q4 G9 K# }# F- [. u. r( ^
  78.                                         key_up = 1;) ]3 y' z0 P) o" v1 Z+ m
  79.                                         KEY_ALL_Pull_Down();                                                                                // 初始化所有按键输出拉低(低电平);必须在此位置;
    7 C# h8 R6 ~8 `) |
  80.                                 }( ?) ~3 x1 ~; I
  81.                         }
    ; p+ C/ f$ J3 d" z6 [
  82.                         else/ C7 m( n/ j0 O, c
  83.                                 printf("PEout:IO口%d输出异常!  \r\n ", i);2 u& u2 f: r$ D
  84.                 }# A" {; P$ l# i* i
  85.                 , }/ ~# V" L* i3 F) O% n
  86.         delay_ms(10);                                        // 按键防抖;
    7 X. J% [# g* E3 l4 z5 J
  87. }  d; v4 R+ K" X. e
  88. ; q! d  a8 C" }( _2 ]3 U

  89. , j( r  O* ]. P1 P9 x
  90. /******************************************标准扫描函数*********************************************/
    & _9 M! Y+ z8 [, y
  91. // 支持连按# ]6 U$ G% }' T+ a
  92. u8 KEY16_Scan(void): |- s6 l8 \; u) f: K
  93. {
    9 e: N% @" n, y& h+ B  |0 n% H, X
  94.         int i,j;
    1 E+ ~& ?3 L5 h6 x7 E5 h, F
  95.         u8 IO_Sign = 0;                                // 很简便的一个IO反馈方式标签!!!  且嵌套循环特有!!  // 能返回0-15,适合任意排列矩阵按键# _) M' V" U3 J
  96.        
    ( f3 d5 l+ `6 d! P
  97.         ALL_DOWN_KEY_Y                                                                                                        // 初始化所有按键输出拉低;8 n7 M# k3 `% p$ H3 A
  98.        
    ; A9 R* A9 Y' @5 V  t3 {9 r
  99.         for (i = 11; i <= 14; i++)                                                        // Y输出IO口编号;
    ) Y9 t; u& k7 a2 f6 `
  100.                 for (j = 7; j <= 10; j++,IO_Sign++)                // X输出IO口编号;  // 递增IO_Sign,反馈对应值(0-15);7 r7 o: B, q# n
  101.                 {9 G2 e! v1 ]( M( Y+ U" U4 C3 U( V
  102.                         KEY_Y(i) = 1;                        // 使PEout(i)输出高电平;
    5 c- g$ j6 W/ Z/ \  C9 _
  103. 0 s* R+ I, H! d( M/ [" n& N
  104.                         if (KEY_X(j))                        // 当输入检查到高电平时;
    . c; ^" _5 s4 A9 g  _) g& ~' x
  105.                                 return IO_Sign;
    1 [( f" E9 A& c% k) t
  106.                 }+ o, I6 [1 g* |  @2 r# h% d
  107.                 & ~( H; l- V+ J% H
  108.         delay_ms(20);                                        // 按键防抖;                // 连按延时;
    ' `9 h& T1 G: }
  109. }
    1 z$ F; k: R3 @  p! N- C

  110. 3 C, Y' B1 P9 F) t4 t3 y0 a
复制代码

$ w9 T" L; o8 ~3 ]) r; ]* ~

+ F- D; R/ Y6 F" O9 p*4x4按键原理图* o  d8 \5 V( x. a! Z( P" [2 F
1.png
0 H- _" r7 K: U% Q/ P4 B3、按键工作原理:1 i5 ~+ k! B) d1 S, u) r
当按键被按下时,相连的电路导通;即S1按下时,位于0行0列的线短路,使标号4和5对应的IO口相连(导通);
+ O& S9 n" I: L) n# d: h最后通过扫描检测输入输出状态即可判断出对应按键被按下;% E( b" k& A. h: U6 E/ G
) U' x0 i& D$ ~
1 I9 t/ A! t' ~( t6 `" _9 I' [
4、程序设计思路:
- Y8 E  N- s% y, E7 ^7 }程序通过依次使标号1、2、3、4(列0-3)输出高电平,判断5/6/7/8(行0-3)状态;完成按键扫描;
" k/ P, Y  T/ C- z" u* R& q
$ D" e* {/ y" k5 g4 \4 f+ X* x4 J7 s  A
, y8 E8 u( A" ^6 J6 {- J6 F- U2 o

2 l2 n# t/ N' l9 ~0 N6 k0 a
收藏 评论0 发布时间:2021-6-7 17:43

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版