找回密码
 注册
关于网站域名变更的通知
查看: 1247|回复: 12
打印 上一主题 下一主题

单片机独立键盘与矩阵键盘的问题

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-3-21 09:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
单片机独立键盘与矩阵键盘的问题9 N& ]& O$ Y% x* k, e
/ \4 z4 L3 _9 T- H

' t& y4 F& Z6 u- o4 `( B0 R. R" O#include <reg52.h>/ H9 K6 C/ {' X6 q& C9 h9 ^6 n

0 T* L& \5 W0 u+ S- w& K#define GPIO_KEY P1 //矩阵键盘的接口
; F3 g7 f, o- a5 E#define GPIO_DIG P0
; J3 |! [2 q7 T9 @0 [7 Itypedef unsigned char u8;& k7 z& z% C! s( a+ y: I
u8 KEY;
5 k3 q1 Y# q) w: ]sbit SM = P3^1;   //输入密码按键
* s- ?1 B6 R/ m- g8 m* T, Jsbit GM = P3^0;   //修改密码按键% t6 O& l; q1 D/ M
sbit OK = P3^2;   //确认键
4 L5 G: r9 z) Asbit LSA = P2^2;
$ b) O% R; \3 D1 t/ @( y, Psbit LSB = P2^3;
  }9 q9 Q9 p1 r% usbit LSC = P2^4;# ]6 M% U  y) |1 w4 N1 p: ?, m

. J9 B7 w4 K1 o4 G2 Bu8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
7 Z' s+ r0 ^& J  O5 N                                         0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值" x* @# Q4 D' I) N5 {
. ]' o6 @" u7 N7 Q- F0 k7 N6 v- ~
void delay_ms(unsigned int x)
( a# n3 b3 w, `) W{
, h' s2 o/ u3 F4 O: \( \   unsigned int i,j;
9 ~( W' J9 f% t* {$ w* o& j        for(i = 0;i < x; i++)
# U4 V4 x/ W& y) B- A) G; p                for(j = 0; j < 110; j++);- s; X& d5 C2 a
}
* _6 G/ R. b! j; l  o% R/ }' k
% R- }' E' }$ P6 y, au8 Keyscan()
1 u+ n. p6 M. \5 z: k, \{" U0 y8 z0 u+ v* K4 Z9 t! R7 d
    char a = 0;* a+ P/ v3 r  }8 }# b
    u8 KEY;
9 E6 ]1 c  z+ `. C    GPIO_KEY = 0x0f;
+ E( K6 s! Z+ r+ `    if(GPIO_KEY != 0x0f) //判断按键是否有按下5 V: D2 o  w& i% r) o
    {3 B) k  J% @. \
        delay_ms(10);   //延时去抖; y* h0 N5 J7 m8 ^9 t, t# b! ^
        if(GPIO_KEY != 0x0f)  //再次判断是否有按下
