Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Pic debounce routine

Status
Not open for further replies.
You haven't cleaned up set_up. Just use the following for bank selection:

bcf SSPCON,SSPEN ; Disable Synchronous Serial Port which bank is this in???????????????

Code:
set_up
    ;bcf        STATUS,RP0        ; RP0 = 0
    bsf        STATUS,RP1        ; 0 -> Bank 2
    clrf    ANSEL            ; digital I/O
    clrf    ANSELH            ;    "    "    "
    ;movlw    B'00000000'        ; To disable comparators
    clrf    CM1CON0            ; disable comparator
    ;movlw    B'00000000'        ; Not necessary?
    clrf    CM2CON0            ; disable 2nd comparator
    ;movlw    B'00000000'        ; Not necessary?
    clrf    CM2CON1            ; disable 3rd comparator
    bcf        STATUS,RP1        ; 2 -> Bank 0
    bsf        STATUS,RP0        ; 0 to 1
    movlw    B'00001000'        ; RA0,RA1,RA2,RA4,RA5,RA6 and RA7 output - RA3 input
    movwf    TRISA            ; 
    ;movlw    B'00000000'        ; 
    clrf    TRISB            ; All PORTB output
    movlw    B'10000010'        ; RC0,RC2,RC3,RC4,RC5,RC6 output - RC1 and RC7 inputs
    movwf    TRISC            ; Set it
    bcf        STATUS,RP0        ; 1 to bank 0
    ;bcf        STATUS,RP1        ; RP1 = 0 -> Bank 0
    bcf        SSPCON,SSPEN    ; Disable Synchronous Serial Port   which bank is this in???????????????

    ; Turn off all displays and leds
    bsf        LED_CMN            ; Leds off
    bsf        DISP1            ; Display1 off
    bsf        DISP2            ; Display2 off
    bsf        DISP3            ; Display3 off
    movlw    D'180'            ; Init temperature with 180 degrees Celsius
    movwf    temper            ; Put it in temper file
    movlw    D'40'            ; Start timer with 40 minutes
    movwf    timer            ; Put it in timer file
    clrf    units            ; Clear dislay's files
    clrf    tens            ;
    clrf    hundreds        ;
    movlw    D'255'
    movwf    buz_length        ; Buzzer initial duration
    movlw    B'11110001'        ; Leds initial state (led onoff blinking, up, down and temperature on)
    movwf    leds_s            ; Set leds state
    clrf    k_pressed        ; Zero keys pressed state
    clrf    Key_deb            ; Zero Keys debounce flag
    clrf    Key_off            ; Zero Key off flag
    movlw    D'255'            ; Value to preload to
    movwf    Led_blink        ; Led blink time control
    clear the "key pressed" flag file 
    clear the "not pressed" flag file
    goto    main
 
Last edited:
For the 16F677, the SSPCON register is in bank0, as stated in page 20 of manual, so:
Code:
	bcf		STATUS,RP0		; RP0 = 0 (removed the bcf STATUS,RP1 - I was n page 1 before)
	bcf		SSPCON,SSPEN	; Disable Synchronous Serial Port
        bsf		STATUS,RP0		; RP0 = 1 goto Bank 1
is correct, isn't?
 
The full program is in post #98
I will work in the sub-routine to turn leds on/off and will put all the program here again.
 
There is nothing on post #98

Before you provide any sort of message like this, test the result.

This is exactly the same thing I am trying to impress on you with writing the program.
 
I have already explained how they work in the program.

All you have to do is match up each flag with turning on a particular LED. It could not be easier.
 
First of all:
Without this code inside he keys rutine, the keys detection will not work. I tested it with and without (the Microchip manual is correct):
Code:
	movlw	B'00110100'		; 1 = enable pull-up - 0 disable it.
	movwf	WPUA			; Enable RA2, RA4 and RA5 pull-up internal resistors
    bcf		STATUS,RP0		; RP0 = 0 -> Bank 2
	bsf		STATUS,RP1		; RP1 = 1 -> "   "
    movlw	B'11110000'		; 1 = enable pull-up - 0 disable it.
    movwf	WPUB			; Enable RB4, RB5, RB6 and RB7 pull-up internal resistors
    bsf		STATUS,RP0		; RP0 = 1 -> Back to Bank 1
	bcf		STATUS,RP1		; RP1 = 0 -> "   "
	bsf		OPTION_REG,7	; Set RABPU flag

