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

单片机独立按键短按加1,长按连加总是无法实现,问题在哪?

[复制链接]
  • TA的每日心情
    开心
    2022-1-24 15:10
  • 签到天数: 1 天

    [LV.1]初来乍到

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

    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
  • TA的每日心情
    开心
    2022-1-29 15:04
  • 签到天数: 1 天

    [LV.1]初来乍到

    2#
    发表于 2022-2-15 10:11 | 只看该作者
    不是那两个函数的问题,是你用它们的问题吧?     a: m% Y0 F1 y) {) z
    case 2: //SW1开始连加触发      & D7 {& a* g1 Q) G( H( v5 Y6 f
               min_sec_set_temp --; //为啥用--呢?明明是++的。

    该用户从未签到

    3#
    发表于 2022-2-15 13:30 | 只看该作者
    用状态机不难吧就一个短按状态和长按状态,外加一个无按下时的状态
  • TA的每日心情
    开心
    2022-1-29 15:04
  • 签到天数: 1 天

    [LV.1]初来乍到

    4#
    发表于 2022-2-15 15:37 | 只看该作者
    局部静态变量static了解一下
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-8-11 19:55 , Processed in 0.109375 second(s), 23 queries , Gzip On.

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

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

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