TA的每日心情 | 开心 2022-1-24 15:10 |
---|
签到天数: 1 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
最近在做单片机独立按键长按连加,短按加1的功能,网上找了很多例子,都不是很满意,试了很多都不成功。最后找了一个很多人在用的代码,不知道什么原因,在我这边总是无法实现功能,搞了好几天都不能解决,修修改改无数次,实在是没思路了。以下是这部分代码,希望大神赐教!
. x: @1 w. C( W- \, B3 x1 M2 K. }* W0 K/ f9 I8 Y) t
现在的主要问题是:
) d3 Z1 I; _- o1 k1,只能实现短按一次的功能,即数码管显示0时,短按一下可以增加到1,再按就没反应了。
8 s4 _/ W7 `. g( S; T) O- H2,应该是KEY_SCAN() 和KEY_PROCESS()这两个函数的问题,但是找了好久,改了很多也没解决问题,现在没有思路了。按键扫描函数KEY_SCAN()是在网上找的朱兆琪学习板的程序,我用的单片机是AVR的,在我上面怎么都用不了,不知道啥问题,不知道是程序问题还是硬件问题,感觉硬件没啥问题,换另一种写法就没问题,但是如下写法总是不行。
% p( a0 f8 j8 }+ \% k' i# n' }
w: N S- X( ]: b8 L单片机源程序如下:& Q# C3 g! w3 K" }% b3 @. I
unsigned char key_number=0; //触发的按键编号9 A% ?# A5 W* r% x
unsigned short key_time_delay_cnt_SW1 =0; // SW1 按键去抖动计数器
0 U+ D4 a2 p$ `8 q8 ~unsigned char key_lock_SW1=0; // SW1 自锁变量
; [- L7 m7 ~. W* p8 Xunsigned short key_cont_trigg_cnt_SW1 =0; //SW1连加计数器
( q# f0 R/ H* T
3 e* W/ O4 U4 W4 y) Y) h
' ^4 o& g% j% [unsigned short key_start_cnt1 =0; //中断启动计数器标志位
: Q; Y9 o7 {6 ?8 Z5 I3 p1 g Cunsigned short key_start_cnt2 =0;
! T9 W( _' q% e9 R- F0 ounsigned short key_start_trigg_cnt1 =0;: D; Q3 b9 u% c, z; w1 j
unsigned short key_start_trigg_cnt2 =0;& Y: w+ X7 I* v) y' r" g
% p/ T# b" m# T9 E% T. j
6 C/ M+ { n# c- g: G
" V' E& O3 Y6 f/ h. v$ d8 l+ s
- L+ Q p, r! O$ H& c8 Fuint8_t KEY_SCAN(void); // 按键扫描函数% R/ a1 }2 C( _/ l1 v4 k B3 L; Q
void KEY_PROCESS(uint8_t); //按键处理函数: K4 O7 A0 c9 `/ B3 X
2 I, z" e* \6 u' x1 `0 a/ { T
7 S7 V( f! @1 A! [& a# I% x9 [8 w) p+ `: R, y: b# P- T
int main(void)
* X! s+ }$ i" E4 ^% c' S' r
* ?, x$ U) i S{" s' Q4 y' i) V9 @) m1 D5 {& _
KEY_PROCESS(P_min_set_temp_ON); //P_min_set_temp_ON在数码管上显示分和秒
9 c7 l2 }7 K1 x- ^) V4 z8 Y# \6 z}
1 F9 l# o* n2 G0 i$ Q
- Z0 z% Y7 a& M# N0 M' M- t- F' P+ i/ [, P6 S6 c( F. T+ A/ A
c9 @$ }8 ?5 V. a. ^1 p8 ~' Xuint8_t KEY_SCAN(void)
, O% V8 o0 z H" Y0 O) Y
V) T3 B# e$ {+ D3 X; j6 F{: _8 W' y! q4 D- K" `
// 扫描SW1* y& g% j: ^' e5 S
if (1==KEY_SW1) //按键没有被按下(高电平),清零标志位; P8 U! j0 `4 l: |' {
{
* E! ^" ~" j2 b$ b$ c8 l key_lock_SW1 =0; //自锁标志位清零, j! k! Y4 X3 W: O) T, X7 z0 k
key_time_delay_cnt_SW1=0; //去抖延时清零
0 z% ^, m9 _( _# n* W% J key_start_cnt1=0; //在中断中启动计数
& X) b# m% Z, C, u: H key_cont_trigg_cnt_SW1 =0;7 D- ^- s9 U3 {1 K: R. u
key_start_trigg_cnt1=0; //在中断中启动计数. y' D4 u5 \; X9 A
}8 D2 t9 I' o) M. S( }+ M
# e+ E8 r$ Z( U$ A
else if (0==key_lock_SW1) //如果有按键按下,且是第一次按下
' M5 w9 ?2 _) W+ v: t {
9 i) E+ \+ `6 e+ W( }! o* o key_start_cnt1=1; //中断中启动计数器,key_time_delay_cnt_SW1开始自加
- ^; t9 v0 g* r7 D) y+ | if (key_time_delay_cnt_SW1 > KEY_TIME_DELAY_SW1) //自加到10mms去抖动,KEY_TIME_DELAY_SW1为进入中断10次,约10ms
& w* B8 s0 o4 v+ g- S' H5 @, X {
. r; a/ F0 K4 z key_time_delay_cnt_SW1 =0;
7 W. C/ k. t$ {: r& H! Q key_start_cnt1=0;
9 ^% ?: K' e/ S/ p key_lock_SW1=1;2 [, y2 |" P; P! R1 y1 c* d5 H
key_number=1; //触发 一次SW1单次触发,如果松手,立即返回到if (KEY_SW1)& N( `! C- Q( C( J5 A4 A5 u
+ q8 v- P4 r L# A" X. H }
* o; l6 X! l5 X) I, @ M5 v/ ^( r }
) @: \ v& j- T) N8 J" i- z
$ i3 V7 J$ w2 l6 _/ u/ c7 s( Q else if (key_time_delay_cnt_SW1 < KEY_TIME_ALWAYS_PRESS) //如果按住不放, 在1s内自加,KEY_TIME_ALWAYS_PRESS为1s
# R6 P, Q3 h9 S, s, x {
8 a0 _$ ^6 }2 Y* ]/ Z7 Q# y key_start_cnt1=1; P) @/ V1 j2 l2 ^: r
}( ]% |: N8 W3 A
/ L& Q7 L: f+ F* s( Z* X
else //持续按住大于1s时,进入连加状态
& }& V& c% o& h8 Z {
$ r6 I8 F% y. O: [ key_start_trigg_cnt1=1; //启动key_cont_trigg_cnt_SW1自加6 b& E" L6 s- g: `- ^- H& M
if (key_cont_trigg_cnt_SW1 > KEY_TIME_SEQ_INTER) //自加到250ms后,清零,KEY_TIME_SEQ_INTER为250ms+ \7 i* m i! e) F' o
{3 d! w' u; i( \! \: G& Q; W, O" G# N) y
key_cont_trigg_cnt_SW1 =0;* }( M# H! o& Y" d/ V; ?2 e
key_start_trigg_cnt2=0;
( M! D- ^$ V% \' E5 c( Z key_number =2; //触发SW1连续触发,实现长按SW1超过1s, 产生每250ms触发一次按键的效果
9 e, g1 N$ ?( t% j4 i: Z/ {
9 Y% |# P) E7 B& w$ Q6 v }
4 G' P( V! l. Y; n: d9 `9 [( C }
$ Q. i5 J% |& q6 K8 Q+ Z
$ G, U& W/ n0 _3 [# Y+ v" Q; a return key_number; //返回按键编号值+ I7 w: X0 r' t( r
, a: g) w) k. m: T [/ m3 D}
9 u6 Q1 P) |1 N1 o1 |8 Q5 X# l* y) F( P; E. }* I
0 Z6 a, B9 W+ S- j( E; k O
void KEY_PROCESS (uint8_t min_sec_set_temp)
) ^. ]& J9 V, J: I- d O; ~0 k
' g9 v8 S4 h! o1 {{
! E- Z* c5 s& H: v9 s) g KEY= KEY_SCAN(); //根据返回的按键编号值处理
! c/ B6 V# k- @& P& O switch (KEY)0 T6 \( {! x5 I( _0 R
{
8 U, x( P5 V, x case 1: // SW1 单次触发1 l1 S% u' K' y+ y
min_sec_set_temp ++;
; V* Z+ p( \; G* i- p8 v if (min_sec_set_temp >99)
% i) \& K9 b* z% n2 s {1 [* p* O, }- u; u6 s
min_sec_set_temp=0;
: T7 }) K! p4 {& [( ^5 f }
' H2 L; \1 f0 f" ~. n i% o //key_number=0;' ?. R+ }% \/ \# A) C) Q7 d: P3 Y( _
% x/ @. [# y3 ?1 S' U
break;
9 a2 e/ c- I: n- e3 D . @9 B( `- I# L; z' J2 j4 e$ K+ }- W# V
case 2: //SW1开始连加触发 ]# D/ D4 z2 u4 H8 i
min_sec_set_temp --;+ I; M, C6 w$ b3 C
if (min_sec_set_temp >99)
; w4 n" b4 w, S9 V {
( Z4 l( r, d" }6 v4 p' ] A b min_sec_set_temp=99;
. P* z; F8 j. R7 J, T }, T$ ^; y' J( }
; V; I9 Z7 b' Q! _& u* Y break;
8 [0 a) z7 a) ^8 o. N V3 a
! b# N4 x' }) ^; ]/ n2 @1 H2 i : q; C2 D# \4 |0 ~/ L
default: ; break;0 O1 i$ O+ ?$ Y
}
5 c9 q7 W( C) ?( G5 ^+ I) |& o8 B - @1 g9 a* f; @% ]% x: ~6 b0 t
min_decade=min_sec_set_temp /10; //数码管显示. P" B- I3 W/ ~+ b8 X3 M
min_the_uint=min_sec_set_temp %10;. @% M; `6 T) f1 d
sec_decade=min_sec_set_temp /10;3 {1 |$ r( T) k' H$ K4 ?6 J7 l
sec_the_uint=min_sec_set_temp %10;
p" ^, |9 Q+ u! b
/ y8 y' d1 @" E! @4 V+ E5 _5 W
5 Y4 g& b3 y7 t7 ]! O$ t DISPLAY_TIME_SET_MIN_SEC(1); //数码管显示函数,通过按键加减数字可以显示出来
! W7 T0 z. ]6 y, ~5 N* K9 q- ^- d}+ Z1 y( W6 w$ v$ S0 _; G/ h
$ J$ ~3 E R6 D9 M2 M# ?
x% g% ~* @4 P
4 ]- O: \! f; o9 r8 E
8 m/ A$ P( i% K6 i9 m( W- G- V+ q
ISR(TIMER1_OVF_vect) //中断服务程序, 8M/256分频,1ms进一次中断
9 n6 ~& u5 b, B. q+ o7 x$ W/ g& s) T* @8 y; I7 G$ Z" R
{' y( |9 i$ }( {7 n8 w! _7 {
TIFR1 =0x01; //中断标志置位
0 e# u+ O0 k0 v* V. _# d TIMSK1 =0x00; //关中断
. A. I" P& ]# z; D& j, w! |( f , F* p, U: J" S$ e, t
if (key_start_cnt1==1)
: ?' v- f( j& e( t8 y6 C {
* d7 z) `. J! D key_time_delay_cnt_SW1 ++;
. {9 @% u5 J3 h& o% V! T* f }
% y# W( N2 x# W5 Q, i1 H \
3 _4 K d2 E+ Q6 f# v# w0 K else
+ Q( W! ?# m/ l0 q' [* d4 t {8 Y: h, @' N6 D3 w. U% D0 j
key_time_delay_cnt_SW1=0;* c- \- }5 @ v$ Z: V$ A
}6 I' t) G- n1 S, [+ f
' l" e: o* h+ X0 V/ t if (key_start_cnt2==1)
7 s' K0 i2 Q( P {# h6 K. A3 Q/ t; r
key_time_delay_cnt_SW2++;
& c0 L7 {% t! Z0 w4 t }
0 G! u8 j( ^3 I% Y: w( b else7 ^: @% ~5 a/ u
{, Y+ `3 v& ?, k
key_time_delay_cnt_SW2=0;9 C! `+ F. h& |# m) }' C; x
}
: _$ M- ]' ?0 F* p5 r# E 8 F4 o' A0 Y9 X1 V
if (key_start_trigg_cnt1==1)
2 Y- Z; ^, k+ m, ]! j8 }" w" N {
5 \1 s2 ~4 r& R6 ]4 k key_cont_trigg_cnt_SW1 ++;- q3 g+ Y! t4 E0 I
}0 a# Y w y% x4 x4 v* M
else
2 v) f8 g, u6 i! k {# k' M' z% ^6 m& q1 h3 D' ?; u
key_cont_trigg_cnt_SW1=0;
! u' |7 m; Z, ^; }2 E9 R# w }
, F5 o ~3 Q+ Y3 X+ s
?7 c. M7 m( Q4 |+ n+ x if (key_start_trigg_cnt2==1)
- [7 `' \& T8 s1 e$ [3 e {
. z5 B% S1 @9 Z" V2 `5 Y key_cont_trigg_cnt_SW2 ++;
7 U$ F! s$ A: T4 t/ L6 x2 o }
}5 f3 e1 j0 S7 F& F+ a else, L+ |- t* e: J1 l1 v/ x
{0 }' Y- O7 a4 {6 r& L% Q
key_cont_trigg_cnt_SW2=0;
5 C% i. Z( h( O9 a/ A }$ N9 K6 [8 D! S0 ?- m
# {3 v. o0 Y( @) Q' A m& O
, {* d! i m- u8 r- p
TCNT1H =0xFF; //计数器重装初值高八位
! {7 x) l2 M8 n TCNT1L =0xE0; //计数器重装初值低八位 6 G. L7 n x3 m- c! T: u
TIMSK1=0x01; //开中断2 h' {4 Z% M! \3 C! v/ p6 R
}3 m5 S. {# Q/ k( H. I. b) k
|
|