Second:
I have put the code to only detect the keypress of KEY_UP and KEY_DWN, so it's easier to follow.
Case the KEY_UP is pressed, the temperature (temper file) is increased (this works).
Case the KEY_DWN is pressed, the temperature was suposed to decrease, but isn't (this don't work).
Code:
	;This section has a number of sub-routines to detect a key press, set a flag and turn on a LED
	;This routine detects if a key is pressed for the second
	;time so that a LED can be turned off. It does this by detecting the 
	;key is pressed and looking to see if the "not-pressed" flag has been 
	;set to indicate the key has been released between detections.

	btfsc	KEY_UP			; When KEY_UP pressed, input=0
	goto	$+5				; Not pressed, goto exit (l1)...
	btfss	k_not_pressed,6	; key pressed - look to see if second pressing
	goto	$+3				; (if k_not_pressed,6 is set, key has been released between detections)
	bcf		k_pressed,6		; clear the KEY_UP flag
	incf	temper,F		; increment temperature

	btfsc	KEY_DWN			; When KEY_UP pressed, input=0
	goto	$+5				; Not pressed, goto exit (l1)...
	btfss	k_not_pressed,0	; key pressed - look to see if second pressing
	goto	$+3				; (if k_not_pressed,6 is set, key has been released between detections)
	bcf		k_pressed,0		; clear the KEY_UP flag
	decf	temper,F		; decrement temperature

	;This routine detects if a key is released

	btfss	KEY_UP			; Was the key released? When KEY_UP not pressed, input=1
	goto	$+2				; No, it's still being pressed...
	bsf		k_not_pressed,6	; Key is not pressed, set flag "not pressed"

	btfss	KEY_DWN			; Was the key released? When KEY_UP not pressed, input=1
	goto	$+2				; No, it's still being pressed...
	bsf		k_not_pressed,0	; Key is not pressed, set flag "not pressed"

	;This routine just detects if a key is pressed. 
	;If a key is pressed, it will set the corresponding flag
	;Another routine will detect that the key has been released. 
	;and other routine will deal with doing something will the "key-pressed" flag. 
	;and another routine will deal with turning off the "key-pressed" flag. 
	;clear the flags file in start_up

	btfsc	KEY_UP			; Is KEY_UP pressed, then input=0
	goto	$+3				; No, it's not pressed, exit...
	bsf		k_pressed,6		; Yes, it's pressed, set flag
	bcf		k_not_pressed,6 ; Clear the flag which indicates the key as not pressed.

	btfsc	KEY_DWN			; Is KEY_UP pressed, then input=0
	goto	$+3				; No, it's not pressed, exit...
	bsf		k_pressed,0		; Yes, it's pressed, set flag
	bcf		k_not_pressed,0 ; Clear the flag which indicates the key as not pressed.
Files are being ini in setup as:
Code:
	clrf	k_pressed		; Zero keys pressed state
	clrf	Key_deb			; Zero Keys debounce flag
	clrf	k_not_pressed	; Set Key off flag (all keys not pressed)

In he case of file k_not_pressed I had before made this:
Code:
movlw     D'11111111'
movw     k_not_pressed
But it seems not make any diference.
 
There's no problem with the circuit.
When I disable the leds, in main loop as this:
Code:
	; Leds code:
	bsf		LEDS_ON			; Flag leds on
    bsf		LED_CMN			; Turn off the leds anode (transistor Q6)
	call	DelayAA			; delay
	call	H_keeping		; delay 2 ms
The up and down keys work fine.
It seems that all problem is with leds timing.
 
Last edited:
Let's do this: as I already lost this service (job), I wish continue to learn to program this aplication.
I will change this processor and make a test board.
I will use the PIC18F4620, so it's easier to port this software to any other pic.
Do you agree on helping to make this work using this aproach?
Thanks
 
