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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
单片机独立键盘与矩阵键盘的问题
/ O* R+ a) G  O1 T7 a  |- w& D$ C! c6 t9 \7 o* Z& Y/ m  v6 B

+ c0 e$ ]) a( l; H( t#include <reg52.h>
! k& t4 H4 r, ~8 Z3 u
5 k$ o* A% N2 q+ `  c#define GPIO_KEY P1 //矩阵键盘的接口
$ J% ]6 \$ m8 I/ a#define GPIO_DIG P0
) e( _: {  \" [7 G/ Z( s- d8 x( v- ztypedef unsigned char u8;
1 H& R3 R% [* |) uu8 KEY;
; ]2 k* q( p; K9 k2 l& ~sbit SM = P3^1;   //输入密码按键0 N, @( ^; N8 j9 E+ ^) D. K" Q' e
sbit GM = P3^0;   //修改密码按键5 L) i4 r, T& \$ }3 z3 n2 j) g6 l% J
sbit OK = P3^2;   //确认键
: r' F4 ^6 R# H. wsbit LSA = P2^2;
- T5 d9 p! n5 @" D% @sbit LSB = P2^3;; @1 t4 h" p0 u6 i, |
sbit LSC = P2^4;
# v% U) b. h, G* t/ _; t
& f8 @0 I) O* W" i' Q( |4 Vu8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,# Z/ v. ]3 L! O& e
                                         0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
3 g( d4 E4 \2 O' V2 B# l, |+ L+ m/ h/ m2 @4 _5 ?" Z' O
void delay_ms(unsigned int x)2 r! ^; T/ f9 f
{
7 b6 S# {# O% R   unsigned int i,j;
% L& L  ]( d' S( I        for(i = 0;i < x; i++)2 I; u2 F) T  K
                for(j = 0; j < 110; j++);; ~+ N8 c% P. _
}
; n0 H  W, J" k2 I: e' O6 |! n8 J" d, F; B6 w5 A7 h
u8 Keyscan()* u7 o: n5 l! a7 Z& M; _% ?* y
{
) R& X8 D% [# V    char a = 0;9 B# f. M3 S3 J# w
    u8 KEY;; O+ D2 u2 |6 L8 O+ K" O3 B
    GPIO_KEY = 0x0f;+ P: d2 s* }8 v
    if(GPIO_KEY != 0x0f) //判断按键是否有按下+ Z2 i( V% z! ?  Z( Z& L) j
    {
& Y7 B- o0 J  E, F# T        delay_ms(10);   //延时去抖
4 B) x3 b% Y! R% J. d! {& c        if(GPIO_KEY != 0x0f)  //再次判断是否有按下! E4 P3 d: o* p5 o
        {
2 |; g% n" w7 q8 c& U            //扫描列2 x  |/ D, ~* q+ _, R9 g3 t
            GPIO_KEY = 0x0f;2 _8 E5 w) y* \6 `
            switch(GPIO_KEY)5 h% |/ l1 ^2 q5 Q
            {$ s5 }( ^8 {1 e& |/ ^. x5 C
                case(0x07):KEY = 0;break;( V- F2 x: ]+ C* S2 V# G. W
                case(0x0b):KEY = 1;break;
+ W! \" b: [) ?$ V8 a* q. y$ i2 s  H                case(0x0d):KEY = 2;break;& g- v& @, E- r: A- J0 X5 D
                case(0x0e):KEY = 3;break;4 u, e  N( n. h1 z' t- Q6 W7 E
            }
- N: ?9 }- Y, L: X& D& }2 E, S7 e            //扫描行
) c7 ]- x  Y3 {* ?: ?, Q0 j6 E            GPIO_KEY = 0xf0;# m" k9 g. Q2 \' [8 A
            switch(GPIO_KEY)3 e, N2 \5 p4 H7 y$ Z
            {
6 a1 T0 p0 K; p5 h9 H+ y1 |" F                case(0x70):KEY = KEY;break;4 p) A2 H7 r9 [6 \' w0 z: @( x* E8 D
                case(0xb0):KEY = KEY+4;break;
8 R9 R! \2 \3 I9 F                case(0xd0):KEY = KEY+8;break;' V, \0 z* O0 x( v3 U
                case(0xe0):KEY = KEY+12;break;& _) t) D% f  V8 f: g* y: ^$ D
            }; n0 v5 J& H. k& s& T+ D' c
            while((a<50) && (GPIO_KEY != 0xf0)) //按键松开检查4 d6 k, x4 B) T% K
            {+ ]5 G2 l: J: U. J# j
                delay_ms(10);