; r# I4 [% C" K' Q2 C        {/ r7 ]" i/ v. \1 d
            //扫描列' H' N9 m* s% f5 j; z* ^
            GPIO_KEY = 0x0f;5 u1 k) ], c* N7 Z( m/ I/ q
            switch(GPIO_KEY)
" v  L5 }9 B( K            {
' \* X6 [& P' h- J                case(0x07):KEY = 0;break;- h0 M( X6 U  C1 o/ e  m' r
                case(0x0b):KEY = 1;break;
( k0 v/ _# |: k% ^6 }) m3 N                case(0x0d):KEY = 2;break;
/ H' p7 t% U$ j                case(0x0e):KEY = 3;break;
, s& L5 s2 G, V1 B3 b4 j6 a            } / [7 a) h. \- u( ~( H
            //扫描行) G, w! s. o$ h4 r4 y
            GPIO_KEY = 0xf0;  \3 x2 K, O4 E9 p+ A
            switch(GPIO_KEY)
' H/ K5 R  N8 S            {
- `- K  L: F2 i/ M& G& Q                case(0x70):KEY = KEY;break;
& u5 i% O, ^4 ^" v8 _                case(0xb0):KEY = KEY+4;break;
9 F! ^3 A! Z8 }, v& s4 [. \" L) S                case(0xd0):KEY = KEY+8;break;
, w. ~) w7 d' @5 s9 P                case(0xe0):KEY = KEY+12;break;* o2 I2 w$ _3 G' v
            }
" v5 `, c  E6 X2 ^9 P& u. @5 P            while((a<50) && (GPIO_KEY != 0xf0)) //按键松开检查( G' I: V& ?) l7 M+ H
            {
6 m7 K! W# ~% F1 h7 M; A8 n                delay_ms(10);
1 ]3 c* E- e( x                a++;, p( V# N( e# d- i8 q! C; a
            }
4 X% p6 {. `, B  K7 O! S0 m6 I6 a            return KEY;   . l3 w9 y7 e5 ~8 F! _, ?6 Q9 S- N1 X
        }1 O' A. V$ e) {3 {; N
    }5 o  h2 s- P2 W# \, d' ?+ u& m
}6 V7 r  S; U  B* F! B( s
2 O0 n2 r5 j, [/ o
void Keyscan_duli()
0 P& }0 \4 i% C5 j{
6 N+ @- h, h/ }    if(GM == 0)
6 l+ s0 g* I& f# c; E    {
- \  \0 k' w" c. X& d- x9 W        delay_ms(10);
& R) A# t; k% c' M+ p$ H9 D        if(GM == 0); W' k) C# K2 }; E
        {
& M) ^, B1 M5 H            KEY = 0x0b;
! A2 Q1 {' Q* [9 K( `9 q+ v        }
6 A$ c% j5 P5 o& y' |6 N        while(!GM);+ K5 r8 h8 [( _
    }2 r% F9 D; V: e8 r" ]8 q3 \! R
    else if(SM == 0)
4 u0 f6 |, E1 ~( u# M; X, H    {
* ^. K' l- L1 b( c% c8 J        delay_ms(10);
4 w& N3 F9 s) o$ |        if(SM == 0)$ p, r( U/ z% `5 x1 F: n
        {
# L$ \/ N. I% u            KEY = 0x0a;' _; d4 p) d( `4 ?, ^2 r) x+ q5 @
        }9 L  E; E* [9 v7 D9 }1 g  }9 x# M
        while(!SM);; d" }6 f  k2 x' e
    }7 p( `; g3 m; n& q' p
    else if(OK == 0)% p: U( ^! x) T+ B2 p* l3 p$ a! d
    {
' d1 P. b5 G! w8 h/ q        delay_ms(10);% |; N7 u& I4 R8 e( `
        if(OK == 0)8 g! X. n# z& D& j
        {5 ~1 ~  r/ Z+ K- l( x
            KEY = 0x0c;
  ?8 A1 a: s5 P  n        }) H1 f5 g* r, ^% w5 R
        while(!OK);3 e6 F( P7 P* d; Y: {' [+ J
    }  @& t, j# I' X' F7 C9 O" P
}2 |5 D& t( Z) L+ ~
* B9 {. Z' F) P1 F- }% h! }

  ~7 F1 K# o0 w* t
: B$ I- ?  }8 a2 Dvoid main()* w0 B  U) \; z0 O1 x
{
. d- @2 u  q* }% v% W  W, W    LSA = 0;
6 G  O0 O+ \4 x7 a5 w$ m1 P    LSB = 0;' A3 b2 l, ?" c" j8 V: q
    LSC = 0;4 u# W) \3 I1 H! K$ T
    while(1)
& |. b# f8 h  W0 W( y( E6 E    {   : q, K9 t) |' Z2 ^9 F6 o
        Keyscan_duli();
+ ^7 Z% i* {# `& A        KEY = Keyscan();        ( d- ]( s( Q) z$ N
        GPIO_DIG = smgduan[KEY]; $ i4 k; W% J/ t/ x+ a5 A+ Y
    }$ w# M" C$ z& F! \
}
' C) j7 I: ^4 J/ o! m4 ^
) Y% S# L7 N7 q: N% B% k$ J! t+ h' z. a7 u5 e
想问下各位大佬,为什么不管按GM、SM、OK键数码管都显示A,而如果只有独立键盘扫描函数,即把主函数中的KEY=Keyscan()注释掉,按GM、SM、OK键就能分别显示A、B、C。
: p0 U/ i8 ^1 G0 y; W