For those who continue to follow this thread:
The problem with the keys not being read was really related to the leds/displays timing.
After having modified the sequence of leds/displays a little bit, all keys are working now.
The code of house keeping and main are now:
Code:
;/****************************************************************************
;* DESCRIPTION: House keeping and delay routine.
;*****************************************************************************/ 
H_keeping:

    ; Leds:
    ;   7       6       5       4       3       2       1       0
    ; blink   onoff     up     down   light    toast   time    temp

    btfss	leds_s,7		; Is led blink enabled?
    goto	contled			; No, it's not enabled
    btfsc	leds_s,6		; Is led on/off on?
    goto	$+3
    bcf		LED_ONOFF		; No - it's activated directly, not using LED_CMN
    goto	$+2
    bsf		LED_ONOFF		; Yes - it's activated directly, not using LED_CMN

    decfsz	Led_blink,F		; Blink control = 0?
    goto	contled			; No
    movlw	D'255'			; Value to preload to
    movwf	Led_blink		; Led blink time control
    btfsc	leds_s,6		; Is led on/off on?
    goto	setledoff		; Yes, turn it off.
    bsf		leds_s,6		; No, turn it on
    goto	contled			; Continue
setledoff:
    bcf		leds_s,6		; Led on/off in off
contled:
    btfsc	leds_s,5		; Is led up on?
    goto	$+3
    bsf		LED_UP			; No
    goto	$+2
    bcf		LED_UP			; Yes
    btfsc	leds_s,4		; Is led down on?
    goto	$+3
    bsf		LED_DWN			; No
    goto	$+2
    bcf		LED_DWN			; Yes
    btfsc	leds_s,3		; Is led light on?
    goto	$+3
    bsf		LED_LIGHT		; No
    goto	$+2
    bcf		LED_LIGHT		; Yes
    btfsc	leds_s,2		; Is led toast on?
    goto	$+3
    bsf		LED_TOASTER		; No
    goto	$+2
    bcf		LED_TOASTER		; Yes
    btfsc	leds_s,1		; Is led time on?
    goto	$+3
    bsf		LED_timer		; No
    goto	$+2
    bcf		LED_timer		; Yes
    btfsc	leds_s,0		; Is led temp on?
    goto    $+3
    bsf		LED_TEMP		; No
    goto	$+2
    bcf		LED_TEMP		; YES

    ; Test_Keys (k_pressed):
    ;   7       6       5       4       3       2       1       0
    ;   X      up     timer   onoff    light   toast   temp    down

    bsf		STATUS,RP0		; RP0 = 1 goto Bank 1
    movlw	B'00111100'		; 0 = output - 1 = input
    movwf	TRISA			; Make RA2, RA4, RA3 and RA5 inputs (RA3 is a sensor)
    movlw	B'11110000'		; 0 = output - 1 = input
    movwf	TRISB			; Make RB4, RB5, RB6 and RB7 inputs
	movlw	B'00110100'		; 1 = enable pull-up - 0 disable it.
	movwf	WPUA			; Enable RA2, RA4 and RA5 pull-up internal resistors
    bcf		STATUS,RP0		; RP0 = 0 -> Bank 2
	bsf		STATUS,RP1		; RP1 = 1 -> "   "
    movlw	B'11110000'		; 1 = enable pull-up - 0 disable it.
    movwf	WPUB			; Enable RB4, RB5, RB6 and RB7 pull-up internal resistors
    bsf		STATUS,RP0		; RP0 = 1 -> Back to Bank 1
	bcf		STATUS,RP1		; RP1 = 0 -> "   "
	bsf		OPTION_REG,7	; Set RABPU flag
    bcf		STATUS,RP0		; RP0 = 0 -> Back to Bank 0 (RP1 already = 0)

	;==================================================================================

	;This section has a number of sub-routines to detect a key press, set a flag and turn on a LED
	;This routine detects if a key is pressed for the second
	;time so that a LED can be turned off. It does this by detecting the 
	;key is pressed and looking to see if the "not-pressed" flag has been 
	;set to indicate the key has been released between detections.

	btfsc	KEY_UP			; When KEY_UP pressed, input=0
	goto	$+5				; Not pressed, goto exit (l1)...
	btfss	k_not_pressed,6	; key pressed - look to see if second pressing
	goto	$+3				; (if k_not_pressed,6 is set, key has been released between detections)
	bcf		k_pressed,6		; clear the KEY_UP flag
	incf	temper,F		; increment temperature

	btfsc	KEY_DWN			; When KEY_UP pressed, input=0
	goto	$+5				; Not pressed, goto exit (l1)...
	btfss	k_not_pressed,0	; key pressed - look to see if second pressing
	goto	$+3				; (if k_not_pressed,6 is set, key has been released between detections)
	bcf		k_pressed,0		; clear the KEY_UP flag
	decf	temper,F		; decrement temperature

	;This routine detects if a key is released

	btfss	KEY_UP			; Was the key released? When KEY_UP not pressed, input=1
	goto	$+2				; No, it's still being pressed...
	bsf		k_not_pressed,6	; Key is not pressed, set flag "not pressed"

	btfss	KEY_DWN			; Was the key released? When KEY_UP not pressed, input=1
	goto	$+2				; No, it's still being pressed...
	bsf		k_not_pressed,0	; Key is not pressed, set flag "not pressed"

	;This routine just detects if a key is pressed. 
	;If a key is pressed, it will set the corresponding flag
	;Another routine will detect that the key has been released. 
	;and other routine will deal with doing something will the "key-pressed" flag. 
	;and another routine will deal with turning off the "key-pressed" flag. 
	;clear the flags file in start_up

	btfsc	KEY_UP			; Is KEY_UP pressed, then input=0
	goto	$+3				; No, it's not pressed, exit...
	bsf		k_pressed,6		; Yes, it's pressed, set flag
	bcf		k_not_pressed,6 ; Clear the flag which indicates the key as not pressed.

	btfsc	KEY_DWN			; Is KEY_UP pressed, then input=0
	goto	$+3				; No, it's not pressed, exit...
	bsf		k_pressed,0		; Yes, it's pressed, set flag
	bcf		k_not_pressed,0 ; Clear the flag which indicates the key as not pressed.

	;==================================================================================

    bsf		STATUS,RP0		; RP0 = 1 -> Goto Bank 1 (RP1 already = 0)
    bcf		WPUA,7
    bcf		WPUB,7
    bcf		OPTION_REG,7	; Set RABPU flag
    movlw	B'00001000'		;
    movwf	TRISA			; Make A0,A1,A2,A4,A5,A6 and A7 outputs.
    movlw	B'00000000'		;
    movwf	TRISB			; Make all PORTB output.
    bcf		STATUS,RP0		; RP0 = 0 -> Back to Bank 0 (RP1 already = 0)
    retlw    00

