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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
单片机独立键盘与矩阵键盘的问题
. n" N' Y9 Y% o6 N  L" n4 M* v5 u9 R; I/ y
; X9 P4 H( w% ]9 y! z% B% e
#include <reg52.h>, W( P! `5 C1 c$ h: R3 ?6 b0 K& g1 p
" V2 \& s0 g7 A# ?+ C- T) u+ g
#define GPIO_KEY P1 //矩阵键盘的接口; `! o$ c) U5 h) y  a/ X
#define GPIO_DIG P05 ?: V) \; W  |
typedef unsigned char u8;
* p) _  f8 g! ^( xu8 KEY;0 g. o& K, S1 f  d3 b. v6 p
sbit SM = P3^1;   //输入密码按键
+ v$ Y0 Q$ Q/ S0 F1 Gsbit GM = P3^0;   //修改密码按键9 L( d! {# g+ c( y' Y
sbit OK = P3^2;   //确认键
5 F" E1 p) j. W$ t7 }- {sbit LSA = P2^2;
; n) V$ j9 I0 v7 t0 Y: \% s+ ~+ \sbit LSB = P2^3;; K& ?5 O! v. x- R; X( c
sbit LSC = P2^4;
: P; l# d, i( i6 _, |& |" G1 x1 y1 [/ D5 O
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,, E! r7 p5 p9 G, r7 L
                                         0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
! x, k/ r  b* U- W# N4 u9 J
4 ^  g7 h) \1 B6 q  ]void delay_ms(unsigned int x)
$ \1 @7 K3 F. G4 Z{5 b; z$ Y$ w; c1 v# G$ G# W
   unsigned int i,j;
- n% c; ]( x% q, f9 u9 o# G- j0 T        for(i = 0;i < x; i++)
8 g1 Z8 s- j4 L                for(j = 0; j < 110; j++);4 F) e  B/ D' c! f" r9 R& e4 M  n
}2 W! b% y5 X" r

4 T% m, t4 P) Zu8 Keyscan()
) P7 Y. F. ?+ X0 k. d0 H7 {0 z4 `) H{+ K$ l! J8 `' N
    char a = 0;: C' j* A" N% E
    u8 KEY;
, h  z# K: ~0 l, u8 W' v    GPIO_KEY = 0x0f;
# T: S* j1 Y% ^) v    if(GPIO_KEY != 0x0f) //判断按键是否有按下
! V7 g$ o  u7 x+ D    {  U- z0 `  o1 E# k
        delay_ms(10);   //延时去抖" G6 t0 h( s. l3 L1 P
        if(GPIO_KEY != 0x0f)  //再次判断是否有按下1 p9 S2 M- g6 B, Q" i
        {; V' n/ n1 ^1 l: s
            //扫描列
% Q( N: T( P7 z1 k            GPIO_KEY = 0x0f;9 U1 v" B- A  w/ s, Z# ]
            switch(GPIO_KEY)
: i# \' J0 M% I            {7 q4 P# ?6 H% Y, s3 ^4 W" l
                case(0x07):KEY = 0;break;
; h2 b$ @$ j" @- g9 Q9 c                case(0x0b):KEY = 1;break;
3 L+ \- G" H$ n                case(0x0d):KEY = 2;break;. K% I) x  e- c. N% W( u: t. \; D3 P
                case(0x0e):KEY = 3;break;
! s% x: {2 |) s! J            }
/ R1 m. `; Q1 E3 n* C3 z3 ^            //扫描行5 X9 B; T. F9 i+ `' V
            GPIO_KEY = 0xf0;
) o( b* z$ i5 w0 k& R$ R' v# |            switch(GPIO_KEY)
' _2 `  O' `; M) w            {
5 C# g$ j, R* U% Z                case(0x70):KEY = KEY;break;
/ s5 _, x8 D4 d                case(0xb0):KEY = KEY+4;break;) _+ o3 y' p. X% I* k% U
                case(0xd0):KEY = KEY+8;break;
# y/ H6 X" L( A4 p9 t                case(0xe0):KEY = KEY+12;break;8 w% b4 @, W6 S; _$ Y% @0 r
            }
, Q3 d  P) A$ N; [6 h+ l7 S2 I            while((a<50) && (GPIO_KEY != 0xf0)) //按键松开检查
. ?( b- z- ^. k1 T) M3 h. e            {
- l% ~: o% F" ]# I: Q                delay_ms(10);
' n1 ^2 N9 ]" c  \                a++;4 j( D1 e" c; T& w) }
            }: @  _- I" @+ f
            return KEY;   . F' r6 J3 `3 b! m* x5 B* \
        }1 }* V9 X7 |7 S5 B; p  K0 y3 i5 \
    }
