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

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

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

    [LV.1]初来乍到

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

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

    [LV.1]初来乍到

    2#
    发表于 2022-2-15 10:11 | 只看该作者
    不是那两个函数的问题,是你用它们的问题吧?   
    ) r) N, M+ p4 G+ X' f$ Ycase 2: //SW1开始连加触发      ' I% W* M/ z5 N+ Q# d( y
               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-6-19 14:58 , Processed in 0.093750 second(s), 23 queries , Gzip On.

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

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

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