;************************************************************************
;                                                                       *
;   Filename:       BA_L4-Toggle_LED-cnt-dec.asm                        *
;   Date:           15/9/07                                             *
;   File Version:   1.0                                                 *
;                                                                       *
;   Author:         David Meiklejohn                                    *
;   Company:        Gooligum Electronics                                *
;                                                                       *
;************************************************************************
;                                                                       *
;   Architecture:   Baseline PIC                                        *
;   Processor:      12F508/509                                          *
;                                                                       *
;************************************************************************
;                                                                       *
;   Files required: none                                                *
;                                                                       *
;************************************************************************
;                                                                       *
;   Description:    Lesson 4, example 4b                                *
;                                                                       *
;   Demonstrates use of counting algorithm for debouncing               *
;                                                                       *
;   Toggles LED when pushbutton is pressed (low) then released (high)   *
;   Uses counting algorithm to debounce switch                          *
;       (alternative version using decfsz in debounce loop)             *
;                                                                       *
;************************************************************************
;                                                                       *
;   Pin assignments:                                                    *
;       GP1 - LED                                                       *
;       GP3 - pushbutton switch                                         *
;                                                                       *
;************************************************************************

    list        p=12F509       
    #include    <p12F509.inc>  

                ; int reset, no code protect, no watchdog, 4Mhz int clock
    __CONFIG    _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC


;***** VARIABLE DEFINITIONS
        UDATA_SHR
sGPIO   res 1                   ; shadow copy of GPIO

        UDATA
db_cnt  res 1                   ; debounce counter
dc1     res 1                   ; delay counter


;************************************************************************
RESET   CODE    0x000           ; effective reset vector
        movwf   OSCCAL          ; update OSCCAL with factory cal value 


;***** MAIN PROGRAM

;***** Initialisation
start
        clrf    GPIO            ; start with LED off
        clrf    sGPIO           ;   update shadow	
        movlw   b'111101'       ; configure GP1 (only) as an output
        tris    GPIO            ; (GP3 is an input)

;***** Main loop
loop
        banksel db_cnt          ; select data bank for this section

db_dn   ; wait until button pressed (GP3 low), debounce by counting:
        movlw   .13             ; max count = 10ms/768us = 13
        movwf   db_cnt        
        clrf    dc1             
dn_dly  incfsz  dc1,f           ; delay 256x3 = 768us.
        goto    dn_dly
        btfsc   GPIO,3          ; if button up (GP3 set),
        goto    db_dn           ;   restart count
        decfsz  db_cnt,f        ; else repeat until max count reached
        goto    dn_dly

        ; toggle LED on GP1
        movf    sGPIO,w
        xorlw   b'000010'       ; toggle shadow register
        movwf   sGPIO           
        movwf   GPIO            ; write to port

db_up   ; wait until button released (GP3 high), debounce by counting:
        movlw   .13             ; max count = 10ms/768us = 13
        movwf   db_cnt        
        clrf    dc1             
up_dly  incfsz  dc1,f           ; delay 256x3 = 768us.
        goto    up_dly
        btfss   GPIO,3          ; if button down (GP3 clear),
        goto    db_up           ;   restart count
        decfsz  db_cnt,f        ; else repeat until max count reached
        goto    up_dly

        ; repeat forever
        goto    loop            

        END