$ D/ Y* F1 r, T( }}
6 U9 j5 ?. Q5 v9 f1 q! |3 k
- r& y* E" C! |1 U" |void Keyscan_duli()3 ]7 b+ O" }( G8 H4 X
{: F7 ~% y9 D. O$ z
    if(GM == 0)9 W7 |# _' S$ E" Y7 V9 w
    {
; K. y$ T0 b, p/ s8 p        delay_ms(10);- l% ^" q# A' b: ~( S+ V8 W
        if(GM == 0)4 G( H& G2 ?1 h+ c1 A* \
        {
# O4 t/ `0 n& ^9 J9 E            KEY = 0x0b;% v; t9 K9 S3 N8 `* V8 G
        }
7 S- q& M) z, |# E3 F8 W- l        while(!GM);( N. O0 Q: u+ ~, i
    }: X6 C  K! S- `9 J) A
    else if(SM == 0)
' [( Z9 W& A( [! z    {
4 }" {/ W, V6 y( \        delay_ms(10);- S, G! Z) I, y6 j8 W) ?1 \
        if(SM == 0)
6 R( J+ A. A, g        {7 |( V1 ^# D8 J% L- S
            KEY = 0x0a;
5 ?% {$ d* P3 J3 H! V- }% w- {        }
; ]& T' T* ^9 G9 `/ L9 R* H5 C        while(!SM);( w, a9 ~1 P( w  w( F9 u
    }+ z% I" m4 h* }0 l* s, x# R, N- {
    else if(OK == 0)
5 B" s% K0 A- n# X$ D/ V7 M) B) T    {. a7 U- d6 H2 _- x2 L: x3 \) P) U- h- e  [
        delay_ms(10);
5 [8 ~% k+ C/ M) L  H1 n        if(OK == 0)
9 ^8 X# w5 Z0 d. Z1 J        {+ L7 f" P1 O5 Q7 m, c! C8 h
            KEY = 0x0c;8 J/ \) J% Y9 n+ {' s
        }3 i7 |) E1 r4 {4 \$ r8 x+ a5 h
        while(!OK);7 Q# c: b+ s4 q1 z) u- e1 P
    }
7 \3 f3 C! y% j$ ?. f8 g1 G}) r$ T4 I/ s( O4 ~8 x  c9 `

; L. V! s6 h3 d: R( L7 f6 K. a
$ a6 Z% p, n" A* J! B2 X( K8 d# y7 [5 S6 r
void main()4 b7 G% s- u: `6 A7 n; V) E
{7 z$ m; B/ O9 w; V+ D% ?* O+ X
    LSA = 0;
0 Y5 n2 e% u5 O  H4 T+ t    LSB = 0;
1 d% k5 E0 q8 Z$ E    LSC = 0;
5 Z! ^4 {5 B- z+ a    while(1)7 y) d0 N! N2 O# T' ]
    {   
! E! w5 u6 {( G' s+ g        Keyscan_duli();6 w, A4 \1 R2 ?/ U* c/ ]
        KEY = Keyscan();        
1 W2 c- q/ G. c  F6 Q4 K! R        GPIO_DIG = smgduan[KEY];
$ J4 o9 z7 S. @: ?  N  V    }0 w9 B* E9 Y9 n; K9 l5 j$ ^
}* h# ~  T3 G' p9 k
; `" S8 Z! E1 y3 K4 q. q
+ {% m2 }( K+ ?+ w; S
想问下各位大佬,为什么不管按GM、SM、OK键数码管都显示A,而如果只有独立键盘扫描函数,即把主函数中的KEY=Keyscan()注释掉,按GM、SM、OK键就能分别显示A、B、C。
! ]7 g1 ~  i. A/ x3 x. S

该用户从未签到

2#
发表于 2019-3-21 10:01 | 只看该作者
Keyscan_duli();8 K; U6 S" `' S% ?6 B
        KEY = Keyscan();
6 c4 a0 `4 C+ G9 G这两个函数都是修改同一个变量KEY,Keyscan_duli();是在函数内部修改,Keyscan();是执行完后返回给KEY,这样的话,执行完Keyscan_duli();后,不管KEY是什么值,再执行完Keyscan(); 就被修改了。7 |- K  G+ u6 F" ^. K
应该用两个不同的变量,或者用不同的按键码值

点评

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

该用户从未签到

3#
 楼主| 发表于 2019-3-21 10:04 | 只看该作者
relchhiclty 发表于 2019-3-21 10:017 ~7 r& n& Y! P) l
Keyscan_duli();, L) w- z3 `- P* b: p
        KEY = Keyscan(); ; l; i6 w, B+ h3 i
这两个函数都是修改同一个变量KEY,Keyscan_duli();是在函数 ...
# h, W3 `- G# ?( K4 ~
那显示时不就有两个变量名) [0 v( z1 o  E+ |4 p0 i. L9 {

点评

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

该用户从未签到

4#
发表于 2019-3-21 10:06 | 只看该作者
小黄豆 发表于 2019-3-21 10:04
& F9 l& B. n; P" e. P" S5 _4 x那显示时不就有两个变量名
1 U4 N& Q/ {: Q5 r- a; i
不想有两个变量名,两个函数调用次序对调一下,先键盘矩阵,然后再是独立键盘
4 ]% n9 S  v- j

点评

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

该用户从未签到

5#
 楼主| 发表于 2019-3-21 10:19 | 只看该作者
relchhiclty 发表于 2019-3-21 10:06) ?3 Q' M) V; M7 A1 r5 x) R
不想有两个变量名,两个函数调用次序对调一下,先键盘矩阵,然后再是独立键盘

" o% b( p5 }! H+ c( Y还是不行
1 u0 M) L; N% p  m/ O& V2 t' i0 i$ M

该用户从未签到

6#
发表于 2019-3-21 10:20 | 只看该作者
矩阵按键扫描函数错了。。。
( o) U, C& Q' f" j1 t//扫描列
9 N6 G/ H1 V2 M- L) M            GPIO_KEY = 0x0f;
, P5 |' B: @0 X            switch(GPIO_KEY)2 `2 L: g7 t) t7 t
            {
) D& f" F' w* M; s2 A% D; w                case(0x07):KEY = 0;break;- [+ G. l& [4 S* _
                case(0x0b):KEY = 1;break;
5 D. C0 U& ?- ]. @# l( f# a% _                case(0x0d):KEY = 2;break;5 M9 D$ `/ F! ~: a; b
                case(0x0e):KEY = 3;break;
  Z  i3 j$ J& d! n! @* k" p            } 7 v% E+ C( L6 M2 l# H/ D5 _3 c" U; ]
            //扫描行