该用户从未签到

2#
发表于 2019-3-21 10:01 | 只看该作者
Keyscan_duli();. s1 i4 u7 ]( A
        KEY = Keyscan();
7 A* l& H" b$ k* |这两个函数都是修改同一个变量KEY,Keyscan_duli();是在函数内部修改,Keyscan();是执行完后返回给KEY,这样的话,执行完Keyscan_duli();后,不管KEY是什么值,再执行完Keyscan(); 就被修改了。9 |! W' [$ N% A' ^7 A
应该用两个不同的变量,或者用不同的按键码值

点评

那显示时不就有两个变量名  详情 回复 发表于 2019-3-21 10:04

该用户从未签到

3#
 楼主| 发表于 2019-3-21 10:04 | 只看该作者
relchhiclty 发表于 2019-3-21 10:01
+ X0 Y, u  P9 WKeyscan_duli();( K. _1 S' r  j$ C3 P
        KEY = Keyscan();
9 b' K( F% A0 R这两个函数都是修改同一个变量KEY,Keyscan_duli();是在函数 ...
* ~0 N+ S# _8 b8 p5 S+ \- @2 R9 D
那显示时不就有两个变量名4 [: k3 \, F9 E) ^3 N- I" t- n

点评

不想有两个变量名,两个函数调用次序对调一下,先键盘矩阵,然后再是独立键盘  详情 回复 发表于 2019-3-21 10:06

该用户从未签到

4#
发表于 2019-3-21 10:06 | 只看该作者
小黄豆 发表于 2019-3-21 10:04& A! P' b5 x: {5 _* X
那显示时不就有两个变量名

9 `8 K( e: p& D1 L: g% ~不想有两个变量名,两个函数调用次序对调一下,先键盘矩阵,然后再是独立键盘  ]& p% h6 G8 X6 X

点评

还是不行  详情 回复 发表于 2019-3-21 10:19

该用户从未签到

5#
 楼主| 发表于 2019-3-21 10:19 | 只看该作者
relchhiclty 发表于 2019-3-21 10:06, K" G' h8 }# g
不想有两个变量名,两个函数调用次序对调一下,先键盘矩阵,然后再是独立键盘
2 W, b( ~$ R# M  R" g& D: M# Z5 {
还是不行% y. l3 e7 L/ u: U

该用户从未签到

6#
发表于 2019-3-21 10:20 | 只看该作者
矩阵按键扫描函数错了。。。* N9 @  p* B/ ^! R
//扫描列' v8 D4 w( R$ N  s' [
            GPIO_KEY = 0x0f;6 E3 l' h/ t5 i" a3 X% e
            switch(GPIO_KEY)
: u& k: {8 O$ y9 K# p. v( P            {! P4 D9 J: @0 R3 K8 t0 Z
                case(0x07):KEY = 0;break;
( W1 S* [6 m0 O$ w! k* C                case(0x0b):KEY = 1;break;5 B, \9 U) S7 }% q9 G" q" o9 t" Z
                case(0x0d):KEY = 2;break;
$ c$ P6 X* o! e  j0 g! W3 A% ?                case(0x0e):KEY = 3;break;
! c4 `9 M$ l6 A" _% L7 Q            } ( e/ u6 V* ^4 @6 [0 I. g& p. Y
            //扫描行5 v( i! ~6 {3 F9 k" s; l
            GPIO_KEY = 0xf0;
3 T- A/ f2 Y9 T0 n# ?9 n7 C! q; r            switch(GPIO_KEY)" W% e  a% i& ?8 H: z* m; o
            {' N# L$ B) ^7 \
                case(0x70):KEY = KEY;break;
& {3 S- _% U/ R, t                case(0xb0):KEY = KEY+4;break;
1 R: q+ r$ N1 r  u! I0 Z$ U                case(0xd0):KEY = KEY+8;break;. p; p& O# q4 S- }7 R; m. H3 W# f- ~8 z
                case(0xe0):KEY = KEY+12;break;: s3 j  r9 h/ _" M! R. d& R
            }8 d) G4 z+ h% b/ ]6 B; b
应该是&=吧??你直接赋值,case没有满足的!

点评

单独使用没问题啊  详情 回复 发表于 2019-3-21 10:21

该用户从未签到

7#
 楼主| 发表于 2019-3-21 10:21 | 只看该作者
yxlk 发表于 2019-3-21 10:20
( w$ a. \$ |/ M- V/ N6 v/ V; R矩阵按键扫描函数错了。。。
7 o! k1 O7 H5 e* B) Q//扫描列
# ~. i+ x  g% G$ `$ ], [8 C            GPIO_KEY = 0x0f;

& ~# ^0 A  i- e单独使用没问题啊3 d% v2 r) @/ s5 g" r

该用户从未签到

8#
发表于 2019-3-21 10:26 | 只看该作者
全局变量KEY在Keyscan_duli();程序中获取的值被下一条语句KEY = Keyscan();覆盖掉了。改成这样看看:#include <reg52.h>( }1 V! c, R8 `. v1 X9 L% H! L5 Z

+ q4 J# M/ j5 n$ ~7 w#define GPIO_KEY P1 //矩阵键盘的接口
0 y2 D( R& X2 C+ S) h# n#define GPIO_DIG P0, e( A7 B4 F$ P, z- |
typedef unsigned char u8;5 |; d0 C+ E) |$ O( A) F0 c& g. v
u8 KEY;
% `1 J1 W5 I5 L4 o' u/ Q* Asbit SM = P3^1;   //输入密码按键  R. h+ `3 v& f2 j( s/ r8 Q
sbit GM = P3^0;   //修改密码按键$ y0 p) H( d! `, i- |. s. X
sbit OK = P3^2;   //确认键1 a" a3 A' |5 D
sbit LSA = P2^2;
9 K* c, E" ]! y. Isbit LSB = P2^3;2 f5 J) b" F% K  T" ^3 `) ~- X* ?8 X
sbit LSC = P2^4;
" h7 {. R+ _! V1 i6 I5 c1 h2 B5 i" N/ S/ e* S' Y2 i: f- X
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,: m, o+ C- ?7 j5 I7 e* I( R5 p$ I
                                         0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值1 X0 ^+ q7 g; h- c4 e- B

8 y- F* M7 b1 A& D! a: Q( ?void delay_ms(unsigned int x)
4 I2 N  `+ I" F! D/ X) |* y& ^{3 z" U5 a; l9 D( R
   unsigned int i,j;' f8 S4 H  [/ U- B
        for(i = 0;i < x; i++)+ K" \8 C: T6 P5 ^3 o, p6 V
                for(j = 0; j < 110; j++);2 Q3 I2 v6 L+ k: x" I
}
9 A9 G6 U5 t( Q7 e; w8 T: ~, n* P5 b; G7 I
void  Keyscan()
1 y( _, e: ]3 Q9 ]: F$ m6 I{
2 \5 C& A3 Y: R  Y/ I% ~    char a = 0;
7 \" {9 |( H! `+ r//   u8 KEY;
7 i1 K' x9 I% {0 O! O    GPIO_KEY = 0x0f;. u4 B6 s  W( ]% G
    if(GPIO_KEY != 0x0f) //判断按键是否有按下7 J4 V/ J6 t- ^1 l  ^8 Q
    {( }" {1 l; c% x9 v% X; ~2 m
        delay_ms(10);   //延时去抖. t+ J% L3 s: r" @
        if(GPIO_KEY != 0x0f)  //再次判断是否有按下9 o3 j  i% G" G- `
        {
5 U) Z' D3 }& c' u+ m2 z' b; M$ p) n            //扫描列  w- }9 e; e3 P; a% z
            GPIO_KEY = 0x0f;. E. e; P3 X, d1 L# ?2 D5 d% d# e
            switch(GPIO_KEY)8 @0 s/ F+ _1 a% T1 p1 x0 x
            {
6 {( m. [1 `* |9 v9 Q7 Y- ?( w                case(0x07):KEY = 0;break;+ Q4 [: {2 U% K# p( }
                case(0x0b):KEY = 1;break;
3 d, {5 }* }5 v. d8 M6 z7 }' O                case(0x0d):KEY = 2;break;+ T% H) y& R, A
                case(0x0e):KEY = 3;break;
" X* B. u6 [6 k$ {( {- }6 D' P            }
  D- q1 Y) P2 N1 Z4 T            //扫描行
* M0 C) @8 r  X% n% b  u            GPIO_KEY = 0xf0;6 M& k* Z' Q' V3 l! b! e5 m/ a
            switch(GPIO_KEY)
+ r1 N# A" v8 C3 f            {
7 U: K  U; ~! ~) x; m+ S$ p                case(0x70):KEY = KEY;break;; d, F: |4 P% T4 T8 U, j
                case(0xb0):KEY = KEY+4;break;
7 z5 {% C1 i# x: |" Z                case(0xd0):KEY = KEY+8;break;/ m6 l4 Y! V- x
                case(0xe0):KEY = KEY+12;break;
4 j# j' o6 F8 Y/ B2 N$ I; T& Q            }
1 p* x( _- u! g1 a; |2 S8 G            while((a<50) && (GPIO_KEY != 0xf0)) //按键松开检查
& N& k5 t6 d2 v4 k/ s7 c" d1 c            {$ Y3 @4 S! P3 k% P+ h$ Q- I) Q
                delay_ms(10);, U/ z: m: [; x9 s) ], F
                a++;
1 M9 t# G1 T/ X! g% u# R            }# z5 s% T% L+ x# f' x/ e
//           return KEY;   * t' T' f6 I% e7 e' y
        }/ [$ }. |3 ^1 e. ~8 N+ x3 J, {/ W
    }: n- h+ y1 _- |7 C& g8 }" \
}
$ u( R4 L, n% a, o+ N, I: Q" z; {4 y" X4 P# t" o5 f+ R
void Keyscan_duli()
8 F- ]: G2 M1 h0 i{
* O% A1 Q0 l* ?8 p0 K    if(GM == 0)* u4 \3 X% r$ I  T; k4 N, B
    {
3 H5 S2 V$ J& X+ S7 H/ w) P" d$ a; Y% ?        delay_ms(10);0 l4 e1 S5 x- e! E
        if(GM == 0)
3 R. D7 v+ Y$ \  Q, M* F2 h  e        {
1 V/ J; |: ]* z/ u            KEY = 0x0b;
7 l) a' \3 y9 V: a        }% F" G# }, G4 R0 w
        while(!GM);
0 f  t1 d7 z& X9 V9 l- k. v: a    }
0 v0 g0 n, M, R5 ^    else if(SM == 0)
6 W. I4 C2 k* r8 X8 |( j- m    {
3 o+ ~% k- _+ u" c, j  m+ k9 g: Z        delay_ms(10);
: A4 J5 e* S/ A' A        if(SM == 0)6 `0 a, ]$ ^, v) R
        {
9 u% ^3 v/ ?/ L/ f' C            KEY = 0x0a;$ `6 T* Z; D! g( V* C. F$ b& A
        }9 ?* `1 B7 J0 r4 ^, @' w
        while(!SM);
, P" b4 C4 H  r5 J* R1 J' {    }
! k0 `+ W! g8 p% _3 r$ R. j7 g: y    else if(OK == 0)7 q, ^3 f0 V3 B- h
    {# _, m$ t1 V+ b% A: N! _7 G
        delay_ms(10);
  V4 k% z7 \! A6 V/ M3 D$ X        if(OK == 0)
; a. v$ a: ~0 `        {
9 a  ]# y! j) {* F$ R1 Q, y2 D& Z; I' w            KEY = 0x0c;
$ c9 U6 k  A' x" w! W: g0 p        }
. B9 C3 p' c) `& n        while(!OK);
: O6 O/ E1 y) V; ~  v    }
$ {1 h1 j( ?2 p0 a# Z2 ~}' |; m0 d, l  _
; L0 y7 o0 g8 F
& \- ~5 G- V( X* N* t; g$ r& @" x1 M# `

2 J5 e$ E5 L1 [6 m* a6 G8 Vvoid main()  j4 g" Y! c  A
{2 [9 i; w3 F6 S- q, z
    LSA = 0;, x4 ]' Z# e  o2 t( X$ M9 L1 e' }' w
    LSB = 0;, X5 c$ k8 ~/ |6 I3 ?5 b
    LSC = 0;
' z( q% P0 e1 S5 ?    while(1)  M7 K0 w5 B# ~& B. w4 o
    {   
1 |7 G3 ^/ y  f. _5 L- n        Keyscan_duli();6 X; E: B" q/ r+ t1 d0 R$ k
        Keyscan();        9 F& d  b) Q* y+ @! D, }
        GPIO_DIG = smgduan[KEY];
2 m0 P: j: x" }* j1 g    }
5 `" z! v9 ]4 c* ~2 S  x}

点评

这样就可以了,这是为啥啊  详情 回复 发表于 2019-3-21 10:33

该用户从未签到

9#
 楼主| 发表于 2019-3-21 10:33 | 只看该作者
kinidrily 发表于 2019-3-21 10:26# q( O, M2 Y- H$ ?' b) G# s! q
全局变量KEY在Keyscan_duli();程序中获取的值被下一条语句KEY = Keyscan();覆盖掉了。改成这样看看:#inclu ...

' i# g# Q  y8 ^$ t6 g这样就可以了,这是为啥啊
6 c/ a" J+ U; D, ?

点评

这是因为全局变量KEY在独立键盘扫描程序Keyscan_duli();中获得的值会被矩阵键盘扫描程序KEY = Keyscan();改写。我把矩阵键盘扫描程序中的局部变量KEY注释掉,也取消返回值,这样两个键盘扫描程序共用全局变量KEY,在  详情 回复 发表于 2019-3-21 11:21

该用户从未签到

10#
发表于 2019-3-21 11:21 | 只看该作者
小黄豆 发表于 2019-3-21 10:33
( {  Y% `/ S6 ^; G) Y9 L这样就可以了,这是为啥啊

) F. x% @/ j* c# l" E# u这是因为全局变量KEY在独立键盘扫描程序Keyscan_duli();中获得的值会被矩阵键盘扫描程序KEY = Keyscan();改写。我把矩阵键盘扫描程序中的局部变量KEY注释掉,也取消返回值,这样两个键盘扫描程序共用全局变量KEY,在主程序中分别调用两个键盘扫描程序,谁有操作就显示谁的键值。
' \. C. D0 l/ B  T; Y/ K, p- e
0 q! B1 F% h: r1 }, c$ J1 t7 J, x

点评

哦 明白了 谢谢  详情 回复 发表于 2019-3-21 11:26

该用户从未签到

11#
 楼主| 发表于 2019-3-21 11:26 | 只看该作者
kinidrily 发表于 2019-3-21 11:210 m# v# q3 w  ~3 H9 e: O5 v' y1 y/ I: K# g
这是因为全局变量KEY在独立键盘扫描程序Keyscan_duli();中获得的值会被矩阵键盘扫描程序KEY = Keyscan(); ...

4 @% s2 l- b2 ]哦 明白了 谢谢
; ~6 ~# q% _2 ]; y/ j! p0 x2 x

该用户从未签到

12#
 楼主| 发表于 2019-3-21 11:27 | 只看该作者
谢谢大家的指点
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-8-17 23:36 , Processed in 0.156250 second(s), 33 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表