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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
单片机独立键盘与矩阵键盘的问题
9 O: @& a, w6 S( U8 ~4 h. z
, a( W. k7 e& |
, H2 R, j/ K" P$ v
#include <reg52.h>, h# {: a8 ?! t, h: D

: i& [/ b. w+ O  \& w. ?#define GPIO_KEY P1 //矩阵键盘的接口
0 v! d+ P. J6 E6 \  @  g1 C4 u#define GPIO_DIG P0
% e  _" B! e  p7 ]7 c2 w$ |typedef unsigned char u8;
1 }' q, B+ ^3 H7 K+ Gu8 KEY;
1 z" a7 D4 c! zsbit SM = P3^1;   //输入密码按键8 m8 x' Z; m, a- b
sbit GM = P3^0;   //修改密码按键1 S" g% c: d+ {# \, Z) G6 b" i) X
sbit OK = P3^2;   //确认键
$ D5 d- V# x; k6 H$ bsbit LSA = P2^2;
  }" H; q( f+ C2 E* zsbit LSB = P2^3;0 {. d) D# k, Y3 C" E" X- u! i
sbit LSC = P2^4;
3 U! @8 @' P) Z# l4 ~8 |1 ?+ b( p; l, H, Y+ z$ _5 O* l
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
& L$ F! K+ f/ n4 N                                         0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
2 [2 i- s% B* Q, g" [
9 ]9 h! u2 ~8 E7 D% Avoid delay_ms(unsigned int x)
; l3 N, e! q1 n{: ^; a2 j  s% S; M, c. O
   unsigned int i,j;! h' S9 H0 r0 s  b; R, n
        for(i = 0;i < x; i++)- g- \. D0 K7 }! V% s: G' j% P
                for(j = 0; j < 110; j++);" L! f0 p3 N# H  P- A' c0 l2 B
}: g8 n: k$ A: ^% ^' Z2 v8 O

# q; K6 D0 h# Ru8 Keyscan()
9 o/ Z8 Q* K; ?% I3 w{/ x2 g3 ~% ~) v2 H3 x4 @8 X5 f# Q( Z/ n
    char a = 0;# H! J, Q5 T) I- a! p" T9 a5 X
    u8 KEY;0 z; G  S) u, f2 Q. |, g
    GPIO_KEY = 0x0f;
! k3 |7 A8 H" ?3 ]; ~1 k3 u! i/ Z    if(GPIO_KEY != 0x0f) //判断按键是否有按下( B$ R- v+ z& e2 U
    {
2 T7 }- \) H7 p- h" q0 |        delay_ms(10);   //延时去抖( Y, i) v. U5 K
        if(GPIO_KEY != 0x0f)  //再次判断是否有按下
' P* r' F3 N& S9 d8 L        {* `6 I% F' U+ R6 ]
            //扫描列, S+ z& c- ~& H" R# n1 c$ N8 |  e; Y
            GPIO_KEY = 0x0f;4 r, F  |. t# z6 G2 d
            switch(GPIO_KEY)4 n! @! \6 D4 \% |3 I0 E
            {
3 s4 n/ y+ @7 }: j  _! ]$ @                case(0x07):KEY = 0;break;) n2 a6 E5 c# [) j" B8 v
                case(0x0b):KEY = 1;break;& a* c/ D, [+ j
                case(0x0d):KEY = 2;break;
' i; @; D% _* y" Q4 \                case(0x0e):KEY = 3;break;: f2 @( Z. v, c7 X
            } : `, x' `7 e* P; {
            //扫描行- N$ H$ ]  d) p/ w$ X6 C
            GPIO_KEY = 0xf0;
% y" G( A- S$ k( p# ~0 M            switch(GPIO_KEY)
$ e) q; v+ N, U& _. G3 ?1 d            {
! K* Y1 |) m# N                case(0x70):KEY = KEY;break;4 m6 m1 e8 w$ s* g: c
                case(0xb0):KEY = KEY+4;break;/ h$ H* ?- A7 h: [4 ^% x
                case(0xd0):KEY = KEY+8;break;1 Z1 {) `. n* H2 n# {
                case(0xe0):KEY = KEY+12;break;' D  X& D  j6 ?) U' ^' C
            }
+ ^. A2 \- c, h4 a. \; @            while((a<50) && (GPIO_KEY != 0xf0)) //按键松开检查: Z# e) f4 q# q2 A3 T# Q
            {
5 J2 [3 [1 g) w                delay_ms(10);2 U: }& e9 c4 m% o3 d7 h
                a++;
6 H7 G9 O, K# k  s! A" Z            }
, I0 b% U9 l2 Q$ s            return KEY;   ( {! P# s  {% Z' Z/ o; i! B
        }
4 z! K4 ~7 H+ U    }
+ b# ^& j2 Z, h' [* I! b' h}
( C/ l% c% k& b6 o0 \
& F6 i' h! @. R9 j% wvoid Keyscan_duli()" l2 e: I$ n2 e" L/ W
{& D, U# a( U. r7 |- j
    if(GM == 0)
% a+ }0 ?; w/ k    {* a. x/ n5 O$ U3 }) ]
        delay_ms(10);! C6 p1 a+ C5 y1 F  \( J
        if(GM == 0)
" X  B& p8 ]3 G+ M# `' j. n        {
2 l2 K+ Y4 B0 D9 F1 z5 I/ o            KEY = 0x0b;7 k. X+ ^+ d0 }/ M, J# D( {; B
        }
