Pic debounce routine


To all friends:

This is the final code for the keys autorepeat with debounce and turbo, explained:
Code:
;/****************************************************************************
;* 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:
	;/****************************************************************************
	;* 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
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…