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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
单片机独立键盘与矩阵键盘的问题
& Q" V$ U$ K1 Z# w, V0 e  ^, R. X- ^

5 P9 a+ J: D# g" W7 U* J#include <reg52.h>
& N. D1 _+ L2 T& h) ~
6 ?8 S" U& a$ {#define GPIO_KEY P1 //矩阵键盘的接口' s6 ~4 \7 l$ F9 T/ U
#define GPIO_DIG P0
6 R. _% O1 w' h5 {4 f: U' [typedef unsigned char u8;8 Z/ c& Z3 r% O: i. R5 a& e9 K- X
u8 KEY;3 ~$ K. I1 D- `3 P/ w  k  v  x9 @
sbit SM = P3^1;   //输入密码按键0 U# b' w- n5 v3 s9 M) ~4 w
sbit GM = P3^0;   //修改密码按键
. k0 p9 b7 x) csbit OK = P3^2;   //确认键
( r: r& i% U3 a8 v% z3 csbit LSA = P2^2;0 u0 h& A) r$ W+ G  ^5 J
sbit LSB = P2^3;5 o2 v3 o- R1 c. ?
sbit LSC = P2^4;
1 l( g5 g; u6 `  f0 Y4 _/ Z- E9 M+ N* @6 m5 D( I
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
1 M4 j4 U* p  @: b& @" @                                         0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
. z, A) b; p8 G" j# w) G
& K3 ~# O& c0 C5 m  a/ {void delay_ms(unsigned int x)
( ], E4 c) ~6 o2 P: w, D{
  D* n: X! Q! w6 h; S   unsigned int i,j;# ~5 X1 g4 A) b2 _0 O  G+ S
        for(i = 0;i < x; i++)# v5 t4 M5 l; s$ r
                for(j = 0; j < 110; j++);! B- x6 ~2 E+ j, D, A1 L9 W* y
}( Y' l$ ~+ f' Y6 \# v
9 ^9 S1 G1 F$ v) M9 [
u8 Keyscan()
; m! G5 Z/ m' h{' ]+ R  L3 N2 ]* v7 T9 ]4 _: ^
    char a = 0;% X, u. K6 F+ d( ^
    u8 KEY;
8 ?4 k4 W4 s0 _; H3 k& p  k    GPIO_KEY = 0x0f;& ?8 z: d* h' R; m( D+ W
    if(GPIO_KEY != 0x0f) //判断按键是否有按下
8 A; @1 U; m2 J" t# ~' }) `5 D    {+ p. i) s8 ?" E. s# I
        delay_ms(10);   //延时去抖
7 f7 h8 H6 h3 _" a' J        if(GPIO_KEY != 0x0f)  //再次判断是否有按下
9 y. Q" P" i) \& S- ]4 M" y        {7 o7 C) A* i' e9 M  {1 G1 u) h
            //扫描列( m" I3 {6 f' U
            GPIO_KEY = 0x0f;6 S6 r! [4 o$ s' P1 `( a% ^
            switch(GPIO_KEY)9 Z/ D$ r, v, l4 B
            {6 G: ^! b5 O7 Y9 x5 I7 W% R
                case(0x07):KEY = 0;break;" r) Z1 `; N' Q$ T8 V7 w$ |
                case(0x0b):KEY = 1;break;5 g4 V5 }/ h5 x
                case(0x0d):KEY = 2;break;
& r* q" d7 Y" M                case(0x0e):KEY = 3;break;
  t* k$ u0 k5 _            } 7 N7 x0 E) A8 i$ e" |7 U
            //扫描行/ {5 t0 r, J: G$ y7 w
            GPIO_KEY = 0xf0;
