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

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

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

    [LV.1]初来乍到

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

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

    [LV.1]初来乍到

    2#
    发表于 2022-2-15 10:11 | 只看该作者
    不是那两个函数的问题,是你用它们的问题吧?   3 t" R- Q/ M$ o# U
    case 2: //SW1开始连加触发      : h7 d; ^  J* d6 A0 @: T( l
               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-10-9 07:17 , Processed in 0.140625 second(s), 23 queries , Gzip On.

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

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

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