debouncing switches with a timer interrupt?


Closed Thread
Results 1 to 28 of 28

Hybrid View

  1. #1
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default

    When you exclusive-or "new" and "old" a resulting 1 bit indicates a change of state (either a new hi or new press, or a new lo or new release). You need to filter these "change" bits. If you AND the "change" bit with the "old" bit you filter out the "new press" bits and you're left with "new release" bits. If you AND the "change" bit with the "new" bit you filter out the "new release" bits and you're left with the "new press" bits.

    Hope this helps.

    Cheerful regards, Mike

    Code:
    '
    '  swnew  ____-----_____-----_____   new switch sample (positive logic)
    '  swold  _____-----_____-----____   switch state latch
    '  delta  ____-____-____-____-____   changes, press or release
    '  newhi  ____-_________-_________   new press bits
    '  newlo  _________-_________-____   new release bits
    '
        swnew = PortB                  ' sample active hi switches
        delta = swnew ^ swold          ' changes, press or release
        newhi = delta & swnew          ' get "new press" bits
        newlo = delta & swold          ' get "new release" bits
        swold = swnew                  ' update switch state latch
        IF newhi.4 = 1 THEN            ' 
          BTN_PLUS = 1                 '
        ENDIF

  2. #2
    Join Date
    Dec 2009
    Location
    Kalamazoo
    Posts
    42


    Did you find this post helpful? Yes | No

    Default

    that is just great. thanks for pointing me to the right direction, Mr Mike. its all fixed now.

    cheers
    NAG CON WIFE!
    WIFE VAR MOOD

  3. #3
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by DDDvvv View Post
    that is just great. thanks for pointing me to the right direction, Mr Mike. its all fixed now.

    cheers
    You're very welcome Sir.

    Please note that the previous example can be optimized a bit. Since you're using the "new press" state as the action state in your program you don't need the "newlo" variable and its assignment statement. You can also retask the "swnew" variable and eliminate the "newhi" variable. Some XOR trickery is used to update the "swold" switch state latch to the new PortB pattern.

    Code:
    '
    '  swnew  ____-----_____-----_____   new switch sample (positive logic)
    '  swold  _____-----_____-----____   switch state latch
    '  swnew  ____-____-____-____-____   changes, press or release
    '  swnew  ____-_________-_________   new press bits
    '
        swnew = PortB                  ' sample active hi switches
        swnew = swnew ^ swold          ' changes, press or release
        swold = swold ^ swnew          ' update switch state latch (swold = new PortB)
        swnew = swnew & swold          ' get "new press" bits
        IF swnew.4 = 1 THEN            ' if RB4 "new press"
          BTN_PLUS = 1                 ' set flag for main
        ENDIF
    With your 1-msec interrupt intervals you might consider adding a piezo speaker and code for "new press" beeps;
    Code:
    '
    '  beep task (32-msec 500-Hz beep using 1-msec interrupts)
    '
        IF beepctr > 0 THEN            ' if beep task running
          PortB = PortB ^ spkrpinmask  ' toggle piezo speaker pin
          beepctr = beepctr - 1        ' decrement beep msec counter
        ENDIF
    '
    '  swnew  ____-----_____-----_____   new switch sample (positive logic)
    '  swold  _____-----_____-----____   switch state latch
    '  swnew  ____-____-____-____-____   changes, press or release
    '  swnew  ____-_________-_________   new press bits
    '
        swnew = PortB                  ' sample active hi switches
        swnew = swnew ^ swold          ' changes, press or release
        swold = swold ^ swnew          ' update switch state latch (swold = new PortB)
        swnew = swnew & swold          ' get "new press" bits
        IF swnew.4 = 1 THEN            ' if RB4 "new press"
          BTN_PLUS = 1                 ' set flag for main and
          beepctr = 32                 ' task a new press beep
        ENDIF
    If you experience bounce problems with a 1-msec sampling interval you might consider adding a counter and executing the switch sample code at some interval between 16 and 32 msecs.

    BTW, assembly language "parallel switch state logic" is incredibly efficient (6 or 8 words);

    Code:
    ;
    ;  wreg  ___-----_____-----____   new switch sample (positive logic)
    ; swold  ____-----_____-----___   switch state latch
    ;  wreg  ___-____-____-____-___   changes, press or release
    ;  wreg  ___-_________-________   filter out new release bits
    ; flags  ___-----------________   toggle sw flags for main
    ;
            comf    PORTB,W         ; sample active lo switches
    ;       movf    PORTB,W         ; sample active hi switches
            andlw   b'11110000'     ; on RB7..RB4 pins
            xorwf   swold,W         ; changes, press or release
            xorwf   swold,F         ; update switch state latch
            andwf   swold,W         ; filter out "new release" bits
            skpz                    ; new press? no, skip, else
            bsf     beepctr,5       ; task a "new press" beep
            xorwf   flags,F         ; toggle sw flags for main

    Cheerful regards, Mike

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts