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

STM324X4矩形键盘

[复制链接]
STMCU小助手 发布时间:2022-11-28 15:18
介绍什么是矩阵键盘

矩阵键盘是单片机外部设备中所使用的排布类似于矩阵的键盘组,由于电路设计时需要更多的外部输入,单独的控制一个按键需要浪费很多的IO资源,所以就有了矩阵键盘,常用的矩阵键盘有4X4和8X8,其中用的最多的是4X4。

640 (1).jpg

  b0 ?, ]% R& i, ?& C矩阵键盘的原理

矩阵键盘又称为行列式键盘,它是用4条I/O线作为行线,4条I/O线作为列线组成的键盘。
. d; z) P4 h5 F0 U在行线和列线的每一个交叉点上,设置一个按键。这样键盘中按键的个数是4×4个。1 z8 p: r. x4 `( e4 A# r
这种行列式键盘结构能够有效地提高单片机系统中I/O口的利用率。由于单片机IO端口具有线与的功能,因此当任意一个按键按下时,行和列都有一根线被线与,通过运算就可以得出按键的坐标从而判断按键键值。
/ b. ~( C8 g3 ]原理如同矩阵数列的行列式。

8 s4 W2 o2 @# ~$ h$ D; ?7 G

640.jpg


9 |7 b" n% ^6 [) e4 w, `

驱动电路图

按4*4矩阵搭建的按键矩阵还是比较简单的,也有的人为了保证电路的稳定性,加上二极管保护和上拉电阻,但是一般要求不太高的电路就不需要加了,向下面设置的电路那样就可以了。

' O) g# V6 D" |, B: `

640.png


1 X" w- O4 b( ?4 s4 s" u3 Z

软件程序实现

在这里宏定义一些GPIO的信息。

KEY.h

  1. #ifndef _KEY_H: V+ g1 l* x! j. p: `2 W
  2. #define _KEY_H' ~/ ?5 i; u& F
  3. #include "stm32f10x.h"* q$ I$ y$ H% {5 h
  4. //引脚% _9 h" |6 p  P) Q' S6 e: C
  5. #define S0 GPIO_Pin_0
    2 @; k. b' ?; k8 c% K; J& c/ X
  6. #define S1 GPIO_Pin_1( ^  g( i7 G4 \5 P
  7. #define S2 GPIO_Pin_2
    - B  R1 A4 e( z" |
  8. #define S3 GPIO_Pin_3
    : u: }) \, x- y/ P
  9. #define S4 GPIO_Pin_4
    # E% n" U; \$ Y9 H' G
  10. #define S5 GPIO_Pin_5& m9 E+ z5 ~3 x7 Z& p: ]
  11. #define S6 GPIO_Pin_6" D' o# s- P1 D0 V
  12. #define S7 GPIO_Pin_7" r* K4 o2 \. ~# g0 T; [( e6 K
  13. //GPIO寄存器( o% E1 `9 C3 Z- F, m; V
  14. #define KEY_PORT GPIOB
    $ ]2 N" e5 S! a0 o1 @
  15. //时钟% A' e. a% }/ b' q: d) M8 ]
  16. #define RCC_APB2_KEY  RCC_APB2Periph_GPIOB
    $ D, e7 A: B& Y! H9 a; j% l
  17. //函数定义
      u7 I" t4 _# P) T) O6 I0 M
  18. void InitKey(void);3 J- p7 ^, X: m( E$ p0 a$ K: g
  19. int NumKey(void);
    2 z+ B! f, ^# V0 k0 ^
  20. //延时+ U) V" E4 z: b5 S  L
  21. void Delay( uint32_t count )2 a. b6 t9 g5 G+ |; f0 ]' Y
  22. {
    + o! Z) e# u6 a+ F! ]
  23. for(; count!=0; count--);# ?( f+ Z  C7 ?
  24. }
      N2 J& d$ C8 t" }- C. w" P% C
  25. #endif /* _KEY_H  */
