TA的每日心情 | 开心 2022-1-24 15:10 |
---|
签到天数: 1 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
最近在做单片机独立按键长按连加,短按加1的功能,网上找了很多例子,都不是很满意,试了很多都不成功。最后找了一个很多人在用的代码,不知道什么原因,在我这边总是无法实现功能,搞了好几天都不能解决,修修改改无数次,实在是没思路了。以下是这部分代码,希望大神赐教!' w1 K3 q! H8 b$ Z
2 e# T* D! A U3 U. v
现在的主要问题是:2 J2 v7 h7 c3 }3 Z; d
1,只能实现短按一次的功能,即数码管显示0时,短按一下可以增加到1,再按就没反应了。
4 a r' U' H* X* @2,应该是KEY_SCAN() 和KEY_PROCESS()这两个函数的问题,但是找了好久,改了很多也没解决问题,现在没有思路了。按键扫描函数KEY_SCAN()是在网上找的朱兆琪学习板的程序,我用的单片机是AVR的,在我上面怎么都用不了,不知道啥问题,不知道是程序问题还是硬件问题,感觉硬件没啥问题,换另一种写法就没问题,但是如下写法总是不行。1 n& z/ P3 _/ e$ z
* x9 m8 Q4 |5 y- ]单片机源程序如下:3 {3 m$ A* y* {- x! m
unsigned char key_number=0; //触发的按键编号
0 S" J3 M+ q4 g. lunsigned short key_time_delay_cnt_SW1 =0; // SW1 按键去抖动计数器
/ X; l% {) g, y1 `unsigned char key_lock_SW1=0; // SW1 自锁变量
7 I% U# z% J% O: n9 {unsigned short key_cont_trigg_cnt_SW1 =0; //SW1连加计数器0 U% D/ p# M" P+ S& O' a
d3 g/ T; O+ e
, I/ H/ V$ i# U, dunsigned short key_start_cnt1 =0; //中断启动计数器标志位+ z+ p1 c6 q3 k Q1 A- Y' s
unsigned short key_start_cnt2 =0;! U3 b7 g! Q- _' \' i: O, \! ^
unsigned short key_start_trigg_cnt1 =0;; @6 G8 d6 X0 N4 H$ q
unsigned short key_start_trigg_cnt2 =0;5 V8 q' b+ q, Q6 }" m |+ }
1 Z0 C: ]5 h, \/ J I2 X M* A; O# H5 [$ o- k9 {1 I2 d
# W1 R0 H1 |$ q1 g
. m- s/ x( W: r/ X7 r# nuint8_t KEY_SCAN(void); // 按键扫描函数* i6 W* @$ k# y# \1 e H
void KEY_PROCESS(uint8_t); //按键处理函数8 E6 W' f8 @$ I9 F( d; T
/ i6 @1 y, I8 a3 F- u# M
( p, A/ Q: K( s& W* f' Z+ m, l& L
int main(void)
* Y1 H: j, ~% f) Q. `1 ?! N+ b6 B' W3 Q1 P
{4 X3 l5 V) Z( C: d' m) X# [8 n) u; |
KEY_PROCESS(P_min_set_temp_ON); //P_min_set_temp_ON在数码管上显示分和秒
# b. F1 |2 K. f2 e* w+ L; @}
+ J5 I& k- A( z' \2 m. z7 u4 ^. z* F
* |0 K9 S9 m6 x" c
1 |7 V* F3 T/ {- G8 I. iuint8_t KEY_SCAN(void)
$ @1 I9 b j% L3 g, m! }
/ ^& p. s2 o& C{
' ?; Z7 r. u2 L/ c ~# t7 ]& b5 l // 扫描SW1
! b H- n* H3 p( N if (1==KEY_SW1) //按键没有被按下(高电平),清零标志位
, |; K) r0 h4 h' I1 r {
; \7 l& d. o% {! {8 m G: W key_lock_SW1 =0; //自锁标志位清零4 ^2 w$ }" Q2 j: M$ ]
key_time_delay_cnt_SW1=0; //去抖延时清零0 t" C8 @* E( `
key_start_cnt1=0; //在中断中启动计数% \+ }4 C' `! B& [) e
key_cont_trigg_cnt_SW1 =0;# @% Y9 X( g* p3 J5 M4 F
key_start_trigg_cnt1=0; //在中断中启动计数
% v' E- d! I R7 L! G& d$ |7 b }
- w: ? F7 t' d3 L8 T; E ; l1 r( x9 z# C
else if (0==key_lock_SW1) //如果有按键按下,且是第一次按下
" }- ?& k: f% g9 x, p {
2 x3 X' V* g' A7 n. H key_start_cnt1=1; //中断中启动计数器,key_time_delay_cnt_SW1开始自加
5 [! g& J( G4 O- @8 z( ?2 o/ ^) V8 ~ if (key_time_delay_cnt_SW1 > KEY_TIME_DELAY_SW1) //自加到10mms去抖动,KEY_TIME_DELAY_SW1为进入中断10次,约10ms6 _4 c4 `, I& x; O. j( Y$ l
{
H2 s* ~% D' D* f/ V: l+ y key_time_delay_cnt_SW1 =0;
' o) k' M0 m5 L key_start_cnt1=0;+ q0 V8 J4 m, a- c& s
key_lock_SW1=1;
, g5 g5 j' V5 G) l% x key_number=1; //触发 一次SW1单次触发,如果松手,立即返回到if (KEY_SW1)7 i/ `' E' r; r2 x# F/ Q
% @( M# }0 N1 ^8 A( s }
% S6 q, u7 _. s* X( v$ Z }
; }" P/ t* l S7 J2 L$ C' r
3 i W: b q) S5 f else if (key_time_delay_cnt_SW1 < KEY_TIME_ALWAYS_PRESS) //如果按住不放, 在1s内自加,KEY_TIME_ALWAYS_PRESS为1s
, x; J0 F$ h, x2 X3 U a. { {/ b- p. Z8 s- T8 @
key_start_cnt1=1;
2 W1 F8 k( X/ Y/ q6 ~0 }7 v }0 Q/ s- B. T1 y% ]& v/ @
2 \' w! B G& n, z: T1 n5 E5 L/ k
else //持续按住大于1s时,进入连加状态
& c8 m1 N2 y# d9 F- k, R6 a {* `. r+ h1 Z1 Z
key_start_trigg_cnt1=1; //启动key_cont_trigg_cnt_SW1自加. Q' L/ H) |7 Q5 d
if (key_cont_trigg_cnt_SW1 > KEY_TIME_SEQ_INTER) //自加到250ms后,清零,KEY_TIME_SEQ_INTER为250ms
; Z* H8 p" h7 v7 a {: P+ s8 L( F, c V% t! |6 ^' o: {
key_cont_trigg_cnt_SW1 =0;
9 w: |' z1 { M" L key_start_trigg_cnt2=0;5 i/ k, c& ]. O' u0 q1 w/ ~
key_number =2; //触发SW1连续触发,实现长按SW1超过1s, 产生每250ms触发一次按键的效果
+ V- z- J6 {9 u% U : Q" Z' z1 e, z2 _; d
}4 k* U9 a) e2 I* g r9 l' E
}
5 W% L2 u3 E# U( H, I5 p6 Q* ^) J& S j3 ]( T
return key_number; //返回按键编号值 r9 k% `4 v+ C' Q! \
9 E1 m R5 u7 m" v) W) \* Z
}
% c+ Y4 ~" q, |8 A- ` `) W( q- @* k
0 K4 q6 {( P# ^' G) q" D, d- l0 ^" G; u m3 f u( i& }
void KEY_PROCESS (uint8_t min_sec_set_temp)
! \& r8 N; J( o' a
5 p) T% l/ B, j2 f( z{ . M+ M9 t. x3 x V( N) S; U
KEY= KEY_SCAN(); //根据返回的按键编号值处理
, k$ l7 }5 u1 u1 I) F+ d switch (KEY)
- S+ ?! E% ?: e: M* g- o {
) |: v4 x% E( f" T/ N case 1: // SW1 单次触发& X& [* e4 u+ W
min_sec_set_temp ++;. P, Y, w- G; I. y8 W
if (min_sec_set_temp >99)
+ k# G% O S: m, m8 A% k2 Q {& F7 L/ L- S7 B7 i- I. i" f
min_sec_set_temp=0;
2 M& L- n1 \5 b" r1 ?# o0 U& d }0 ?4 E8 D2 Q* L0 \) x0 b* y) ~
//key_number=0;* C. x1 n1 R7 q; z# |1 }! H
9 m; ^. X9 A$ F5 t6 V break;
" U" e& J6 f: x2 Z% x. `1 ?8 T: f
* C: E- Y: O4 D7 s case 2: //SW1开始连加触发
: X1 c4 H/ b8 \4 |" H6 U" r! [; J min_sec_set_temp --;4 ~- U6 |; E: n' Q- p3 k2 g
if (min_sec_set_temp >99)
2 e4 `1 }2 V- g9 \) A& H! c9 A {+ z# J% k k2 x
min_sec_set_temp=99;3 k9 t- J" q, d$ V2 l6 l
}
7 y0 @! [$ U' D/ E6 }7 {
% o% k4 R5 x9 N: K break;
$ b* @" w' D3 E
3 h) S$ N |+ y# U
# x+ A6 R+ r, _) z default: ; break;
" F0 U+ z5 ~; ~& y& z5 F% ? } ?* R) u5 D$ v. A
2 _( C% B0 P, O' g
min_decade=min_sec_set_temp /10; //数码管显示# ~5 g$ X0 \3 d6 n9 w5 M( b7 ~" w
min_the_uint=min_sec_set_temp %10;9 m2 R. P- e1 x- G7 ]" {! u
sec_decade=min_sec_set_temp /10;9 c7 h* J3 @ ~( S' i" E
sec_the_uint=min_sec_set_temp %10;
, F* ^. [: y9 p$ s # s7 t& c; U/ @
" a3 M" N: P1 M& Q DISPLAY_TIME_SET_MIN_SEC(1); //数码管显示函数,通过按键加减数字可以显示出来 ' F- I$ W Y5 g I Z: m1 a" Z
}
- ], w! V) }+ m/ e! I/ a( S4 D4 U l* `) t# N
6 h7 k: K2 q" ^- E, b* g
9 W8 [6 ?3 U" X+ k
5 m, y: p% t' c, A0 [
* Z+ [) G+ ` i
ISR(TIMER1_OVF_vect) //中断服务程序, 8M/256分频,1ms进一次中断
# L1 @( y- U# @3 d5 h% ~
" F' h- e3 y- O4 v {
/ B* e: o- Z3 v! Q+ T TIFR1 =0x01; //中断标志置位
K# r6 A, u2 l+ W+ N- w3 L1 U TIMSK1 =0x00; //关中断
' d( T- D2 U; X& R" K ; E$ y/ z3 T y
if (key_start_cnt1==1)- G1 E' o+ `+ w9 h- j: ]
{
) P/ A6 u8 J+ R7 H( z- L key_time_delay_cnt_SW1 ++;
5 u' c( J8 [4 V/ S6 k: e [5 s: l }
7 s5 {6 Q' ?9 [+ f) z- v0 e0 r
0 K5 w8 n4 d% k+ E else" a8 I' I7 o* t9 r
{( `6 _) Z' K/ |$ ^
key_time_delay_cnt_SW1=0;/ M: d9 P1 O- M
}
' |2 T% v, B# @+ i
7 V9 A3 Y) @, h3 X6 b0 l if (key_start_cnt2==1)
& O) m* b: y7 l8 p; Q6 ~ {" o! U! h# d* f! t/ C
key_time_delay_cnt_SW2++;
+ l, a! a: K# t }
$ P0 {3 U$ K& R+ ]8 w) t' N else
( p$ X8 i$ i$ D( E8 { {1 G# v# `/ ~9 D4 w
key_time_delay_cnt_SW2=0;+ h$ i; c x8 g" S& r6 L* T+ R: e5 R
}& j7 [8 E9 k# L0 K6 f8 B
9 J6 |" w3 N2 d2 X2 C if (key_start_trigg_cnt1==1)( Y; K) m+ N0 N8 R2 M+ z# R
{; j1 t' }3 W* E# R
key_cont_trigg_cnt_SW1 ++;) F' M2 q! u" R; O
}
+ U+ d N( P7 v else
2 Y( T4 [# K" y3 J7 o: W& h& P {
2 n c+ I8 U3 O& T* z' j key_cont_trigg_cnt_SW1=0;
. }3 u& ^- A8 }$ [8 i1 B3 ?" I }
. X, ?7 W/ o6 ^" ^! `9 S0 M
$ I& J; w# N3 E3 w if (key_start_trigg_cnt2==1)- _% \6 \6 ~0 A8 Q
{0 c5 d2 y, @" C
key_cont_trigg_cnt_SW2 ++;
( B) e i# }0 r7 ~5 D }
$ ^ u0 v Q& B else
" R+ x* g6 x7 Y4 K5 I0 ?' G {% z- j6 j3 P4 Z7 e
key_cont_trigg_cnt_SW2=0;8 B3 G5 J* l; R: a" D
} `! p: N$ X3 n7 a; u" K
" w$ K" _' z: ]1 m: X! A
8 f7 U# U& M/ v) Q( Y: `6 ?; p TCNT1H =0xFF; //计数器重装初值高八位) Y% i9 n: h. b
TCNT1L =0xE0; //计数器重装初值低八位
9 u/ ~5 ~( j+ B# ~' q4 I TIMSK1=0x01; //开中断
: p+ B& e1 z9 @! c3 ]6 L: V7 D}( {5 T6 ~. z" a$ Y
|
|