3 n" f  U: }7 D                a++;
6 K- P& w4 ~' |! g            }; D' u5 n! V4 Y) ^  E! M; ^% R
            return KEY;   
5 m* x" |1 m% U6 k- N5 R- n5 |        }
( \- H/ w3 A! a( O    }3 E8 C* ^# q, \* E* j8 }3 B
}
! [9 r) x7 O) e1 G* E( D/ t( P9 i6 @  R8 t3 p' J$ p& v! a7 E
void Keyscan_duli()
& S- _; |3 M& W' }{8 l4 @5 p6 U7 R. |. {# x* D
    if(GM == 0)
2 }' T2 f. D, ]9 z7 o7 a& v    {! N  U/ |- r$ O* p0 c
        delay_ms(10);8 C; U# H5 [7 X  t1 s5 V
        if(GM == 0)' D1 f0 [6 C' e
        {$ e+ p" m$ T9 ?- w' O3 f; I& m$ j
            KEY = 0x0b;6 p& N  B! U# _3 e( Q: E
        }) w# f* R: M; }, M% C/ [
        while(!GM);
- m! M' e! u0 W/ a    }
2 v4 L) A: O5 z3 G8 `    else if(SM == 0)
; D8 I6 p, s6 \' W' h    {8 K4 z+ P( i; {& n% t# \; \+ n: L
        delay_ms(10);
% q$ ]! [" c0 V        if(SM == 0)3 r6 ?, M; {4 t( H3 C- G! n# X
        {5 y4 P8 z* s, B9 o
            KEY = 0x0a;3 a0 a2 n* g, y  n6 Y7 y
        }
! Z) q( S( z0 Y        while(!SM);
( {9 i: q. h2 N7 \" u    }
5 X& g" U. Q) u* L6 n$ K0 H  N    else if(OK == 0)0 \) s2 x: ~0 H
    {
$ t1 s2 `# u4 [' J* y2 @$ L# |        delay_ms(10);
: R/ {5 a- Q( M        if(OK == 0)% v- J7 f+ g: u+ C: w( a
        {, o! }! W: w% e, x) ]
            KEY = 0x0c;6 N" P& J: i4 L7 Q  O% z
        }
! ~6 P6 r9 p8 \, ?; R        while(!OK);5 Q8 c- G0 q+ n0 }+ S0 F% ?, _
    }. g) {0 y  I" G* B
}
" D  D( B1 A+ {; O. D
. ^" z& T* l; q
  c( C  F4 x6 `1 u# j! ^3 m- U. P' M. ^. ]
6 A0 Z, h# i+ p- ?void main()
, n; m; k0 z& r$ e" s" ]; Y8 z+ J( a{1 y  t5 s4 Y. [& t- w6 m, A
    LSA = 0;
6 G: e, N' `9 F0 m" p0 C8 Q    LSB = 0;
9 B. @/ p' Y, {8 [+ `' V+ E    LSC = 0;
% B4 w( W# K8 ?8 t6 `    while(1)
# q5 a# i. k% D/ w    {   
. i5 S" q1 r# Q$ m# l        Keyscan_duli();3 A7 I: t) B: F/ i" t  d
        KEY = Keyscan();        9 g+ m8 f8 a* Y; K5 C' T
        GPIO_DIG = smgduan[KEY]; : u" b) F4 v* r% Q* |6 b
    }
6 Y5 Y( p4 B( A8 ]% V}
& B' A  r. [2 @8 f% D: i  C
- g5 i5 B8 o. J6 t# w
/ ]  |- Y" n- Q- j2 H想问下各位大佬,为什么不管按GM、SM、OK键数码管都显示A,而如果只有独立键盘扫描函数,即把主函数中的KEY=Keyscan()注释掉,按GM、SM、OK键就能分别显示A、B、C。
8 J5 J; G9 ]5 r

该用户从未签到

2#
发表于 2019-3-21 10:01 | 只看该作者
Keyscan_duli();% y( ]' W# s' J+ D- j
        KEY = Keyscan();
$ b7 r" Q) H. B1 {  n  @( D+ D" D这两个函数都是修改同一个变量KEY,Keyscan_duli();是在函数内部修改,Keyscan();是执行完后返回给KEY,这样的话,执行完Keyscan_duli();后,不管KEY是什么值,再执行完Keyscan(); 就被修改了。: r8 Z+ x6 c8 a  U
应该用两个不同的变量,或者用不同的按键码值

点评

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

该用户从未签到

3#
 楼主| 发表于 2019-3-21 10:04 | 只看该作者
