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

Pic debounce routine

Discussion in 'Microcontrollers' started by ssaguiar, Jun 7, 2010.

  1. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    To all friends:

    This is the final code for the keys autorepeat with debounce and turbo, explained:
    Code (text):

    ;/****************************************************************************
    ;* DESCRIPTION: Verify if key Up is pressed
    ;/****************************************************************************
        BSF     TRISB,7         ; Set PORTB,7 as input (KEY_UP)
        BCF     STATUS, RP0     ; Goto BANK 0
        BTFSS   KEY_UP          ; Test if PORTB pin 7 is 0 (KEY_UP pressed)
        GOTO    KEYUPISR        ; If key pressed, go process it

    ;/****************************************************************************
    ;* DESCRIPTION: If we arrive here, no keys are pressed, so clear keys flags.
    ;/****************************************************************************
        CLRF    KEYS_FLAGS      ; If no key pressed, clear Keys pressed flags.
        CLRF    KEYUPCNT        ; Clear Key UP press counter
        CLRF    KEYDWNCNT       ; Clear Key DOWN press counter
        CLRF    KEYONOFFCNT     ; Clear Key ONOFF press counter
        MOVLW   D'3'            ; Reset key debounce counter
        MOVWF   KEY_DEBOUNCE    ;
        CLRF    KEY_TURBO       ; Reset Key turbo counter
        GOTO    EXITTMR0        ; Done, exit.

    ;/****************************************************************************
    ;* DESCRIPTION: Process key Up
    ;/****************************************************************************
    KEYUPISR
        BTFSC   KEYS_FLAGS,0    ; First pass? If not, use debounce/turbo   
        GOTO    CONTDEB         ; Continue, if not.
        CLRF    TMR_1MS         ; Clear 1 ms counter (for 100 ms)
        BSF     BUZZEREN        ; Enable beep (for 100ms)
        GOTO    CONTUPISR2      ; Continue

    CONTDEB
        MOVF    KEY_TURBO,W     ; If KEY_TURBO == 255
        SUBLW   D'255'          ; Let it be 255 (we are at maximum TURBO speed).
        BTFSS   STATUS,Z        ; Else
        INCF    KEY_TURBO,F     ; Increment KEY_TURBO

        DECFSZ  KEY_DEBOUNCE,F  ; KEY_DEBOUNCE--;
        GOTO    EXITKEYUPISR    ; If KEY_DEBOUNCE > 0, exit

        MOVF    KEY_TURBO,W     ; Else, if KEY_TURBO < 20,
        SUBLW   D'19'           ; Then, let's use a value of 6 in KEY_DEBOUNCE
        BTFSS   STATUS,C        ;
        GOTO    CONTUPISR0      ; No, it's not < 20, continue
        MOVLW   0x06            ; Yes, it's below 20, then
        MOVWF   KEY_DEBOUNCE    ; set simple autorepeat mode - KEY_DEBOUNCE = 6
    CONTUPISR0
        MOVF    KEY_TURBO,W     ; If KEY_TURBO > 20 and KEY_TURBO <= 40
        SUBLW   D'20'           ; > 20?
        BTFSC   STATUS, C       ;
        GOTO    CONTUPISR1      ; No, goto next test
        MOVF    KEY_TURBO,W     ;
        SUBLW   D'40'           ; <= 40?
        BTFSS   STATUS, C       ;
        GOTO    CONTUPISR1      ; No, goto next test
        MOVLW   0x03            ; Yes, KEY_TURBO is > 20 and <= 40 then
        MOVWF   KEY_DEBOUNCE    ; Put in turbo mode - KEY_DEBOUNCE = 3
        GOTO    CONTUPISR2      ; Continue
    CONTUPISR1
         MOVF   KEY_TURBO,W     ; Else if KEY_TURBO > 40
         SUBLW  D'40'           ;
         BTFSC  STATUS, C       ;
         GOTO   CONTUPISR2      ; No, Continue
         MOVLW  D'255'          ; If yes, make it 255, so
         MOVWF  KEY_TURBO       ; Next time, it will allways get here...
         MOVLW  0x01            ; KEY_DEBOUNCE = 1
         MOVWF  KEY_DEBOUNCE    ; Put in extra tubo mode - KEY_DEBOUNCE = 1.
    CONTUPISR2

        MOVF    TEMPER,W        ; If TEMPER == 250
        SUBLW   D'250'
        BTFSC   STATUS,Z        ;
        GOTO    LLA1            ; get out if = 250 and beep
        INCF    TEMPER,F
        GOTO    LLA             ; continue
        CALL    SETDISPVAR      ; Convert
        DECFSZ  KEYUPCNT,W      ; If this is the first time the key UP is pressed, then beep?
        GOTO    EXITKEYUPISR    ; Exit
    LLA1
        CLRF    TMR_1MS         ; Restart 1 ms counter, so timer1 isr can make beep last 100ms
        BSF     BUZZEREN        ; Enable beep (for 100ms), untill it's disabled by timer1 isr
    EXITKEYUPISR
        GOTO    EXITTMR0        ; Done, exit
     
    In timer1 interrupt service (at every 500us), do this, to beep:
    Code (text):

        ;/****************************************************************************
        ;* DESCRIPTION: If beep enabled, toggle buzzer pin.
        ;/****************************************************************************
        BTFSS   BUZZEREN        ; Buzzer Enabled?
        GOTO    ENDBEEPC        ; No, get out
        BSF     STATUS, RP0     ; Bank 1
        BCF     TRISC,0         ; PORTC pin0 output
        MOVLW   D'1'            ; Pin 0 => Buzzer
        BCF     STATUS, RP0     ; Bank 0
        XORWF   PORTC,F         ; Xor PORTC,pin0 with decimal 1 (Binary 00000001).
    ENDBEEPC
        ;/****************************************************************************
        ;* DESCRIPTION: Initialize all interrupts values for TIMER0 and TIMER1
        ;/****************************************************************************
        INCF    TMR_1MS,F       ; Increment TR_1MS (0.5 ms counter)
        MOVLW   D'200'          ; 200 because we have an timer1 int at every 500us.
        XORWF   TMR_1MS,W       ; Is TMR_1MS = 200 (100ms)?
        BTFSC   STATUS,Z        ; No, skip if TMR_1MS < 200
        GOTO    INC100MS        ; Yes, zero TMR_1MS and inc TMR_100MS
        GOTO    END_INT         ; No, exit interrupt

    INC100MS
        ;/****************************************************************************
        ;* DESCRIPTION: Disable buzzer at every 100ms and process 100ms counter
        ;/****************************************************************************
        BCF     BUZZEREN        ; Disable buzzer
        CLRF    TMR_1MS         ; Zero TMR_1MS
        INCF    TMR_100MS,F     ; Increment TMR_100MS (100 ms counter)
        ...
        ...
        ...
        ...
        ...

    END_INT
     
    Hope this can be helpfull.

    Sergio
     

Share This Page