Wednesday, March 15, 2006

PIC: EXAMPLE 7

EXAMPLE 7

Using macros in the program, using debounce routine

You have probably noticed in the previous example that the microcontroller does not always operate as expected. Namely, by pressing the push-button, the number on port B is not always incremented by 1. Mechanical push-buttons make several short successive contacts when they have been activated. You guess, the microcontroller registers and counts all that...
Example 7 - Using macros in a program, using debounce routine
There are several ways to solve this problem. This program uses program delay known as debounce. Basically, it is a simple procedure. Upon input change detection (button press), a short program delay is provided and the program waits for another change (button release). Only after this, the program comes to a conclusion that the button is activated.
In this very case, the push-button is tested by means of macro called button. Besides, this macro contains a program delay which is provided by means of another macro pausems.
The main program is relatively simple and enables the variable "cnt" to be incremented and decremented by using two push-buttons. This variable is thereafter copied to port B and affects the LED (logic one (1) turns LED diode on, while logic zero (0) turns LED diode off).

Source Code

;********************** Header **********************
;************* DEFINING VARIABLES *************************

       cblock      0x20            ; Block of variables starts at address 20hex
       
       HIcnt
       LOcnt
       LOOPcnt
       cnt
       endc                        ; End of block of variables
;**********************************************************************
       ORG         0x000           ; Reset vector
       nop
       goto        main            ; Go to program start (label "main")
;**********************************************************************

       include    "pause.inc"
       include    "button.inc"

;**********************************************************************
main
       banksel      ANSEL          ; Selects bank containing ANSEL
       clrf         ANSEL          ; All pins are digital
       clrf         ANSELH
 
       banksel      TRISB
       bsf          TRISA, 0
       bsf          TRISA, 1
       clrf         TRISB
       
       banksel      PORTB
       clrf         cnt       
Loop
       button       PORT,0,0,Increment
       button       PORT,1,0,Decrement
       goto         Loop
       
Increment
       incf         cnt, f
       movf         cnt, w
       movwf        PORTB
       goto         Loop
Decrement
       decf         cnt, f
       movf         cnt, w
       movwf        PORTB
       goto         Loop
       end                         ; End of program

Macro "pausems"

;**********************************************************************
pausems MACRO arg1
       local        Loop1
       local        dechi
       local        Delay1ms
       local        Loop2
       local        End

       movlw        High(arg1)     ; Higher byte of argument is moved
                                   ; to HIcnt
       movwf        HIcnt
       movlw        Low(arg1)      ; Lower byte of argument is moved
                                   ; to LOcnt
       movwf        LOcnt
Loop1
       movf         LOcnt, f       ; Decrements HIcnt and LOcnt while
       btfsc        STATUS, Z      ; needed and calls subroutine Delay1ms
       
       goto         dechi
       call         Delay1ms
       decf         LOcnt, f
       goto         Loop1
dechi
       movf         HIcnt, f
       btfsc        STATUS, Z
       goto         End
       call         Delay1ms
       decf         HIcnt, f
       decf         LOcnt, f
       goto         Loop1
Delay1ms:                          ; Delay1ms provides delay of
       movlw        .100           ; 100*10us=1ms
       movwf        LOOPcnt        ; LOOPcnt<-100
Loop2:
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       decfsz      LOOPcnt, f
       goto        Loop2           ; Execution time of Loop2
       return                      ; is 10 us
End
       ENDM
;**********************************************************************

Macro "button"

;****************************************************
button MACRO port,pin,hilo,label
       local       Pressed1        ; All labels are local
       local       Pressed2
       local       Exit1
       local       Exit2
       
       IFNDEF      debouncedelay   ; Enables debounce time to be defined
                                   ; in main program
       #define     debouncedelay .10
       ENDIF
       
       IF (hilo == 0)              ; If pull-up used
       btfsc       port, pin       ; If "1", push-button is pressed
       goto        Exit1
       pausems     debouncedelay   ; Wait for 10ms debounce
Pressed1
       btfss       port, pin
       goto        Pressed1
       pausems     debouncedelay   ; Wait until released and
       goto        label           ; jump to specified address
Exit1
       ELSE                        ; If pull-down used
       btfss       port, pin
       goto        Exit2           ; If "0", push-button is released
       pausems     debouncedelay   ; Wait for 10ms debounce
Pressed2
       btfsc       port, pin
       goto        Pressed2
       pausems     debouncedelay   ; Wait until released and
       goto        label           ; jump to specified address
Exit2
       ENDIF
       
       ENDM
;**********************************************************************