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

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

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

    [LV.1]初来乍到

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

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

    [LV.1]初来乍到

    2#
    发表于 2022-2-15 10:11 | 只看该作者
    不是那两个函数的问题,是你用它们的问题吧?   
    , f* c( [; k+ R& l3 Ccase 2: //SW1开始连加触发      
    ' l2 G+ L' d3 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-7-18 08:14 , Processed in 0.125000 second(s), 23 queries , Gzip On.

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

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

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