relchhiclty 发表于 2019-3-21 10:01$ a$ N5 R/ Z, l+ o
Keyscan_duli();
2 \: i9 N  V: m" v/ `        KEY = Keyscan();
. H: R% D1 }6 w( d# {这两个函数都是修改同一个变量KEY,Keyscan_duli();是在函数 ...

) P* O+ ^0 {* U7 i那显示时不就有两个变量名  U3 ~: j  M$ n/ S9 t+ U7 N

点评

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

该用户从未签到

4#
发表于 2019-3-21 10:06 | 只看该作者
小黄豆 发表于 2019-3-21 10:04
9 h2 P* u1 G' n. M  Q# ?2 J那显示时不就有两个变量名

1 \4 X6 o8 k( Z7 w# G' q" u不想有两个变量名,两个函数调用次序对调一下,先键盘矩阵,然后再是独立键盘
0 ^; M3 D9 b; T4 Y- @- ^

点评

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

该用户从未签到

5#
 楼主| 发表于 2019-3-21 10:19 | 只看该作者
relchhiclty 发表于 2019-3-21 10:069 y6 r- g+ L& M  u7 F
不想有两个变量名,两个函数调用次序对调一下,先键盘矩阵,然后再是独立键盘

9 T% s9 X- e' |4 c7 X6 a还是不行
% c" f# y9 R& {& y- }. Y/ ^8 c

该用户从未签到

6#
发表于 2019-3-21 10:20 | 只看该作者
矩阵按键扫描函数错了。。。
6 r: {8 `; q, B//扫描列
% ~5 w. T+ i$ O            GPIO_KEY = 0x0f;
. ]8 Y' n: A6 s; O$ s3 Z            switch(GPIO_KEY)3 {) W: a$ d6 \# t( Y* ]
            {
, [+ G% f; W& _9 ]                case(0x07):KEY = 0;break;; s1 @# U3 t1 F* `
                case(0x0b):KEY = 1;break;" `+ a9 G$ N2 s+ S/ N# h% M' x
                case(0x0d):KEY = 2;break;- t: o! I/ n4 x% F
                case(0x0e):KEY = 3;break;
$ ~4 n2 L# r$ p" B% x1 s5 x  g            } ) |. @9 k! L! t6 A. Z) S0 g
            //扫描行9 f: P2 }( @& E/ Z
            GPIO_KEY = 0xf0;5 R( A$ G$ H- B
            switch(GPIO_KEY)
; D2 \6 Z- _, M  O; L- H            {
; o3 _; m, j- v% d3 h/ M2 i4 {                case(0x70):KEY = KEY;break;4 d, E) q0 y3 F" G2 K
                case(0xb0):KEY = KEY+4;break;+ e( A1 L* o! M; d/ Z- p* a/ `! i
                case(0xd0):KEY = KEY+8;break;
8 @, l+ Z7 g' \9 v5 c% s5 D! m                case(0xe0):KEY = KEY+12;break;
, |# m$ i+ }( b, g            }
& Q& e+ ^1 d! N应该是&=吧??你直接赋值,case没有满足的!

点评

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

该用户从未签到

7#
 楼主| 发表于 2019-3-21 10:21 | 只看该作者
yxlk 发表于 2019-3-21 10:203 ]/ }9 _: e; S# q
矩阵按键扫描函数错了。。。! L/ S4 `3 a  e0 ^! Y7 {) l, y
//扫描列
- m/ z6 ]( T" k0 _2 L4 g            GPIO_KEY = 0x0f;
8 b/ N, p& N3 z* `
单独使用没问题啊
# H/ f5 T, s# m) [

该用户从未签到

8#
发表于 2019-3-21 10:26 | 只看该作者
全局变量KEY在Keyscan_duli();程序中获取的值被下一条语句KEY = Keyscan();覆盖掉了。改成这样看看:#include <reg52.h>
# S; ^# L9 Y# f8 L. `
  C5 L, v- _9 ?) L#define GPIO_KEY P1 //矩阵键盘的接口* F2 Q% x# y  h& O+ t7 u# r
#define GPIO_DIG P0
9 C" j& t/ \# B$ K- ]/ S* L5 g  |typedef unsigned char u8;
% e% F$ N2 p/ R- G! }u8 KEY;
3 y+ _( d. Y6 `3 W+ e# D+ d2 ssbit SM = P3^1;   //输入密码按键
7 k* T# x& E8 D: B! D9 Y* wsbit GM = P3^0;   //修改密码按键
- T7 Y0 |1 |5 B  esbit OK = P3^2;   //确认键
) X7 {# G5 z7 nsbit LSA = P2^2;& A, Z6 q$ |9 x0 G2 O' j
sbit LSB = P2^3;8 L2 k% G3 Z, b# ?6 ?- j6 T3 n
sbit LSC = P2^4;8 d& x9 u) q0 H. u" j
( C$ O4 E) p9 p) r0 O0 j- w
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
5 A4 P) S* u$ k- H5 S5 w$ n                                         0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
8 E9 o6 E& \! j) T9 [  f# K# ]0 _4 {* ?" ]
void delay_ms(unsigned int x)
3 ]: ]* b! `1 A1 }{
) ^4 R  h" Z! h3 ]+ M! f   unsigned int i,j;* a2 y+ g: b4 K8 ?! `& D6 ^: \
        for(i = 0;i < x; i++)' [+ q& m$ y- a0 m' ^5 K" z
                for(j = 0; j < 110; j++);
1 y9 w3 \: L: V" s" h}
& I3 T- e6 L! Q* G
; e6 P# y0 ~! U" a, [void  Keyscan()
0 d0 U# v, O% Y4 Z2 {7 O{+ |4 a4 @& A9 D0 Y+ w' Y1 ]4 n
    char a = 0;& n% l* I3 s7 H& i
//   u8 KEY;5 N9 y8 ?" l7 c
    GPIO_KEY = 0x0f;6 U# A3 F& c2 x4 A
    if(GPIO_KEY != 0x0f) //判断按键是否有按下
+ ^, x) v  @' ?) d0 }1 z- Y    {3 [  b1 Z! T; ?0 N; p) E. L$ U
        delay_ms(10);   //延时去抖
2 q* m4 }0 u# b: p" Q5 N7 c        if(GPIO_KEY != 0x0f)  //再次判断是否有按下9 }6 d- |" N6 R# {2 P0 w* @! ?/ k2 h
        {! O- g8 _/ [( T0 A, Z- j, X
            //扫描列
' g5 D9 k- v; p7 p. X            GPIO_KEY = 0x0f;
( w- ?1 x( |) L' N& b* d+ l( U8 x6 H            switch(GPIO_KEY)
6 u5 C6 d$ i( l            {
$ y0 ^) W$ _; n4 i, _1 t3 U. p3 l' q% H) M                case(0x07):KEY = 0;break;
3 P5 x$ Z7 w0 x/ ]) _# D7 h0 E                case(0x0b):KEY = 1;break;
& h: D7 ^! ?# V9 v, y                case(0x0d):KEY = 2;break;* @4 u8 `2 }: ?: j# v- v; ~
                case(0x0e):KEY = 3;break;
* ~) F. \1 }6 g4 i& ~            }
- `/ _0 r+ O, k& \' V            //扫描行
& O. ^( J. w* a7 W3 ~/ p' s            GPIO_KEY = 0xf0;
8 N/ d. x6 h' A. L3 R4 h            switch(GPIO_KEY)" V  K: g1 S. T, Q, [
            {
* S  |" i0 u! n                case(0x70):KEY = KEY;break;; z1 X2 c' f7 c* \. a
                case(0xb0):KEY = KEY+4;break;9 Y- p0 l0 O; V
                case(0xd0):KEY = KEY+8;break;
. A2 w. M0 [; c8 ~" {5 r  u5 m* E                case(0xe0):KEY = KEY+12;break;
" k8 c8 h% U9 ?: @            }% ?3 K* N% q& g; L
            while((a<50) && (GPIO_KEY != 0xf0)) //按键松开检查
! Z# _: n0 `: y# H7 F" `            {
( }6 M$ p& X6 l3 g7 ?2 @                delay_ms(10);
# o/ o, F3 L3 F* y; x                a++;8 ?. T2 b7 T+ }
            }3 U6 w6 {: j7 z4 G6 V0 E
//           return KEY;   
& h* V4 S( @$ t( H* A7 U+ @        }
. u4 j* l- X7 {    }
$ m) ~- a& B. o}
! t8 f- R* B+ l8 y# d
1 v; p6 N% I; y( hvoid Keyscan_duli()
' f1 x+ o2 q8 J$ S. m{
( U2 A2 H) K. U& K* \9 Y% c5 ^    if(GM == 0)
9 Y, q5 Q. G$ @' I    {
) X7 W  x% |( Y+ P7 ]' y+ f/ j+ {        delay_ms(10);# h/ f* q+ M2 S3 m- F
        if(GM == 0). u4 I  x4 @: O! Z+ c
        {
/ ], b* J8 \1 Y% M: w            KEY = 0x0b;4 `" Z& [* u, R+ f
        }  \! H$ P6 p( z/ D0 M8 @! f0 J
        while(!GM);0 M" N" H3 C( G  ^$ M% L
    }: L5 g& k# ~9 }% m, q- K
    else if(SM == 0). n+ P& V8 a" S& |2 q0 L: z9 y" K
    {3 J8 U* L5 Z5 ?+ ^
        delay_ms(10);8 Q3 U) x# t6 u+ D" [9 z
        if(SM == 0)( P/ r' w) W2 I( g$ q, F. n8 h
        {
- Q% z- `) |/ }8 E: q3 T4 A& c3 F            KEY = 0x0a;+ w6 n. v/ G6 Z+ a3 T" h" \
        }4 n' D. {, M; j  Q
        while(!SM);