; u( r* N" f; V5 i            switch(GPIO_KEY): m2 m: n& _, N$ D
            {5 z7 n# o  M7 _7 x) t5 G0 g
                case(0x70):KEY = KEY;break;
1 x) ^1 i  p: a7 i                case(0xb0):KEY = KEY+4;break;2 \9 n. r3 R) K
                case(0xd0):KEY = KEY+8;break;. e9 `7 z6 c7 H3 ^9 Z* M
                case(0xe0):KEY = KEY+12;break;
* s5 O; N, {* K. F3 p7 h1 N            }* Z6 U/ `0 f$ }
            while((a<50) && (GPIO_KEY != 0xf0)) //按键松开检查7 _5 B( }% j* `! A, M# C
            {/ ?# p3 y8 V/ Z- t& j7 ^+ l( u
                delay_ms(10);% f3 |$ [6 f5 m1 I0 N, O
                a++;
" Q3 O7 S7 \1 s! G            }
5 z9 j2 y0 u  [/ N1 R            return KEY;   
. u* r4 y. D, Q! x$ n8 H* ?9 d        }
5 o+ @: B  B  q    }
# r/ Q3 z/ ^/ U# i/ o; a}, Y' X; w- G0 D0 }2 `# v; ^2 \  C

) d& e! ]8 S3 rvoid Keyscan_duli(): V  s# O6 s' O0 j6 R
{2 R3 M' L- i4 W1 O/ m& n  a
    if(GM == 0)
; h: h: S! k- W& d6 h    {
5 b6 y" h! i  f. |' ?# ?5 F3 p6 q        delay_ms(10);
+ P7 k) Z8 |9 W% I. R        if(GM == 0)2 p; Q5 Y: j5 n( C; G# M: u
        {+ s' P& ?: C" i% x2 h9 \1 K
            KEY = 0x0b;- p. @9 d8 Q+ E7 W8 v, Y  s
        }( M" |& i# i0 T9 n( q
        while(!GM);% |* G; G& B6 [
    }3 @% R* s1 U5 P* z- H' u
    else if(SM == 0)
3 K2 U) g. n- Q7 `    {
' L; f$ z6 B8 X        delay_ms(10);8 }9 P7 X+ G1 E& R5 F  B0 P  E
        if(SM == 0): u1 E6 \, F) H# v8 f6 d
        {$ [! Z) I  G. \, }5 _7 G
            KEY = 0x0a;+ R/ ]. j& p7 w- s6 R
        }
  u. p2 l3 ?% l0 c. Y1 O% ?6 J6 U        while(!SM);
: w! B9 ?7 o# @: T    }
4 {. h# h+ m! x* |0 h    else if(OK == 0)
+ C: v' e4 W  o8 t- [5 R    {
( D2 h( C# n4 f, s: s- T& m3 x        delay_ms(10);
$ E  O9 ?$ G+ f6 \        if(OK == 0)3 q- Y- S& u3 D0 F( q
        {5 J) P- J4 h" S
            KEY = 0x0c;& h' g  _* @9 a0 U( J9 N
        }) M7 S& g. f( Q
        while(!OK);3 B* _# T2 A* _. P% P- W
    }
) V( V# }& A+ n# V}  d. w3 M2 g' d2 j3 F, E
) Z  T5 B$ H$ M& `  g
7 X9 U0 q. ]( a8 [' k

+ ]+ t1 y- O5 {  M, K# d8 u3 `' ]void main()/ C% p8 ~4 @: y( P1 e, e
{
6 p. d+ ]# u( ^+ W    LSA = 0;. \6 N6 @- g. {, i- p+ [9 s
    LSB = 0;
; L1 ~, N! z$ ]1 m    LSC = 0;9 o; S9 c7 z/ M( K7 S: S* S5 L) \
    while(1)
$ F$ k" M6 N4 z4 F  H    {   1 i7 b5 ~3 @8 r+ ]# z1 m8 w& j
        Keyscan_duli();
0 _7 `0 q! R) `4 e/ e# C        KEY = Keyscan();        
# v5 B3 V0 Z% ]        GPIO_DIG = smgduan[KEY]; 6 l+ ]8 j* Q9 f
    }7 G2 O# |1 @1 Z' G% p0 D# X/ [
}
$ {! S4 _' h7 c* F1 o6 ~- H+ O4 N1 M) k  j1 E8 t( A

$ [1 p* y9 e5 O2 M5 P4 J想问下各位大佬,为什么不管按GM、SM、OK键数码管都显示A,而如果只有独立键盘扫描函数,即把主函数中的KEY=Keyscan()注释掉,按GM、SM、OK键就能分别显示A、B、C。( g& J& G- H1 j

该用户从未签到

2#
发表于 2019-3-21 10:01 | 只看该作者
Keyscan_duli();
9 ^. F: a, r% O7 \; x3 U        KEY = Keyscan();
! R% d: e. ~% C这两个函数都是修改同一个变量KEY,Keyscan_duli();是在函数内部修改,Keyscan();是执行完后返回给KEY,这样的话,执行完Keyscan_duli();后,不管KEY是什么值,再执行完Keyscan(); 就被修改了。1 |" [" i: {& W# y7 d
应该用两个不同的变量,或者用不同的按键码值

点评

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

该用户从未签到

3#
 楼主| 发表于 2019-3-21 10:04 | 只看该作者
relchhiclty 发表于 2019-3-21 10:01
# W# P! {% [) x  m( r+ ]1 ?Keyscan_duli();
. L; k: B; D6 h+ N  v) ?7 k        KEY = Keyscan();
( P3 D5 j  V8 ], q/ t这两个函数都是修改同一个变量KEY,Keyscan_duli();是在函数 ...
4 m- R0 u0 R) t
那显示时不就有两个变量名
! s7 g$ S; s7 y. d' T  P

点评

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

该用户从未签到

4#
发表于 2019-3-21 10:06 | 只看该作者
小黄豆 发表于 2019-3-21 10:04: V5 H$ i# f! T7 W3 E6 t0 E5 Q7 E
那显示时不就有两个变量名

; C# }4 w! O  E/ J& m; e! E不想有两个变量名,两个函数调用次序对调一下,先键盘矩阵,然后再是独立键盘# w: E# e7 ^- k+ H. m3 W- q

点评

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

该用户从未签到

5#
 楼主| 发表于 2019-3-21 10:19 | 只看该作者
relchhiclty 发表于 2019-3-21 10:06
7 V) v) `6 a; n) X; q# x5 _不想有两个变量名,两个函数调用次序对调一下,先键盘矩阵,然后再是独立键盘
* ~. s/ ?% W2 |3 m- q6 ~  t
还是不行  {. s" w/ `- G3 q; R

