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...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
;**********************************************************************