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