TA的每日心情 | 开心 2022-1-24 15:10 |
---|
签到天数: 1 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
最近在做单片机独立按键长按连加,短按加1的功能,网上找了很多例子,都不是很满意,试了很多都不成功。最后找了一个很多人在用的代码,不知道什么原因,在我这边总是无法实现功能,搞了好几天都不能解决,修修改改无数次,实在是没思路了。以下是这部分代码,希望大神赐教!6 ?. J0 M+ ~! b A- R# B. d
# a% E. X _ t
现在的主要问题是:
3 u; @7 i! q3 ? T8 k: q1,只能实现短按一次的功能,即数码管显示0时,短按一下可以增加到1,再按就没反应了。% m8 J) d7 G9 u0 e: `
2,应该是KEY_SCAN() 和KEY_PROCESS()这两个函数的问题,但是找了好久,改了很多也没解决问题,现在没有思路了。按键扫描函数KEY_SCAN()是在网上找的朱兆琪学习板的程序,我用的单片机是AVR的,在我上面怎么都用不了,不知道啥问题,不知道是程序问题还是硬件问题,感觉硬件没啥问题,换另一种写法就没问题,但是如下写法总是不行。1 Y4 ]' X' K+ |) K$ i( |
. v( }: s' f* T0 X) F% `, K% j1 e' \单片机源程序如下:7 h3 r9 }! j* m- F* K9 Y
unsigned char key_number=0; //触发的按键编号, D2 T# @% P- N4 X7 A0 Q C! B. z, w
unsigned short key_time_delay_cnt_SW1 =0; // SW1 按键去抖动计数器( Z5 P1 G7 }7 L% O$ F- D& ~) ]
unsigned char key_lock_SW1=0; // SW1 自锁变量
" Q& \4 t0 P5 u- d) ?unsigned short key_cont_trigg_cnt_SW1 =0; //SW1连加计数器
# _/ {8 w& P% t* t( T$ n8 v% ]6 S$ P$ i y/ X: g/ @
$ l2 `5 Y* a0 ]3 ^4 Aunsigned short key_start_cnt1 =0; //中断启动计数器标志位- N$ _# \$ C8 y
unsigned short key_start_cnt2 =0;
! k# g6 U3 `5 z _9 z p% J5 y" ?0 C$ [unsigned short key_start_trigg_cnt1 =0;
4 t: k( `7 q' G1 Junsigned short key_start_trigg_cnt2 =0;
4 B2 h4 t: A* v1 _; O
( \9 v# l* Y9 f6 V" d0 J6 j* B! M! T: Y- s! J# p
4 `. x' {. w U# y. M+ h. y
# @2 i: r3 W! F+ {- B$ auint8_t KEY_SCAN(void); // 按键扫描函数& t- N0 q1 S; P6 L, r2 [
void KEY_PROCESS(uint8_t); //按键处理函数( ~+ I9 M$ q& `8 p
/ j Q; N- ?7 Y
6 r0 ]& Y6 I9 D+ [5 y
, I3 D% Q. J) G+ a' d1 ], _int main(void)! k: {) F" p! ?) Y9 ~( E
$ Y, E5 R% J" H U+ o1 z{; h, e+ c% j1 N$ `# \% N
KEY_PROCESS(P_min_set_temp_ON); //P_min_set_temp_ON在数码管上显示分和秒7 O t# s( ?7 C
}
8 G K2 |3 C8 k9 [' w5 z- j8 |( W& s$ a. ^+ [ ^; v
! u: x6 F$ w: r0 a1 m
" d/ K$ w) E5 A1 l% R) w' ~
uint8_t KEY_SCAN(void) ~% d: H) k: R7 |8 O. Q% C @2 f
. ^" l/ z; `$ I7 j2 M
{4 \% k" M) @# E$ D
// 扫描SW1" m. x" ?# d/ v3 ^5 Z8 P
if (1==KEY_SW1) //按键没有被按下(高电平),清零标志位
( H! `$ s d o1 @' B# X' L8 V {
' X$ W; N' F" g9 _& D7 W0 S key_lock_SW1 =0; //自锁标志位清零
0 p8 p3 H0 Q3 B4 I. n! D key_time_delay_cnt_SW1=0; //去抖延时清零
( U0 g- S! E C% g- g: } key_start_cnt1=0; //在中断中启动计数* g0 q8 d% ?2 P2 n: t' _% T( f
key_cont_trigg_cnt_SW1 =0;
- N- i6 X: C& L/ l5 B( i3 @ key_start_trigg_cnt1=0; //在中断中启动计数
+ K4 | n: S+ r7 p) G }- ^4 H6 ]( Z% O
$ n8 Z' L$ L% V' N$ T x. b
else if (0==key_lock_SW1) //如果有按键按下,且是第一次按下6 K5 W$ t1 R( y( p
{2 ]% \, u! H, e% k# u: @2 a
key_start_cnt1=1; //中断中启动计数器,key_time_delay_cnt_SW1开始自加% |0 O( Z' S: q" p3 F' Q& n3 R
if (key_time_delay_cnt_SW1 > KEY_TIME_DELAY_SW1) //自加到10mms去抖动,KEY_TIME_DELAY_SW1为进入中断10次,约10ms
' u- i6 c3 t, D% | {5 u$ \4 S; X0 G, u( \
key_time_delay_cnt_SW1 =0;
/ x) c& H3 q6 _1 F- M+ C% | key_start_cnt1=0;- [9 \9 O: a2 A" l4 Z
key_lock_SW1=1;$ u7 B% j r( a+ T
key_number=1; //触发 一次SW1单次触发,如果松手,立即返回到if (KEY_SW1)
* D! x8 P: i H: K% K$ T$ ~
3 `; C# w9 ^$ D. [9 K' P }1 V1 U; Z2 o( v. p. ]- w
}
5 q& Z. B/ ^! t: ^
, [0 r h6 p, w0 S3 x else if (key_time_delay_cnt_SW1 < KEY_TIME_ALWAYS_PRESS) //如果按住不放, 在1s内自加,KEY_TIME_ALWAYS_PRESS为1s
5 R3 y3 A+ m! Q8 k3 y: v {
% C: ~) h* q q' _4 W6 S0 ]& F7 ] key_start_cnt1=1; 7 L, _7 D. i: x* o
}
8 i3 a- u! B2 S z! J: ^ ' C# k Z* P# I8 a
else //持续按住大于1s时,进入连加状态
; w# E: B6 N) I5 R {
1 E2 f% {; ]- r* ]) N% L key_start_trigg_cnt1=1; //启动key_cont_trigg_cnt_SW1自加7 Y' A- K. ]1 H+ r% b
if (key_cont_trigg_cnt_SW1 > KEY_TIME_SEQ_INTER) //自加到250ms后,清零,KEY_TIME_SEQ_INTER为250ms, r7 ?" t+ G" i0 _8 S" v8 J
{. ]* `0 a2 A' s# {" w
key_cont_trigg_cnt_SW1 =0;$ C$ j: Q/ {, ], \" S# ]: @
key_start_trigg_cnt2=0;; J# c4 l5 h! H0 b" O$ H9 [
key_number =2; //触发SW1连续触发,实现长按SW1超过1s, 产生每250ms触发一次按键的效果. L( O) O9 j- c6 V3 b
' R* T/ Y/ S) A S" `( ]4 N }2 ]; Y$ d3 S; ?- |
}
9 e% L, ?9 \" ~* u& G* `4 B; f1 \6 f( W' z, G& v! |
return key_number; //返回按键编号值
0 e/ P* o# t" U# y8 z* s! J. H( z K0 b# d. _7 l+ v
}
! n4 j9 h+ h3 |3 @% K, L
5 ?2 @; Z9 k- N% R" S( K1 Z% v! R4 Y. J. z; j0 i
void KEY_PROCESS (uint8_t min_sec_set_temp), |1 o6 _, o8 s+ N, @7 E+ e% R7 Z
- e/ ~8 X6 g4 @: C) o, s7 f& [2 ?{ $ I# ]0 c" {6 C8 q( z' q4 O6 u
KEY= KEY_SCAN(); //根据返回的按键编号值处理
/ K! v4 r# U' T switch (KEY)
! ]& i5 l2 R! Q {8 g2 T( m n& m" T- {& x/ \$ _
case 1: // SW1 单次触发
3 W) C- {. F9 ]5 `0 l min_sec_set_temp ++;+ f( V% f/ U% o3 n# x4 r/ p
if (min_sec_set_temp >99) ) ~0 w1 I; N' C7 k- q
{% U1 ^/ d+ N3 r
min_sec_set_temp=0;9 I5 u7 G; Q2 B) w* O
}. \, f2 u1 w$ ^8 X( l
//key_number=0;4 S' }, g4 `3 l6 ^6 T$ Z9 w8 O" H
) O8 ~( \' _' s* ^* M' `! | break;2 x* T N! g( y7 F2 k
* F, v$ d2 s t" ` f; t1 M, a* i+ r case 2: //SW1开始连加触发. b/ ~2 R" `- u" i1 j3 d$ {
min_sec_set_temp --;6 y. s8 B% F0 A) A2 {! c5 W
if (min_sec_set_temp >99)8 W" R5 u* `+ d% h
{. l, b- R8 b' a9 D( p
min_sec_set_temp=99;$ l+ K3 l3 _- t {
}; Z p5 B, k, s6 D( P. c9 A# D
9 T9 B2 a- i/ H4 b& C
break;3 Z, c8 i' s( |+ C
5 h' R8 @0 r4 z0 d* k4 k3 w % t h+ |" I- X" Y T! d; |. @) r `
default: ; break;+ _& _" {) D% r" M* [* x
}
! ^1 s# F) R$ Z- q7 d
+ Z# T2 O6 g6 B7 k+ `) T min_decade=min_sec_set_temp /10; //数码管显示' j( k; \! b, k* f" Y) p
min_the_uint=min_sec_set_temp %10;4 t/ A! N+ A% S ~
sec_decade=min_sec_set_temp /10;
3 y9 {! i `, `- ^+ w0 m sec_the_uint=min_sec_set_temp %10;5 E. _7 K8 V; v5 _6 r1 W
- c# t( {) _ p. n3 X, i5 T8 w! q
% A7 x1 @6 i4 m. u& ]
DISPLAY_TIME_SET_MIN_SEC(1); //数码管显示函数,通过按键加减数字可以显示出来 * x; z E1 J4 l& }+ I' e
}: q% D) _1 @# q) A& P) X; X
+ g1 [, J/ [( V4 Q2 q4 `7 I
8 d( _! ^4 P# c: W' h3 H( A* u5 k! y# F1 m" c
8 E5 p& ^' P2 A$ c/ X
: k+ j2 m6 f- K6 M: ?$ C* ]ISR(TIMER1_OVF_vect) //中断服务程序, 8M/256分频,1ms进一次中断
5 m! g. O4 l {6 l1 a7 w! y0 R& B; P8 {4 s! q1 P
{+ o: m" R) g9 x' X% `( ?. e
TIFR1 =0x01; //中断标志置位
9 |* W* r( S% [0 r8 x2 i' {! F( ? TIMSK1 =0x00; //关中断
: k) R! c- y7 j0 Z! X( P/ W$ K
$ p/ ^) n' U- o7 {. D; h if (key_start_cnt1==1): O2 Q7 {$ r0 D' `8 s9 t8 q+ `
{8 W; V" Y2 Z& n
key_time_delay_cnt_SW1 ++;
; t! d4 Y; Y! R" A+ t+ w3 N }, J3 C! j/ U; t* O: p# }
6 b* @; `6 b1 E$ h7 @
else
" m8 y4 H' I/ M3 I/ ^, ?* ^ {
4 A' V, N. s( N& K5 I7 I key_time_delay_cnt_SW1=0;
8 P0 e2 P; N/ | }
) T: s% p' Y0 G) \3 M# D
) ~1 s9 t: W5 h$ ^ if (key_start_cnt2==1)7 r+ O, N3 N/ J. D2 T$ h
{( M: T0 V( N% x6 s9 J7 L r+ o
key_time_delay_cnt_SW2++;7 d2 U E) [- i: Y1 {0 @5 [
}/ q k8 h5 ?: L% [6 U
else
: [# k# a& N) I: z( m {
' e" ~) C! V8 c, R b( S key_time_delay_cnt_SW2=0;; N- z! ? f! [& T! p: |
}
' S7 O/ {8 Q' U; ]' G
6 R) l% J+ G2 i' l* E j if (key_start_trigg_cnt1==1)4 O) Q$ R3 Y: q. f* c$ Z% c
{/ y# e- y }* ?+ {9 m+ l
key_cont_trigg_cnt_SW1 ++;. \$ m, n1 c7 x$ F. ?) M; n
}' N0 X- L9 l$ J/ K9 O! U
else
3 W$ d' y' ] p' a# l0 B" \ {% _$ i- H6 ?8 C ^* Z
key_cont_trigg_cnt_SW1=0;' G2 Q6 }9 Q/ b& M3 J5 G& s. M
}
1 D' ^: z! _) h: A+ v ' n2 y" y/ |) Y6 M9 H
if (key_start_trigg_cnt2==1)9 F: q1 U! F2 V1 D
{
3 |' z( H; Z" j: I- Z) I key_cont_trigg_cnt_SW2 ++;
; W3 Y4 T" C% T5 K) b% } }
" s- C/ o4 U# z7 N+ v else
$ z! }5 H, Z$ X1 R {
. J$ V% B l2 t9 P; G% {: X0 \4 p key_cont_trigg_cnt_SW2=0;9 V+ O7 h9 U" |+ o6 N9 z$ \
}3 L' M. q( o) U! Z2 U! N! [
/ O4 |! \3 a t' E5 H
. e3 V0 {( `; { y4 `6 n+ e6 Z E" R3 ~
TCNT1H =0xFF; //计数器重装初值高八位
9 j% R! R- K& C TCNT1L =0xE0; //计数器重装初值低八位 / R8 e r5 o0 i2 v9 Q& G
TIMSK1=0x01; //开中断
! M) S, _+ i# b9 W}( Q. p" @: v/ Q$ x/ Z
|
|