TA的每日心情 | 开心 2022-1-24 15:10 |
---|
签到天数: 1 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
最近在做单片机独立按键长按连加,短按加1的功能,网上找了很多例子,都不是很满意,试了很多都不成功。最后找了一个很多人在用的代码,不知道什么原因,在我这边总是无法实现功能,搞了好几天都不能解决,修修改改无数次,实在是没思路了。以下是这部分代码,希望大神赐教!
9 W: H" b) ]3 W1 f f; W1 c, y, R4 S
3 T5 M+ l$ X. _0 b) q/ m现在的主要问题是:
A2 p( S, g" z: q) x1,只能实现短按一次的功能,即数码管显示0时,短按一下可以增加到1,再按就没反应了。4 K! j1 C r! }7 r$ K9 @0 z
2,应该是KEY_SCAN() 和KEY_PROCESS()这两个函数的问题,但是找了好久,改了很多也没解决问题,现在没有思路了。按键扫描函数KEY_SCAN()是在网上找的朱兆琪学习板的程序,我用的单片机是AVR的,在我上面怎么都用不了,不知道啥问题,不知道是程序问题还是硬件问题,感觉硬件没啥问题,换另一种写法就没问题,但是如下写法总是不行。
, L- r7 _. N! K7 G7 e8 L' C
7 I# P" X" c. d2 F" K单片机源程序如下:$ ^& f4 i' i* P2 b
unsigned char key_number=0; //触发的按键编号
6 i$ L# `0 E- `( E$ Lunsigned short key_time_delay_cnt_SW1 =0; // SW1 按键去抖动计数器
9 \- Z' P3 v2 _1 F: i- dunsigned char key_lock_SW1=0; // SW1 自锁变量# _( q4 U6 U0 i" \; d, a
unsigned short key_cont_trigg_cnt_SW1 =0; //SW1连加计数器3 o$ y+ i" m: Q
! Z6 @! ?* L; ~; x
# @# D$ V% @2 A; _; |; R" nunsigned short key_start_cnt1 =0; //中断启动计数器标志位
2 b. s* R" b ounsigned short key_start_cnt2 =0;9 Z8 X' U) I# P$ o& J
unsigned short key_start_trigg_cnt1 =0;4 x% m7 {( K1 E' P
unsigned short key_start_trigg_cnt2 =0;, i+ _5 i _ B7 e& [
1 ^5 O) H0 q* D% _0 a% E0 ?; a; v( h* ?3 ~- l) V9 a4 q0 |1 u
4 }2 V ?' j; n$ V, j: P) A; m5 j3 I" f: Y( w
uint8_t KEY_SCAN(void); // 按键扫描函数, c# b, ~) O$ c# j3 ?' }- c
void KEY_PROCESS(uint8_t); //按键处理函数 J/ z- T' B& I7 m6 D; \- q; c
: h: [/ ?3 v4 v0 _8 Z: ~0 j6 Z
- t( [5 u: ?4 C8 e! r4 f. [* T( T0 T% s# f
int main(void)
0 X6 b. B/ ]) m5 P" a, I) o6 O. w% I
{8 _1 [3 E+ s" b9 x2 ~. w
KEY_PROCESS(P_min_set_temp_ON); //P_min_set_temp_ON在数码管上显示分和秒' A7 x; S: P8 ]8 y
}1 T1 B+ S1 \6 L8 k
7 T& ?0 P0 c$ e" L- R
, }9 O! u) u* z, j6 g4 Z/ Q. m3 n9 R4 I. G$ D c1 F* H
uint8_t KEY_SCAN(void)
# b2 B/ L0 y, A0 V0 Q, v" v
/ H/ O" \4 ^7 b{
- U# x3 k: z4 i# b& g // 扫描SW1
! q6 o+ t+ R) g5 Y! ^2 T& [ if (1==KEY_SW1) //按键没有被按下(高电平),清零标志位
3 D& ?+ @4 Z+ p7 e {8 ^8 X* ^" b$ O$ {) M3 n' n
key_lock_SW1 =0; //自锁标志位清零3 X0 l2 q* r6 K/ g3 ] A
key_time_delay_cnt_SW1=0; //去抖延时清零: G2 S7 ?8 q$ N( \ p6 L
key_start_cnt1=0; //在中断中启动计数
' i' X& t$ N) e6 L key_cont_trigg_cnt_SW1 =0;
- d* G: t4 @0 a& ^1 g: F key_start_trigg_cnt1=0; //在中断中启动计数
2 g2 A$ N$ M2 k, S3 S7 ^ t }
, [9 e& `/ a8 M' A9 U0 ?
1 S0 a0 L& G( p, E else if (0==key_lock_SW1) //如果有按键按下,且是第一次按下
2 L2 U c9 D3 V8 P {' B8 x& g2 r( L1 [
key_start_cnt1=1; //中断中启动计数器,key_time_delay_cnt_SW1开始自加$ r3 _ D5 h: Z4 o
if (key_time_delay_cnt_SW1 > KEY_TIME_DELAY_SW1) //自加到10mms去抖动,KEY_TIME_DELAY_SW1为进入中断10次,约10ms
$ d$ i! W+ R! m" v; v1 B {) y) n4 q: A- }
key_time_delay_cnt_SW1 =0;$ t0 m9 {0 n2 I4 v& x
key_start_cnt1=0;0 o" d; V6 d% p- s& f4 q# z
key_lock_SW1=1;
! }/ z$ H& D6 Y ^ key_number=1; //触发 一次SW1单次触发,如果松手,立即返回到if (KEY_SW1)$ \: R) j" O2 {- r) x" g
6 L% O9 V6 v# X% H3 ~7 m b
}/ l/ ?# G& y8 E. j0 b
}
0 U# Q- d0 G9 ^1 b3 O9 W& j& O5 G; L& k
else if (key_time_delay_cnt_SW1 < KEY_TIME_ALWAYS_PRESS) //如果按住不放, 在1s内自加,KEY_TIME_ALWAYS_PRESS为1s& w+ t8 u6 T) G3 s3 X
{
# i" P# [* V6 h9 q key_start_cnt1=1; 7 D$ N$ [3 t, ]3 i' K
}
+ o. Z8 C$ h% ~7 r ( H6 B. B2 p, w9 E+ E+ r
else //持续按住大于1s时,进入连加状态3 L* c' t ?$ z( {
{
; t- F$ V3 e* y: T: u8 M key_start_trigg_cnt1=1; //启动key_cont_trigg_cnt_SW1自加( |) [+ a. e% O
if (key_cont_trigg_cnt_SW1 > KEY_TIME_SEQ_INTER) //自加到250ms后,清零,KEY_TIME_SEQ_INTER为250ms0 Y" m% N, |0 T _! d
{
1 l2 x8 u* ]4 i- U2 | key_cont_trigg_cnt_SW1 =0;7 i8 A O9 W' }, w9 u
key_start_trigg_cnt2=0;, o x$ e/ M1 Z% {1 s
key_number =2; //触发SW1连续触发,实现长按SW1超过1s, 产生每250ms触发一次按键的效果2 c G3 E) W. M) K& v8 R
- s) T& Z/ T$ e/ }7 t! r
}9 R9 h) b* J. A8 `# f9 ?; y8 q& D2 G
}3 _2 O. y- M6 i v: C
7 J8 l; F0 ^5 Q, W6 j1 S
return key_number; //返回按键编号值1 M! C7 c, v' u4 o: |, {8 S
3 s( p$ o3 t- u9 L6 K$ P}
& G8 |) T! t3 t$ X- [
( L }4 l, @" l3 C+ {. B
. v3 O( L2 ]9 c( j* [$ j* h4 F, q0 ~7 x) Mvoid KEY_PROCESS (uint8_t min_sec_set_temp)
/ I$ A/ I0 G- m1 R
) u% A1 C& O$ I6 z3 T{
# P3 x4 ]; j9 {5 e KEY= KEY_SCAN(); //根据返回的按键编号值处理/ U0 ^4 E. B+ B- \
switch (KEY): i: a& ?$ f2 [; A+ ~' V/ D7 V: O
{6 v% r# U! y5 H( R: O
case 1: // SW1 单次触发
2 O% f$ j% X, I0 h+ S& N min_sec_set_temp ++;
3 V) ]- Y, u0 }/ \) v* i% F7 M if (min_sec_set_temp >99) + X& h5 p0 y' I9 ]1 P, K
{
: M' x6 j9 H" O, o min_sec_set_temp=0;* t1 Z/ H" ?& X
}
# l8 W. A( @; Z- l$ A: E6 H //key_number=0;# V, k8 ]% \. N, v
& q: ?5 F5 v' X, H break;
4 ]( Z/ a$ W3 |4 {7 X
! M7 i2 k. L/ c) X" P# P case 2: //SW1开始连加触发
& y+ R( _9 k7 ]; i min_sec_set_temp --;
s' @+ J7 Q! h& j2 n7 y0 h if (min_sec_set_temp >99)8 `) V* {6 P5 m' d
{8 Q$ |2 {4 \: W% f
min_sec_set_temp=99;
N& M1 y8 h5 X6 y* t) Q& I }. P5 @' | P7 m( ]
7 A) E' g, L) o z break;
8 r6 @5 W# |; a% i4 w8 E
7 D- R, F) |! b- H 6 M& S2 ^- A+ w8 `/ \( P- s
default: ; break;' t s, S( N# e- x$ ^
}
: P$ L" `( K$ g( U9 ~2 A 1 L8 M( ]& M2 w$ @/ w1 L
min_decade=min_sec_set_temp /10; //数码管显示
, C! }2 i$ r y6 H! a, ~- q min_the_uint=min_sec_set_temp %10;
) E4 Q2 ]5 o* G sec_decade=min_sec_set_temp /10;& l' V1 C8 J! t; w, S9 f
sec_the_uint=min_sec_set_temp %10;' M) Z$ W3 Q& O' ^% L3 ~0 ?
* y/ k0 @1 q5 p. j) ~
& J, t4 g1 s0 s( p( x5 i2 u DISPLAY_TIME_SET_MIN_SEC(1); //数码管显示函数,通过按键加减数字可以显示出来
3 x6 c, p! W2 [6 s' S" A1 t}
& S v- z3 G9 a
( W1 k$ o2 g8 C& ?& s 5 O+ z6 g1 w# x
8 L( K6 g- N1 x+ H1 _9 B; c u- P0 v; k8 L
3 e) }: U7 F6 [( e, E# [3 l
ISR(TIMER1_OVF_vect) //中断服务程序, 8M/256分频,1ms进一次中断
& ] b' w/ f5 \5 m+ e! a# o p) t1 W7 f* N
{9 h' \: \ g ?7 m, n: g
TIFR1 =0x01; //中断标志置位
- O- Q k3 ?, d+ v/ ^0 E2 \9 f& I TIMSK1 =0x00; //关中断/ c, O. b9 G5 {. F( p' _# A
+ U5 @% S" x# g, E$ O) s( }5 e if (key_start_cnt1==1); ~! F- k5 W5 ]* \ a- N( [- F
{
6 c. X! |) Z7 e* `5 Y key_time_delay_cnt_SW1 ++;, K/ d+ `: T) v9 P! g
}
! B( N6 n2 L) O/ E9 z ( H: f3 S6 u, S2 H# X3 m I- n! d
else
2 x P/ r9 u* k7 S1 F+ A8 h$ D; V {7 G0 s7 M% T& F& W6 C4 _
key_time_delay_cnt_SW1=0;, T( K) z; [ b( q& N3 w( H
}+ |5 \0 [ z. u/ Y
, [! l) x$ |& K2 c
if (key_start_cnt2==1)( i. `3 ^; B6 Y( s1 L7 t; s
{
; ^3 @9 o, _* {5 X key_time_delay_cnt_SW2++;0 @& M k( D$ @3 ~+ Z: c% T
}( G6 T6 d5 A4 a, w# G1 o! {8 G$ L
else( k4 _) F8 L, v9 O6 @
{
) Q5 t. v m. p key_time_delay_cnt_SW2=0;
6 b, g1 Q7 X S7 [- V }
% P1 W. g4 {9 ]( f2 w, f3 c
1 Q) ?6 m7 v0 j if (key_start_trigg_cnt1==1)
% y9 U3 I Y1 e" [# Y; p# J {6 G4 N6 J! g4 D1 G: y
key_cont_trigg_cnt_SW1 ++;
5 g3 l$ H( U& U K0 T }
$ D7 L9 W1 @) F- r5 ~7 q! I# q3 o8 O else R2 E. ~; N; e
{
- b/ Q' Q7 \2 q% ?% t9 b key_cont_trigg_cnt_SW1=0;' W! W( Q. K: y2 A1 {/ Q) g
}
6 w0 C& `. H1 c' c
9 V( J7 Q6 t+ N, `; n if (key_start_trigg_cnt2==1)
# M# ?1 M# @+ }( n) R1 h$ Z6 ~* ? {8 ~+ C0 Z a/ I" T P5 b4 a
key_cont_trigg_cnt_SW2 ++;
1 M" e6 x. ]: S }9 H9 b, k A- p$ j. z9 t. w
else
! M5 L0 T% J/ Q; Z {$ {/ Z$ A0 |/ l4 D$ R
key_cont_trigg_cnt_SW2=0;
2 K9 B6 P# U8 b, @) J }0 L. Q. M+ B m% U7 M% |2 g, f
; V/ X0 R' K7 e& `9 J( s7 z; b
# T& y% z* n3 H, | TCNT1H =0xFF; //计数器重装初值高八位
' k R' Z8 b% r6 B) n$ a TCNT1L =0xE0; //计数器重装初值低八位
& b" N- n. g% N- _- F TIMSK1=0x01; //开中断* j- @, K+ Q5 p* Q! u4 a
}
+ I) d4 e+ s: M5 C. V) F |
|