! L0 A4 Q+ {6 T: G0 ~  X            GPIO_KEY = 0xf0;1 w" y- A5 I2 q9 ^5 c+ e  G
            switch(GPIO_KEY)) K$ G5 V/ F9 O8 y* `
            {* o  @0 G+ a- a% N5 e' x
                case(0x70):KEY = KEY;break;
4 K* f; A3 z5 e/ M- m2 j                case(0xb0):KEY = KEY+4;break;
1 j5 m) u/ \& n$ o5 q# t                case(0xd0):KEY = KEY+8;break;  m1 A2 Q5 }& v
                case(0xe0):KEY = KEY+12;break;# @# X9 J7 N1 N  K
            }
6 Z0 S" w9 A1 ^: r- Z. z应该是&=吧??你直接赋值,case没有满足的!

点评

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

该用户从未签到

7#
 楼主| 发表于 2019-3-21 10:21 | 只看该作者
yxlk 发表于 2019-3-21 10:20
; W2 L+ t: ?) F5 ^2 U7 W矩阵按键扫描函数错了。。。
; n1 p7 y2 E6 |7 S0 S. M$ b//扫描列' T5 P; z2 {" x# p
            GPIO_KEY = 0x0f;

# O& h- n. |$ h单独使用没问题啊
0 V. b/ A1 s0 m, n  P

该用户从未签到

8#
发表于 2019-3-21 10:26 | 只看该作者
全局变量KEY在Keyscan_duli();程序中获取的值被下一条语句KEY = Keyscan();覆盖掉了。改成这样看看:#include <reg52.h>
8 u+ s7 z* G4 n
& O  V- K# X- O4 _/ D#define GPIO_KEY P1 //矩阵键盘的接口
% j1 r' S5 L+ n9 B0 C; ~#define GPIO_DIG P0: {  K7 [8 w1 t0 r; ?; `
typedef unsigned char u8;
* ?. m( V0 r6 d5 P# s( Bu8 KEY;% M4 X+ F& {# c& y( |# b
sbit SM = P3^1;   //输入密码按键5 [$ F# L8 W( i8 {% H
sbit GM = P3^0;   //修改密码按键
  Q- O9 G/ B9 q: r1 i: q) l* xsbit OK = P3^2;   //确认键