该用户从未签到

6#
发表于 2019-3-21 10:20 | 只看该作者
矩阵按键扫描函数错了。。。
) d8 _7 V& t& i//扫描列/ k2 b8 v, T0 X- [2 v
            GPIO_KEY = 0x0f;" j7 n, c/ e- A/ x' m
            switch(GPIO_KEY)( W2 ~/ R  o' x2 r1 ~) c
            {; o( S% P4 x/ l( ~' ?" ~/ O
                case(0x07):KEY = 0;break;2 I6 T( M& q' Y$ q/ Z% h3 F
                case(0x0b):KEY = 1;break;( A4 B" c4 y1 n! N
                case(0x0d):KEY = 2;break;
: a  C" s, q4 k5 N% v4 x                case(0x0e):KEY = 3;break;
& v0 d" N5 m5 _            }
- Z  f. z: }. Q- m% w1 \            //扫描行
+ d7 W9 M: d8 g5 H+ \            GPIO_KEY = 0xf0;
+ `( X7 ]2 G1 d. u4 x) Z            switch(GPIO_KEY)4 d8 ?% R, Y6 ~! i% D  H- h# A
            {
  l8 U4 {6 P8 ^                case(0x70):KEY = KEY;break;9 `, j3 C( E, i- w
                case(0xb0):KEY = KEY+4;break;
1 t! A3 k6 J& W# l; h                case(0xd0):KEY = KEY+8;break;
& n: O' P, V& V  j7 D! H                case(0xe0):KEY = KEY+12;break;2 ]! f3 A% [6 C- I* s9 |
            }
6 W* \% x& e5 k3 C, b应该是&=吧??你直接赋值,case没有满足的!

点评

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

该用户从未签到

7#
 楼主| 发表于 2019-3-21 10:21 | 只看该作者
yxlk 发表于 2019-3-21 10:20
! V+ u% ~5 g/ R1 n6 M2 S矩阵按键扫描函数错了。。。
4 v( P& S- V6 V1 R3 P0 m1 J//扫描列' D3 d" G  q# v$ {- R6 N) u
            GPIO_KEY = 0x0f;
# m; F9 a' F( L5 d3 g. Y. k
单独使用没问题啊+ G7 H; \: q% h( K! k+ j

该用户从未签到

8#
发表于 2019-3-21 10:26 | 只看该作者
全局变量KEY在Keyscan_duli();程序中获取的值被下一条语句KEY = Keyscan();覆盖掉了。改成这样看看:#include <reg52.h>2 G* q7 L3 u" O9 H) Q
2 h: ]* x/ }8 K- k' Z
#define GPIO_KEY P1 //矩阵键盘的接口* h5 V6 J! ^( J
#define GPIO_DIG P0
$ T' A4 W1 a% J& H3 u! K0 F; z+ O. ~typedef unsigned char u8;
/ ~. Q1 d6 F+ x/ \9 _, j+ o; [2 j5 Cu8 KEY;
/ o7 _1 u8 M7 b. R+ R) ~# q, `sbit SM = P3^1;   //输入密码按键
6 Z& e  g, r7 Y- Ksbit GM = P3^0;   //修改密码按键
7 L7 g7 O- `( e+ Z6 Bsbit OK = P3^2;   //确认键
/ N  T9 T/ u- x) A7 wsbit LSA = P2^2;
1 B) F7 |. K+ Usbit LSB = P2^3;
; a+ H( X8 g5 s5 |$ v( |1 ~sbit LSC = P2^4;/ G$ j4 L, ]1 z9 g3 H

, J- w$ w8 J' j+ Y. E" d/ Ru8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
3 V# B9 Z  m0 q) y                                         0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值: h$ Y* c: C1 L
2 D7 \9 Q) R" A5 q# e( \: s
void delay_ms(unsigned int x)
- k4 t7 l- a) |9 R+ j2 m{
- t0 d6 ]5 s6 s! l0 J, R2 V   unsigned int i,j;
5 F$ d; ^/ e& P' U: s( c6 o5 a" N        for(i = 0;i < x; i++)+ G7 r$ {# x; W; }6 k) @0 l9 ]! ^" H
                for(j = 0; j < 110; j++);1 \! b/ J) d0 C) v! x6 V$ _
}
! P6 ?8 `0 o$ h& F" N8 |5 J$ n% w( A) d" |! J4 c( ], K
void  Keyscan()3 a( a+ ^0 ~' X6 j' j. a
{
  [3 X8 M% l- |6 J3 h5 ]0 p    char a = 0;  Q/ [7 q9 Z& s# c
//   u8 KEY;
4 |( a5 O5 Z$ V1 ?* d6 G% [' l: H0 L    GPIO_KEY = 0x0f;8 T1 d9 j! y) ~7 r0 V
    if(GPIO_KEY != 0x0f) //判断按键是否有按下& C( @$ [  F, K  ~3 _- ^7 P
    {  J  _* {  X: D3 e4 E* \
        delay_ms(10);   //延时去抖
6 R" E& a1 u, c        if(GPIO_KEY != 0x0f)  //再次判断是否有按下
1 m1 ~$ Y% `* |! y7 K9 A" [) L        {
9 @# I. Z9 f9 R9 w8 T            //扫描列+ e& B+ e' M4 m: ]+ h; ]! k
            GPIO_KEY = 0x0f;9 G: p! h5 t& g7 m  q) b
            switch(GPIO_KEY)  R& Z. U8 k4 F6 l8 u
            {
# y9 i  n2 A! Z' w                case(0x07):KEY = 0;break;* e/ \6 c& m( f4 t% }  D
                case(0x0b):KEY = 1;break;( T" o+ G6 F0 v6 b: X7 `
                case(0x0d):KEY = 2;break;% p7 P6 ~5 Q1 f! U
                case(0x0e):KEY = 3;break;
9 Y% d; g8 D, r# R            } 1 Z: z, _3 }" J9 [( f4 F
            //扫描行
8 A! Y/ s  A; d, f( v% j; [3 U8 T            GPIO_KEY = 0xf0;
( Z  L0 R1 X6 S' a+ Z            switch(GPIO_KEY)8 d) O, I1 i. q
            {
2 a) y, T) b* N. Y6 d* z                case(0x70):KEY = KEY;break;
& U8 E' F$ J$ `                case(0xb0):KEY = KEY+4;break;
% \/ L, t2 e& P% W' z( O                case(0xd0):KEY = KEY+8;break;) I, q7 k$ i7 `. v3 ]: f( q* |
                case(0xe0):KEY = KEY+12;break;7 X5 Q6 t- [1 h$ u) k% h# \
            }
! _7 j6 `& y7 s            while((a<50) && (GPIO_KEY != 0xf0)) //按键松开检查
3 R0 A  n1 I8 ~7 c0 w            {$ v$ s- h6 X/ }, k; Q
                delay_ms(10);* ^8 a& I5 u, g, I! G4 }/ @
                a++;7 D6 B4 ~7 h- a( A" |; l  [
            }
0 ?$ D5 f- T6 Y, s( p& ]* ?4 a1 m! c; R//           return KEY;   5 L; g% N9 B' W+ w1 j9 T
        }- ^' a( N% o+ d& `2 W* k+ u: {
    }
! o* l: Q$ M! r}
- d3 N5 G( d/ U( H
) X2 D4 l  n* Z, N, c; C" c* qvoid Keyscan_duli()# K3 W0 \# i& I8 S- m
{1 v$ F# T5 x9 F  s+ ~
    if(GM == 0)
/ l* I+ g8 e+ m# }  T3 k( K6 o    {+ T1 ]- |# ^, q/ s. H
        delay_ms(10);; T: z% k- ]8 b( Z# k5 K- ^
        if(GM == 0)
0 r+ A, E5 e3 h/ l2 V. W+ H! }        {
% A: x' Q% W% w6 @  ?( ?7 E) }- C            KEY = 0x0b;
& O7 g* g3 v' [4 o5 W        }# k0 }" e& m9 Y* L2 P
        while(!GM);
3 d3 p8 E2 W4 s6 }; Y1 k6 @  v    }
) p, e0 z% I* j: ]* k! q7 J    else if(SM == 0)8 r- ?, A$ F" V" f
    {) u. u, a* v! D5 E! l
        delay_ms(10);
$ l  \$ A, N1 Q) K% y. C        if(SM == 0)% C1 y1 ?7 H( i5 M6 w
        {1 ^. ~+ j" K: w
            KEY = 0x0a;; `' \* k6 d( m1 p  o. }4 Q9 \# F/ ]
        }
( D! M& |, {0 _5 r( k" ^6 F& P# X        while(!SM);; x3 J' X1 S! i8 {
    }
5 K1 \7 w% c* S    else if(OK == 0)
" l5 {+ O3 T, |. j0 v, a    {
# O3 `) Z- b9 z# z5 @2 V' }6 Q- O8 E! p        delay_ms(10);
; T4 O( {7 d: \6 E        if(OK == 0). F2 c4 w8 }& c0 ?1 z, E2 }
        {; ]: F6 E% H6 s  z
            KEY = 0x0c;
7 ^* |# a0 b7 a- V0 t6 `        }
: ?" p8 `! a/ z6 q4 n, Q3 Z8 F        while(!OK);
. h# Z0 u4 J8 b2 j) z4 C    }$ a  \( }' L0 E! Q1 b. q
}
2 x8 t% T; G6 m; W9 |% D  F: w! ?# o9 V! a- V; K
4 z0 q7 p8 S+ [( i2 L
& _# D7 b% E+ W9 a$ \$ x! |
void main()
# I- O' t( y% x7 }. B6 c{! Q3 j& y2 j4 A7 p3 \
    LSA = 0;# {/ |2 a8 k6 B4 ^6 d- W0 u
    LSB = 0;, x# \! k8 z+ ^, b
    LSC = 0;+ S! Z% `" ~" |: [% T" U
    while(1)8 q7 ~# a/ x5 y0 t
    {   
9 n( v- x  u# S/ `        Keyscan_duli();
4 {5 E/ U7 M# O* G: N        Keyscan();        
* k/ r3 y5 O& }$ ?0 P        GPIO_DIG = smgduan[KEY]; , w; ^: L$ j# F* C1 Z/ |+ X( c( @4 L9 T
    }" l6 Q8 P5 I! A! y
}

点评

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

该用户从未签到

9#
 楼主| 发表于 2019-3-21 10:33 | 只看该作者
kinidrily 发表于 2019-3-21 10:26
5 z0 T$ v, _& y9 K- N8 [全局变量KEY在Keyscan_duli();程序中获取的值被下一条语句KEY = Keyscan();覆盖掉了。改成这样看看:#inclu ...
6 a; ?. P) P  l* k
这样就可以了,这是为啥啊8 Z! L$ b8 Y2 c

点评

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

该用户从未签到

10#
发表于 2019-3-21 11:21 | 只看该作者
小黄豆 发表于 2019-3-21 10:33
( J* |/ P, P8 ]( F) a这样就可以了,这是为啥啊

/ I4 ^% F9 A+ r) z" ?这是因为全局变量KEY在独立键盘扫描程序Keyscan_duli();中获得的值会被矩阵键盘扫描程序KEY = Keyscan();改写。我把矩阵键盘扫描程序中的局部变量KEY注释掉,也取消返回值,这样两个键盘扫描程序共用全局变量KEY,在主程序中分别调用两个键盘扫描程序,谁有操作就显示谁的键值。
8 R8 V+ s. Y. f  w4 r' |  ^, c/ F  i5 j; @& L

点评

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

该用户从未签到

11#
 楼主| 发表于 2019-3-21 11:26 | 只看该作者
kinidrily 发表于 2019-3-21 11:21
8 O+ N( Q7 @+ P3 ^  J这是因为全局变量KEY在独立键盘扫描程序Keyscan_duli();中获得的值会被矩阵键盘扫描程序KEY = Keyscan(); ...
7 H) l7 j3 F5 s) i* `, I" U
哦 明白了 谢谢) x- o7 J3 p  I6 B

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-10-12 00:29 , Processed in 0.171875 second(s), 33 queries , Gzip On.

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

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

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