;/****************************************************************************
;* DESCRIPTION: Main Program
;*****************************************************************************/ 

Main:
	movf	temper,W		; Put temperature in W
	call	bin2bcd			; Decode Temperature to bcd

	movf	units,W			; copy units to W
	call	decdisp_a		; convert
	movwf	PORTA			; put it in PORTA
	movf	units,W			; copy units to W
	call	decdisp_b		; convert
	movwf	PORTB			; put it in PORTA
	bcf		DISP1			; display 1 on
	call	DelayAA			; delay
	call	H_keeping		; delay 2 ms
	bsf		DISP1			; display 1 off

	movf	tens,W			; copy tens to W
	call	decdisp_a		; convert
	movwf	PORTA			; put it in PORTA
	movf	tens,W			; copy tens to W
	call	decdisp_b		; convert
	movwf	PORTB			; put it in PORTA
	bcf		DISP2			; display 2 on
	call	DelayAA			; delay
	call	H_keeping		; delay 2 ms
	bsf		DISP2			; display 2 off

	movf	hundreds,W		; copy hundeds to W
	call	decdisp_a		; convert
	movwf	PORTA			; put it in PORTA
	movf	hundreds,W		; copy hundeds to W
	call	decdisp_b		; convert
	movwf	PORTB			; put it in PORTA
	bcf		DISP3			; display 3 on
	call	DelayAA			; delay
	call	H_keeping		; delay 2 ms
	bsf		DISP3			; display 3 off

	; Leds code:
	call	H_keeping		; delay 2 ms
    bcf		LED_CMN			; Turn on the leds anode (transistor Q6)
	call	DelayAA			; delay
    bsf		LED_CMN			; Turn off the leds

	goto	Main			; Back to main loop

	END

I will continue to post any progress I have, here because it's important to learn and share.
The knowledge is one of most important things and we need to share our victories and defeats, so we can always continue to learn with these.
I have lost the service but not the desire to solve this.

Sergio
 
This is the latest version of oven.asm.
It uses timer1 interrupt to handle displays and leds and uses timer0 interrupt to handle key.
This is the best way to make it work.
See the up and down keys routnes, where I implemented debounce and 2 levels of autoincrement for these keys (one normal - twice per second - and, after this, a turbo one - 10 times a second).

Sergio
 

Attachments

  • oven.zip
    8.8 KB · Views: 102
Status
Not open for further replies.

Latest threads

Back
Top