5 d6 `; \7 x) U3 z  h6 ^! a' S        while(!GM);
$ P9 O% Z* I5 x' K# L0 Q0 k    }/ z4 W3 R% m- Y$ h  J9 i6 p
    else if(SM == 0)
; C/ v2 j1 r8 `9 l* F$ t    {2 o; C8 J, n6 U/ r- a! @' ]
        delay_ms(10);% k5 a- O; n' N6 l
        if(SM == 0)
: x$ W) I; c/ m6 C7 t( Q9 F' f5 R        {! w3 O# T. Y" r1 Y$ S( ]
            KEY = 0x0a;6 i) [0 |$ l- j1 R2 k! P3 X
        }( c  l7 ]. O* A7 H: t7 t; e- E
        while(!SM);
7 E2 I$ F. U9 X  F& [9 c) g8 s    }; N, Q& F8 M$ t7 X& j. H) w. a
    else if(OK == 0)* y+ \) n, t2 v  l- X
    {
0 ~% c. r5 \0 X9 B6 @" ]# k        delay_ms(10);8 u& u7 Y, U( W  n
        if(OK == 0)4 J8 D3 \* y1 k0 c, S
        {0 z$ e- M- x  q* X( G; z- R* m
            KEY = 0x0c;
/ J9 k  |; A! A        }
+ D! S0 d& T: x4 v" \/ [6 t        while(!OK);
" M5 p! U) l$ ]* `8 l    }
8 d2 @: c2 P+ d7 ^}
/ D4 A4 k) i* N3 G& T4 v
+ F7 \5 e: D0 R) J  {$ t' G( O* I

+ L) [; y* [4 g. j# Fvoid main()' P8 }3 m! j6 y& h$ v
{9 j; a" r4 D8 v: H. D* ^
    LSA = 0;9 f0 Q4 H& ?  x5 ~  ]  g1 s9 [
    LSB = 0;% i  z* O. x5 {
    LSC = 0;
& i. \: J; d: I( P" O    while(1), ^  i! {- @$ T: R  ]4 ^# v! P
    {   
; {# b; x  q* Q3 l4 C        Keyscan_duli();
' D3 I  ~' o! C! H        KEY = Keyscan();        
- ~/ m& Z, Q- \/ W/ e        GPIO_DIG = smgduan[KEY];
% x6 R6 `* s* i  K) t    }/ ~& {( c" N1 D8 @7 c# x5 }
}) N# c. M+ I: p) F7 l& N
6 m2 `6 E# W' N& e0 W

8 a" t9 @+ ?- m4 Q想问下各位大佬,为什么不管按GM、SM、OK键数码管都显示A,而如果只有独立键盘扫描函数,即把主函数中的KEY=Keyscan()注释掉,按GM、SM、OK键就能分别显示A、B、C。. b$ j. N( H/ P3 R5 n/ D

该用户从未签到

2#
发表于 2019-3-21 10:01 | 只看该作者
Keyscan_duli();$ _/ U" t6 u0 W5 Y& Z
        KEY = Keyscan(); 7 |( x, n8 S0 V- d5 O$ c
这两个函数都是修改同一个变量KEY,Keyscan_duli();是在函数内部修改,Keyscan();是执行完后返回给KEY,这样的话,执行完Keyscan_duli();后,不管KEY是什么值,再执行完Keyscan(); 就被修改了。1 s9 e  U/ @" a9 M6 K( ~1 r  k  s
应该用两个不同的变量,或者用不同的按键码值

点评

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

该用户从未签到

3#
 楼主| 发表于 2019-3-21 10:04 | 只看该作者
relchhiclty 发表于 2019-3-21 10:01
$ Z9 l; Q8 W4 x2 b! x+ yKeyscan_duli();
% L4 ~/ r8 J% q8 X        KEY = Keyscan();
$ @5 O. }3 H) j  F这两个函数都是修改同一个变量KEY,Keyscan_duli();是在函数 ...
& t1 a! ~, U+ J/ S
那显示时不就有两个变量名
5 k1 D. T( l9 n. K& f

点评

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

该用户从未签到

4#
发表于 2019-3-21 10:06 | 只看该作者
小黄豆 发表于 2019-3-21 10:04/ N$ J: m1 r7 g4 B. L* w  j5 a
那显示时不就有两个变量名

# ?5 ]( p  T* q不想有两个变量名,两个函数调用次序对调一下,先键盘矩阵,然后再是独立键盘
/ U* Z5 H& w- N+ X! G' y6 m/ i3 p

点评

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

该用户从未签到

5#
 楼主| 发表于 2019-3-21 10:19 | 只看该作者
relchhiclty 发表于 2019-3-21 10:068 w8 u- O9 t0 @/ y% G+ m4 {
不想有两个变量名,两个函数调用次序对调一下,先键盘矩阵,然后再是独立键盘

7 b- n5 y( K9 q5 o3 {还是不行. ]* D! m: d+ ]

该用户从未签到

6#
发表于 2019-3-21 10:20 | 只看该作者
矩阵按键扫描函数错了。。。- W; G# t8 D6 F2 X8 A. |) A
//扫描列# s. G  I% n: j( S; p/ |. T5 z4 Q
            GPIO_KEY = 0x0f;
% t1 F1 C' \' t( I' X8 u            switch(GPIO_KEY)
/ C' E- q; Y# Z! Q            {
- v) t; M2 i! O  s5 q                case(0x07):KEY = 0;break;9 g8 t! Q9 `1 t! B6 r7 h4 X! O1 U
                case(0x0b):KEY = 1;break;; l0 n4 q, ?+ d2 |, |* ?5 F
                case(0x0d):KEY = 2;break;
/ F4 e7 H+ P$ V                case(0x0e):KEY = 3;break;* M; u" `8 L4 o
            }
  `& l, e( M$ }( [9 }  @  j            //扫描行
8 s. \1 s# ~8 }4 k) p5 Y4 _: \            GPIO_KEY = 0xf0;, p: ^0 `2 W; Q9 j
            switch(GPIO_KEY)6 K5 ^# q3 j! B  a( M+ k$ n
            {( B5 w* p9 @: Y5 L8 M5 x
                case(0x70):KEY = KEY;break;# J# V. Q! [  ~- i) H' m' n9 `* E- \
                case(0xb0):KEY = KEY+4;break;
" J; I; J6 ]; n- l% h2 _. t                case(0xd0):KEY = KEY+8;break;* o" X* E$ Y0 M
                case(0xe0):KEY = KEY+12;break;
% k9 r) u9 I1 T- P) b/ D            }
9 f; R& O1 {3 ~& A应该是&=吧??你直接赋值,case没有满足的!

点评

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

该用户从未签到

7#
 楼主| 发表于 2019-3-21 10:21 | 只看该作者
yxlk 发表于 2019-3-21 10:20
! K/ O2 K" N9 d* d- C/ r矩阵按键扫描函数错了。。。
5 M1 u( O6 h2 V( ~) o$ I//扫描列4 J9 g/ |! C3 L+ H8 ^
            GPIO_KEY = 0x0f;
3 f1 [1 _% D" _& y4 C0 ?: x1 K% T
单独使用没问题啊
2 z! A5 E" b: I" |7 D; m

该用户从未签到

8#
发表于 2019-3-21 10:26 | 只看该作者
全局变量KEY在Keyscan_duli();程序中获取的值被下一条语句KEY = Keyscan();覆盖掉了。改成这样看看:#include <reg52.h>
* D  [$ q  ], h* V
5 K* X9 v: R1 a  ~8 \" T8 {#define GPIO_KEY P1 //矩阵键盘的接口
3 I( B7 o; N' A8 |! E4 x. l3 z#define GPIO_DIG P0
6 S0 l. a& E* d& i" M) J* \typedef unsigned char u8;
. S( H5 N% C- f" M' C+ {u8 KEY;
$ t$ R; q6 U7 Z# S+ S" xsbit SM = P3^1;   //输入密码按键
4 V% w9 B0 U2 b- Y8 ksbit GM = P3^0;   //修改密码按键
# t8 r/ G5 C% Z1 t% Bsbit OK = P3^2;   //确认键8 Q/ B3 ?% A  _* Z" i2 |" k
sbit LSA = P2^2;  b) t* \9 w3 b7 N, n6 W/ T+ x
sbit LSB = P2^3;8 y4 F$ i2 Q- f6 X% w' V2 c9 _
sbit LSC = P2^4;
% y6 V1 A8 G7 C5 Y3 a
9 y8 S% X6 @3 x- X$ ?' g: Gu8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,& _3 ~( h1 x2 f
                                         0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
; D8 i: O" x8 P+ Q' o. f" L7 ^7 q( H  n' T" H5 i% x: {$ r/ i* A/ _
void delay_ms(unsigned int x)/ ~# w5 n! P' Z6 M) x
{# R! k* y5 l+ t7 d$ N. s) M
   unsigned int i,j;) }, q) x  E/ Y& f5 n
        for(i = 0;i < x; i++)
2 e" L# f# O  g, k                for(j = 0; j < 110; j++);
  {# F0 Y! o% s7 O6 ?- M& S6 C}( f3 Q3 |( J- G/ T+ Q5 N2 j# {

! I2 v# E  B- b. Q  z5 evoid  Keyscan()
  A! f; m) ]& ^{
& _9 r" p9 b  Y6 G; S" e: v& W    char a = 0;: ?$ K- h! @( P3 q& f2 Y/ b
//   u8 KEY;/ h( u5 S, v4 D8 `: A0 L+ y
    GPIO_KEY = 0x0f;
3 O" T! [3 ^4 r% U4 o: l$ \. [    if(GPIO_KEY != 0x0f) //判断按键是否有按下
8 h/ n5 M# S% ~& i2 H    {
) r6 u3 A% p0 l* L2 X: f% t' p        delay_ms(10);   //延时去抖% |# |0 g# \0 K# A2 z
        if(GPIO_KEY != 0x0f)  //再次判断是否有按下
/ B& c4 ?* U1 l& y  d5 b7 y        {- t% E0 K4 u1 _! g
            //扫描列' Y6 f8 W, P+ r5 N
            GPIO_KEY = 0x0f;
2 y& b0 H7 I  x6 Z$ f! o* k/ _            switch(GPIO_KEY)
7 z, |4 C4 P" @# k8 n" `            {
1 I# I6 M! j, P                case(0x07):KEY = 0;break;
- z6 e; _. f- ~6 x5 `                case(0x0b):KEY = 1;break;9 T2 ~$ g- C# g
                case(0x0d):KEY = 2;break;$ q7 L6 ^: N2 C$ \8 [
                case(0x0e):KEY = 3;break;
( S( q% ]- F9 L/ C            } ' Z2 k0 p! c  d- G6 d* w4 W
            //扫描行  j  `5 }' z: g+ R
            GPIO_KEY = 0xf0;
" i$ f+ H# }- ~. u1 R$ l4 t7 o! |            switch(GPIO_KEY)
" l. W2 b- S- h1 r, a            {
. ]$ U( k" U; x( W: x4 M, s5 {                case(0x70):KEY = KEY;break;
6 q# l& i5 s8 {                case(0xb0):KEY = KEY+4;break;: ]& b& G, `7 y0 @
                case(0xd0):KEY = KEY+8;break;" q- g5 G) c( G, s' y$ p) @, T2 i
                case(0xe0):KEY = KEY+12;break;5 f! [2 n  L/ ]% V: a; }
            }
; ~( o4 g( s. o' w6 |5 l& K. i3 C, u            while((a<50) && (GPIO_KEY != 0xf0)) //按键松开检查
3 ?2 T8 ?$ n  t            {
) A$ U& B  s4 C4 K" i" T                delay_ms(10);  v: u: L8 w  {& y+ H* R. R/ _0 h* C/ a
                a++;
3 k" Y& f; b1 S' e) ?            }! G# g8 B2 Q; m& \( I1 ~* J
//           return KEY;   ( z0 ]6 l1 G1 f+ a7 ?: H) e% l0 o+ F
        }8 `0 V2 M' k$ P; G3 h
    }
1 r. u% @8 @+ w% X) h6 A- C}2 h2 E2 P4 A" Y- g) ]) G2 D, C: @* P

+ G1 x% m; D  Y" i6 Dvoid Keyscan_duli()
7 o* P% @2 B/ @* @$ I{9 e- A& }. y" b+ S$ c  i' p$ P
    if(GM == 0)- L2 b. j+ p7 j7 r( c; I
    {2 B2 D7 m6 P( y1 H$ N2 o: {6 D+ T
        delay_ms(10);
- r" k/ c% ?$ }( I7 Z, l, W        if(GM == 0)
+ V* ^9 z; @/ y5 F2 x+ f: m        {
9 q: c' Y  G+ u$ u* [# Y            KEY = 0x0b;" Q9 _' t8 B( o5 i! d+ G
        }
1 d& y3 M3 S$ o; o        while(!GM);
/ r8 K. q7 Y1 @/ @6 l    }, ^! R# k$ O6 D. X% F1 V& x
    else if(SM == 0)
3 H- Q: @; j1 Z& G8 @4 c8 N) _    {! e# ~9 Z3 z) w7 n( R0 Z. q
        delay_ms(10);
& i/ T- e- A: X- d* x. S2 Q        if(SM == 0)  T3 \/ V  Y: V# l' S  H
        {. c" r$ ~: [5 R7 K7 c
            KEY = 0x0a;
' _0 i2 U& P4 ?8 C        }4 g$ b' G2 x7 O% k! L: f$ y1 p
        while(!SM);
5 G/ c: T2 R- b# {. e( g! N    }* m0 k" R) m! B0 e5 V
    else if(OK == 0)7 {1 x0 v& M& N  B+ P6 n
    {7 q- Z& ?  o- \/ B+ C; C
        delay_ms(10);
- a0 m) c7 `; @        if(OK == 0)
  [7 P# f0 t8 \$ m: c2 a9 ~: x        {& j: a6 H" I0 {3 M/ w8 ~8 c
            KEY = 0x0c;- T: Q$ ?; ?* |9 b" A
        }; e  j5 l& e* W
        while(!OK);
4 s( _* U4 ?* F! H/ U    }
0 {. `. J' \  ~/ ]9 H4 l0 o  W( r}4 \7 v: e: u' h
, {  |) f2 H& N# N# G9 c
9 z0 B5 ~8 G! M7 \0 l
; M3 W; T- w1 K. G3 S+ I
void main()
; S7 g" v) Q9 u* z6 u{
5 c/ ~* l9 h  U) G    LSA = 0;
/ {/ X. b0 w. z    LSB = 0;  L4 e! N2 C  I4 P
    LSC = 0;, n8 e0 V( M! g  |% h9 M8 g
    while(1)2 w! }' E' a! r: i  f: Q% X3 |
    {   
6 q8 d) _( m+ P2 W        Keyscan_duli();
- @8 {. h- @% ]/ w8 G) f        Keyscan();        
' R( V4 C, V7 {9 s  H        GPIO_DIG = smgduan[KEY];
6 o. q/ g7 m  i4 B7 N* S2 A% C7 Z    }; m+ u8 Q0 a1 O" ]9 [
}

点评

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

该用户从未签到

9#
 楼主| 发表于 2019-3-21 10:33 | 只看该作者
kinidrily 发表于 2019-3-21 10:26, M1 [9 W7 F( L7 v" j/ @( i
全局变量KEY在Keyscan_duli();程序中获取的值被下一条语句KEY = Keyscan();覆盖掉了。改成这样看看:#inclu ...
- k% O5 _+ @5 W, _! B  I) z# h$ ^
这样就可以了,这是为啥啊) r. V: K) J) j& r3 K; K* ]7 l

点评

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

该用户从未签到

10#
发表于 2019-3-21 11:21 | 只看该作者
小黄豆 发表于 2019-3-21 10:33
( k# a7 y: N: y9 V/ S这样就可以了,这是为啥啊
, D8 S& I* p# A% K& P5 C. F$ B
这是因为全局变量KEY在独立键盘扫描程序Keyscan_duli();中获得的值会被矩阵键盘扫描程序KEY = Keyscan();改写。我把矩阵键盘扫描程序中的局部变量KEY注释掉,也取消返回值,这样两个键盘扫描程序共用全局变量KEY,在主程序中分别调用两个键盘扫描程序,谁有操作就显示谁的键值。9 ^0 Y0 g% c" h# g* U

  q' p5 f5 _' Y0 w+ T

点评

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

该用户从未签到

11#
 楼主| 发表于 2019-3-21 11:26 | 只看该作者
kinidrily 发表于 2019-3-21 11:21
1 D9 x# M$ i% S0 _( ?5 O7 T这是因为全局变量KEY在独立键盘扫描程序Keyscan_duli();中获得的值会被矩阵键盘扫描程序KEY = Keyscan(); ...
, M. i, M/ D0 r1 [
哦 明白了 谢谢
" s3 c+ j. \) A8 B) X+ a

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-7-24 01:35 , Processed in 0.140625 second(s), 34 queries , Gzip On.

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

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

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