1 u* ]- P3 z" n5 t) n, m    }
/ T# H# Y) |4 ]+ N    else if(OK == 0)5 ]( s: x% ]  ]4 S$ f
    {
# C9 ~# u  f) S  T3 \. @4 k        delay_ms(10);
% B# ^7 l0 D  V, |8 a/ X3 e        if(OK == 0)
! T  c. B" ]* z9 z  e4 Q9 r        {
. c( V: q+ A6 [* y# F- o6 N            KEY = 0x0c;
; P( H. g7 t( T1 N" o        }
+ ?( B4 ?# B2 V: q        while(!OK);% V, A" @, j4 _" F
    }6 ?6 q* H& O- j. ?! I
}% P- X( e$ c$ {& _' K
3 u5 ]3 ~% q- S5 `3 m* J
/ k: e* g% O: L& U/ z& m

  m" Q1 h9 Y- R1 `* Xvoid main()3 `! y- n  G& `7 [9 j; \
{" o( Z! b) x: e' V2 u8 G) [
    LSA = 0;
% p0 \$ Y4 x3 ~( T- U5 m! U    LSB = 0;
  W9 X2 U! G% q6 r' o# G) ^' g    LSC = 0;
9 I! T: E. n+ v1 G' h    while(1)
7 n6 ?0 w( H" _6 n) x    {   
: y( }' s/ P) d5 f% c' c. E) T$ Y        Keyscan_duli();: w4 q  {. R0 `* M: L& g
        Keyscan();        
+ S) [8 `8 H4 I" ^3 }& B2 O5 L; x        GPIO_DIG = smgduan[KEY];
4 g5 H% ]/ |3 N6 Z1 h    }/ h2 m, ?( x% p* b
}

点评

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

该用户从未签到

9#
 楼主| 发表于 2019-3-21 10:33 | 只看该作者
kinidrily 发表于 2019-3-21 10:26
  f& @! B! W+ y4 i& r全局变量KEY在Keyscan_duli();程序中获取的值被下一条语句KEY = Keyscan();覆盖掉了。改成这样看看:#inclu ...
: d: j' c1 W. v; V7 S/ J
这样就可以了,这是为啥啊
7 e6 N0 |0 ~: S; p: n5 T- s) a

点评

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

该用户从未签到

10#
发表于 2019-3-21 11:21 | 只看该作者
小黄豆 发表于 2019-3-21 10:33
1 ^- V" P5 o0 q  f% m7 h这样就可以了,这是为啥啊

3 W1 |/ `( n4 e5 k( |这是因为全局变量KEY在独立键盘扫描程序Keyscan_duli();中获得的值会被矩阵键盘扫描程序KEY = Keyscan();改写。我把矩阵键盘扫描程序中的局部变量KEY注释掉,也取消返回值,这样两个键盘扫描程序共用全局变量KEY,在主程序中分别调用两个键盘扫描程序,谁有操作就显示谁的键值。
* {$ S) [# J1 S8 p
3 a1 F* f+ r/ V$ A5 e) x5 p$ o

点评

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

该用户从未签到

11#
 楼主| 发表于 2019-3-21 11:26 | 只看该作者
kinidrily 发表于 2019-3-21 11:21
# h5 J# Y( T( b, Y( a这是因为全局变量KEY在独立键盘扫描程序Keyscan_duli();中获得的值会被矩阵键盘扫描程序KEY = Keyscan(); ...

' v) a$ e4 v4 ?6 D- {哦 明白了 谢谢
! M/ f; n/ }' s1 p/ `0 w1 G

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-6-25 18:59 , Processed in 0.109375 second(s), 33 queries , Gzip On.

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

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

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