复制代码
( g7 }! O  p* E0 p% D" i
在这里存放两个函数,一个是初始化矩形键盘GPIO口的函数,在函数里把前四个定义为推挽输出,后四个GPIO口定义为下拉输入。
" x" i0 t1 d% R0 r& o& s另一个函数是键盘扫描函数,通过函数返回值确定是举行键盘的哪一个按键被按下。

0 p/ f4 B1 P) k) v3 g' C
KEY.c
  1. #include "KEY.h"! \" K2 U8 O" U. h4 L
  2. void InitKey(void)//初始化KEY的GPIO2 \' y1 ~: j( g
  3. {# g; s- R1 D& [# G$ R6 c2 b
  4. //打开GPIO时钟
    2 R: n  M, e5 _5 v- a0 }1 B* R
  5. RCC_APB2PeriphClockCmd(RCC_APB2_KEY,ENABLE);
    # e- O( }% s3 X2 t% Y
  6. //把S0,S1,S2,S3配置为推挽输出2 v! d! r9 S2 A$ V- v
  7. GPIO_InitTypeDef   GPIOInit;* M1 g, J" ~! ]$ r. ~; W
  8. GPIOInit.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
    ) M5 i/ |" e6 M( N1 m* c
  9. GPIOInit.GPIO_Speed=GPIO_Speed_50MHz;
    ( L8 Y5 N" }9 V% k
  10. GPIOInit.GPIO_Pin=S0|S1|S2|S3;
    0 Q: O7 j* Q0 K4 }9 M- l2 d0 o) H/ F
  11. GPIO_Init(KEY_PORT,&GPIOInit);
    - S' L; d9 v8 K6 y& c

  12.   y# G6 m9 ?0 R" s: c& e
  13. //把S4,S5,S6,S7配置为下拉输入7 i+ _% L9 y! G" v  r# q( ^4 v: R
  14. GPIOInit.GPIO_Mode=GPIO_Mode_IPU;9 X) R) P$ w; o! I: H
  15. GPIOInit.GPIO_Pin=S4|S5|S6|S7;9 E. H% b+ a) E. A' F: n$ W
  16. GPIO_Init(KEY_PORT,&GPIOInit); 3 s% f" \0 v: S% V

  17. $ o, h; q8 p$ u( F6 I3 Q9 o
  18.   //0--3输出高,4--7输出低
    8 K0 E) J6 W7 Y  P: N. k1 ?
  19.   GPIO_SetBits(GPIOC,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);* D1 @$ `7 y% Z1 m0 K, A
  20.   GPIO_ResetBits(GPIOC,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
    % c: }8 R. ]$ u
  21.   ) X6 ~7 E+ A; X$ f# D( Q
  22. }
    # c( b5 x$ p, @& ]$ ~# B: k$ B- k
  23. int NumKey(void)  //扫描键值
    1 E. g: |5 h) @* W
  24. {
    7 a8 h7 K/ B$ I( ^9 ]) T8 v7 u
  25. int KeyVal=0;     //键值,后面自己设定的,用来设置按键的序号
    . u6 A* Z' p+ r& n$ r4 f
  26. u16 KeyWrite=0;   //写给GPIO的值 & g, L2 M2 F  D: T. L9 G
  27. GPIO_Write(KEY_PORT,(KEY_PORT->ODR & 0xfff0 | 0xf));//0--3全部输出高
    ) |- ^9 `  _+ d5 t! Y  Z
  28. if((KEY_PORT->IDR&0x00f0)==0x0000)   //如果4--7全为0,表示没有按键按下,返回值设置为-1
    3 c' c3 J. B9 P  W  T0 Z5 X5 C# h$ g0 C
  29.   return -1;. {/ H2 o" t& Y
  30.   4 S6 U0 V8 G5 G4 O% ?& [
  31. else
    8 _6 Q0 F' i' f  b1 _
  32. {
    ! r+ l2 i5 L" P" R/ H
  33.   Delay(0xF);//消抖
    0 x% q; E5 ~" p7 E/ S4 p
  34.    if((KEY_PORT->IDR&0x00f0)==0x0000)   //如果4-7全为0,表示刚才是抖动造成的
    8 g* w, z0 W$ S' S3 r( o& C0 ^8 e
  35.   return -1; : f# v+ {$ h1 s
  36. }( Q7 i. ^6 }* i$ N# J. N7 f
  37. GPIO_Write(KEY_PORT,(KEY_PORT->ODR & 0xfff0|0x1));//让0-3输出0001
      B/ E( a2 d+ s2 G& ]; i
  38. ; l* P7 ~/ i4 b1 ~6 _" X$ I
  39. switch(KEY_PORT->IDR&0x00f0)//对4--7进行判断
    1 i& ^5 K( t7 ~8 u
  40. {4 H/ ]* O- s% `: ]4 D1 C
  41.   case 0x0010: KeyVal=16;break;
    # f! o! d! a6 d% N' e
  42.   case 0x0020: KeyVal=12;break;
    6 M; H) X3 y- _
  43.   case 0x0040: KeyVal=8; break;
    & G4 j# C& [; f1 ]
  44.   case 0x0080: KeyVal=4; break; 3 E3 J' v+ S% |6 `1 [7 h# F+ Y; o  B
  45. }
    % A/ \; q0 B7 P) |3 |

  46. - D% C. k, \! [) h+ ~8 q# K
  47. GPIO_Write(KEY_PORT,(KEY_PORT->ODR & 0xfff0|0x2));//让0-3输出0010
    " D9 Q+ d% G  W( m+ i
  48. switch(KEY_PORT->IDR&0x00f0)//对4--7进行判断
    " m$ x  F; e# \. B
  49. {
    7 A3 h$ m) h# `  M
  50.   case 0x0010: KeyVal=15;break;
    , j, a+ E; G2 d, k) l
  51.   case 0x0020: KeyVal=11;break;
    . W4 _- ?4 y8 b: k
  52.   case 0x0040: KeyVal=7; break;# K! d' r+ V; H5 a. s
  53.   case 0x0080: KeyVal=3; break;
    . }' b$ P* d, N0 m' O" r- h+ h
  54. }
    9 Z/ t  O- D/ G& H! H8 O9 G5 V
  55. GPIO_Write(KEY_PORT,(KEY_PORT->ODR & 0xfff0|0x4));//让0-3输出0100
    3 K7 _2 c. ?; k& X2 A
  56. switch(KEY_PORT->IDR&0x00f0)//对4--7进行判断$ E- i  @- v# [& O! C. [
  57. {
    # _1 k: a! z2 w
  58.   case 0x0010: KeyVal=14;break;
    9 a; w% F4 r: [" q2 e
  59.   case 0x0020: KeyVal=10;break;6 v& D! f3 w0 s. L% @; h: h  d
  60.   case 0x0040: KeyVal=6; break;
    , x7 i6 u! E$ h- V( \$ m
  61.   case 0x0080: KeyVal=2; break; 1 @$ w/ ?: L4 U) v4 v
  62. }$ C# D% b" Z) E
  63. GPIO_Write(KEY_PORT,(KEY_PORT->ODR & 0xfff0|0x8));//让0-3输出1000! l; m1 i2 U; E- ]# I
  64. switch(KEY_PORT->IDR&0x00f0)//对4--7进行判断
    # e1 Q$ _& S* p$ @8 e" T
  65. {
    0 L0 m! |7 U! v
  66.   case 0x0010: KeyVal=13;break;# q- ~6 K9 q) t, n
  67.   case 0x0020: KeyVal=9;break;
    ! ?7 W7 i- `/ b5 T9 ^8 _+ F8 n
  68.   case 0x0040: KeyVal=5; break;$ `4 U* |) E* H+ o8 b- b3 b& N
  69.   case 0x0080: KeyVal=1; break;
    3 z- L' N  y- x, E2 \  v
  70. }
    0 Q* \, }5 G# F; R
  71. return KeyVal;
    ' ^, Z$ p$ X+ D% U2 p# N/ ]
  72. }
复制代码
1 b$ ~6 b2 d( e; }0 }% ]
& p0 J7 R% N/ L6 h' @
转载自: 跋扈洋
) D$ C4 [  R2 k! i+ C
赞 收藏 评论0 发布时间:2022-11-28 15:18

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版