1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

asm -16f- switch debounce

Discussion in 'Code Repository' started by Mosaic, Feb 9, 2012.

  1. Mosaic

    Mosaic Well-Known Member

    Jun 3, 2010
    Here's a contribution for managing up to 8 switches, not necessarily in a single port. Heavily commented. This should be called as part of a main program loop once per iteration. There is code to evaluate whether the switch is switched to ground or Vcc. Just comment out the part you don't need. Similarly, there are examples for applying a switch from any pin to fill out a single byte for parallel processing. It is dependent on a 4ms ISR for the delay counter. You can alter the ISR speed and compensate by altering the bit being evaluated for the ISR delay time counter held in GPR , 'Dbouncecount'. Just try to have the overall time within 20% of the times used here.

    Code (text):
    Keypad; Evaluate keypresses for click, hold (long press) , open with debounce & transition states. Works in parallel for up to 8 switches. Requires a 4 (can  use others) ms tick (usually done in an ISR) for 'Dbouncecount'.
    ;Setup for Key_0 , in bit 0;  this method allows any pin in any port to be a key /switch as the keys are mapped to a single 8bit byte here. 'Tmp' is a locally valid temp variable for general subroutine use.
    ; The Transition bytes are set  if a new  debounced keystate just happened . These are cleared on each iteration.
    ;Each of the 8 Transition bits in the bytes (Keytrans and HoldTrans) allow for debounced edge triggering events. eg. If the DbKeystate,0  is hi and the Keytrans,0 is high then the debounced key0 press leading edge just happened.  
    ;If DbKeystate is Hi and Keytrans,0 is lo, then the debounced Keypress is mature.
    ;If the DbKeystate,0 is lo and the KeyTrans,0 is hi then the debounced key was just released - trailing edge. Stored in "Shortpress' GPR; Just do a bit check on this byte for any of the 8 switches' shortpress condition.
    ; A similar structure applies to HoldTrans and HoldKeystate bytes as applies to a 'long key hold/click' operation - holding down a key for a 1/2 second. Stored in 'Longpress' byte. Just do a bit check on this byte for any of the 8 switches' longpress condition.
    ; Thus a single key can deliver up to 4 states, leading and trailing edge for both short clicks and long clicks.
    ; The use of the leading edge transitions is manifest when preventing 'repeating' a routine that responds to the key condition.eg. only respond to a keypress if the transition bit is also set, like make a beep.
    ;The leading edge can also keep track of which key to respond to if multiple keys are pressed simultaneously.
    ; eg. The trailing transition can be used for triggering an acknowledgement after the key is released.

        clrf  Sw_state ;clear switch state byte for evaluation below.
        clrf KeyTrans ;limit all transitions to one complete program loop.
        clrf HoldTrans; " "
        ;btfsc GPIO,3 ;  Key0 = pin physical location.  Btfsc used when key is pulled hi when closed.
        btfss GPIO,3; Key0 = pin physical location. Btfss used when key is pulled low when closed
        bsf  Sw_state,0 ; match  Sw_state bit 0 to  Key state, 1= closed, 0=open.
    ;Setup for Key_1 , in bit 1
        ;btfsc PORTA,6 ;  Key1 pin. = PORTA,6
        ;bsf  Sw_state,1 ; match  Sw_state bit 1 to  Key state, 1= closed, 0=open.
    ;Setup for Key_7 , in bit 7
        ;btfsc PORTB,2 ;  Key7 pin. = PORTB,2
        ;bsf  Sw_state,7 ; match  Sw_state bit 7 to  Key state, 1= closed, 0=open.
        movf Sw_state,w ; get newstate                  eg. Sw0,2 closed    0101
        xorwf LastKeystate,w ; state changes                    eg.     1100 => 1001
        xorwf LastKeystate,f ; make Laststate =Newstate.                    1100=>  0101
        andlw b'11111111'; test wreg if any bits changed
        btfss STATUS,Z; skip zero set, else (statechange)
        clrf Dbouncecount; reset counter (counts every 4 msec in ISR)
        btfss Dbouncecount,2 ; skip if bit 2 set=> 16ms passed, else
        goto Testkeyhold;
        movf LastKeystate,w;                                                    0101
        xorwf DbKeystate,w; get changes bet. current state and debounced state.     0110 => 0011
        movwf KeyTrans; save in transition byte.                                            0011 (transition bits)
        xorwf DbKeystate,f; apply them to DB state                              0110 => 0101   
            movf DbKeystate,w
        xorlw .255; test for key release (open)
        andwf KeyTrans,w; verify transition of key release.
        movwf Shortpress; update shortpress status, based on click/release.            
        movf  DbKeystate,w  ;                                                       0101
        andwf HoldKeystate,w ;zero Hold bits if matching key is released - wreg.                0011 => 0001
        xorwf HoldKeystate,w ; get Transition from Hold to release                          0011 => 0010
        movwf HoldTrans; update HoldTransition byte.                                                        0010
        xorwf KeyTrans,f ; toggle any matching release from clicks off, release from hold priority.
        xorwf HoldKeystate,f ; now immediately switch off Hold if a key is released - file.     0011 => 0001
        xorwf DbKeystate,w ; get newly pressed keys to test for hold.(state change)                         0101 => 0100
        btfss STATUS,Z; skip if  no new key pressed, else
    Testforholdcount ; test if timer expired
        btfss Dbouncecount,7 ; 128*4ms = 512ms
        goto Keydone
        movf DbKeystate,w;                          0101
        xorwf HoldKeystate,w ; get statechanges         0001 => 0100
        iorwf HoldTrans,f; update hold transition byte.         0010 => 0110 (transition bits)
        ;using what's still in wreg to apply changes        0100
        xorwf HoldKeystate,f;apply changes              0001 => 0101
            movf HoldKeystate,w
        andwf  HoldTrans,w; verify transition of key
        movwf Longpress; update Longpress status.
    Keydone return
    Last edited: Apr 5, 2013
    • Like Like x 1
  2. lurkepus

    lurkepus Member

    Oct 26, 2011
    Larvik Norway
    Thanks .. i will havea look at it .. btw will it be hard to rewrite the code so i can use it on a 12f683??
  3. Mosaic

    Mosaic Well-Known Member

    Jun 3, 2010
    Yes will work on any 12f,16f18f series.

    If u tell me which pins u want to place your switches on I will happilly adjust it for u.

Share This Page