/ @6 G# B- c% ksbit LSA = P2^2;/ G6 {2 j  r3 [2 g# r
sbit LSB = P2^3;+ p9 R" g1 O6 M- T1 ]9 T6 U4 z
sbit LSC = P2^4;
5 j% f% N* ?8 ?, c9 `& G+ z" R# U0 r6 `# m  k, N1 [: q- M& _
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  P9 x- w. ~9 J( Q; E# M# a                                         0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
) S8 t3 R! A. M! L. ~, v9 q! s6 c' M
void delay_ms(unsigned int x)
, e7 T9 Q9 o$ B( M* M. g# b{
/ `1 x5 q, e/ }! b   unsigned int i,j;2 _' O% }1 c# }* o
        for(i = 0;i < x; i++)
9 A4 U% L& G# m- j7 j) x) q) {                for(j = 0; j < 110; j++);- u7 M, {, x" W3 R4 k
}: }5 S' Z4 ?7 h! O7 h/ Q, d# s
/ B5 e, q5 w- _7 l& q5 c; _2 [1 G$ D
void  Keyscan()4 x; {, X% g! a. W' D
{
, \5 p1 N0 F4 S0 ~# j" t% b  @    char a = 0;
; c# k$ p" |0 T+ w# s. h; }2 S# C//   u8 KEY;
$ C2 Q" C( G) T+ ~# C+ r    GPIO_KEY = 0x0f;
% W) O/ w3 U. B    if(GPIO_KEY != 0x0f) //判断按键是否有按下7 H' p0 Z' \: a9 z, m% s
    {8 `+ C# P: t$ I' }2 K6 Z- c4 D
        delay_ms(10);   //延时去抖0 X# {+ t: c5 D& h- X
        if(GPIO_KEY != 0x0f)  //再次判断是否有按下
& N! H5 r% g" J+ S8 K0 H        {
: b$ N# _+ i0 H+ r$ T  S8 U            //扫描列
& ?7 b" V) B! f( Y6 U            GPIO_KEY = 0x0f;6 |% T# ^8 X9 G! v
            switch(GPIO_KEY)8 j5 C3 i# g' X: z8 d* x3 h( x
            {$ X. W  b8 i/ X
                case(0x07):KEY = 0;break;" O, X; m/ M* l
                case(0x0b):KEY = 1;break;
2 ~, A, s- B: S) I                case(0x0d):KEY = 2;break;& X( }8 X0 {9 ]0 f
                case(0x0e):KEY = 3;break;
& Y& Q0 _9 L9 r  z            }
: T0 V3 I7 Q7 g! @2 {4 P            //扫描行7 o3 O6 f' H( [
            GPIO_KEY = 0xf0;
' ?% B  w# |# y: q7 V% d- _, y( k            switch(GPIO_KEY)
$ \+ P. X) K7 B0 n+ o! r$ i4 }            {
0 t! }/ f# w) f0 U5 s3 L9 Y5 y                case(0x70):KEY = KEY;break;* ~+ N* s/ Q: ]' F+ a
                case(0xb0):KEY = KEY+4;break;
3 d6 g  |: S+ n! Y+ a! O                case(0xd0):KEY = KEY+8;break;& V% R; i  U0 G- Q
                case(0xe0):KEY = KEY+12;break;
" b$ \; t' M0 Q8 R* Z            }
8 t# X* c, e( Z/ c! a            while((a<50) && (GPIO_KEY != 0xf0)) //按键松开检查# C3 @) r1 M2 L  c7 ?
            {
  j; q8 n+ R! }7 x3 A! d6 |/ G, q                delay_ms(10);& {  c0 a2 o1 w6 G# L
                a++;
# b- D7 T9 ~- W% ^6 B' s" `            }
9 r' n9 e* b3 u  x' o" a5 C//           return KEY;   ! V4 Z5 o" F6 u0 P+ |; p+ B, }2 F
        }/ Q: U: M4 q$ ~
    }
9 _- [1 a) [7 [}
0 b3 w" }3 g' e1 G$ o3 n9 Y- I6 I% M" X5 b
void Keyscan_duli()
. B2 r2 K6 I1 h{5 [( v# n& }( f, }5 X& U
    if(GM == 0)- C1 |4 f8 i1 }8 ?, i, j
    {
5 \0 R- p5 B4 L        delay_ms(10);5 c8 O/ @; n/ M% K- F" a
        if(GM == 0)
% O: \: ^, t' c2 x: n        {# C" d  B8 C0 I" e8 t0 ~
            KEY = 0x0b;
9 S* |: |& l) b5 `1 |' D        }! h7 G; x) k$ L% {5 W* D$ [1 c
        while(!GM);+ n$ L- q+ X7 p1 U/ k8 S& `& I
    }
# g5 U. q, w  m& t# N5 H8 z    else if(SM == 0)
6 ?' s' h9 x9 S: M    {0 X: I; e4 z1 F- a, G
        delay_ms(10);3 Y. `% @, I4 ~
        if(SM == 0)
( p) Z; m; w& p% |+ r9 H        {
+ a3 u* \# S/ O; W+ j# o            KEY = 0x0a;% H% M: J% L# z; G, d2 w$ A
        }
3 s" P4 b2 k" T- h6 \        while(!SM);
+ B( m+ T, S& c/ R7 W9 K' B% C( z& K" g    }' `6 L4 J% a6 {; h5 i6 a
    else if(OK == 0)$ T: H8 B. |7 ^. _9 i  B3 c7 N9 w
    {
: _7 [  ^$ q5 X1 }        delay_ms(10);  P4 n" x) ?2 M0 o4 V+ Q( Q
        if(OK == 0)
6 P3 j. _- f, a) I. m) w5 G4 t, q6 z        {1 r/ Q4 ~' W  O  y/ U& ?# r% `: x
            KEY = 0x0c;. P+ v% H4 Y$ v. u. x! {
        }; y9 n5 z0 n& X
        while(!OK);! M0 q1 a" m0 S# i6 @- j
    }$ u5 _$ u" U# v* @9 D, e$ G, l+ E9 B( m
}
! X8 ]* c: p. S. O2 g( v( y/ S/ f
4 a+ X7 \  B, w+ I5 T  g

7 E, {7 t% P$ O; p" H. Ivoid main()
& H7 Z1 i& q* X6 V9 w1 i{" @% n  M: p- a% M+ O
    LSA = 0;9 O1 r8 g0 D5 Q; ~$ X  [
    LSB = 0;, D5 I2 H7 C' d# C
    LSC = 0;4 K- M0 L# ~% m  h2 D2 D6 |
    while(1)+ I9 @7 p5 i, E4 v# k
    {   
) }+ b/ D+ V% F4 ^1 h9 G* h' Z* T        Keyscan_duli();
6 W, `6 r" C1 @% M% V5 x9 v        Keyscan();        2 l+ p/ P1 @/ f5 i* w$ M/ V$ x
        GPIO_DIG = smgduan[KEY];
: _1 j- z' J) Z    }
: H2 e$ a( q. ?+ Z}

点评

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

该用户从未签到

9#
 楼主| 发表于 2019-3-21 10:33 | 只看该作者
kinidrily 发表于 2019-3-21 10:26" A( R  l' n. G) h# k1 t* y
全局变量KEY在Keyscan_duli();程序中获取的值被下一条语句KEY = Keyscan();覆盖掉了。改成这样看看:#inclu ...
" R: M! q& x4 S* R+ V( I
这样就可以了,这是为啥啊( ^4 y9 y& v8 K+ F' U

点评

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

该用户从未签到

10#
发表于 2019-3-21 11:21 | 只看该作者
小黄豆 发表于 2019-3-21 10:33  z7 m9 p- b3 Z' j/ A; Z, p5 y
这样就可以了,这是为啥啊

9 H6 l; |$ p+ n7 e, D这是因为全局变量KEY在独立键盘扫描程序Keyscan_duli();中获得的值会被矩阵键盘扫描程序KEY = Keyscan();改写。我把矩阵键盘扫描程序中的局部变量KEY注释掉,也取消返回值,这样两个键盘扫描程序共用全局变量KEY,在主程序中分别调用两个键盘扫描程序,谁有操作就显示谁的键值。
4 v9 O4 D! c. l" k: T9 D
; C$ b  c$ g9 X* r) t

点评

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

该用户从未签到

11#
 楼主| 发表于 2019-3-21 11:26 | 只看该作者
kinidrily 发表于 2019-3-21 11:21
5 ]: w" P, ]3 V+ }3 f1 Z这是因为全局变量KEY在独立键盘扫描程序Keyscan_duli();中获得的值会被矩阵键盘扫描程序KEY = Keyscan(); ...

; U" f4 X2 c: W& Q% B' U哦 明白了 谢谢7 X# m5 U0 B) F; l

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-6-23 04:14 , Processed in 0.093750 second(s), 33 queries , Gzip On.

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

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

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