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.
Ok, then, the code, at this time is:
Code:
;/****************************************************************************
;* DESCRIPTION: System definitions.
;*****************************************************************************/ 

	ERRORLEVEL -302 ;remove message about using proper bank

	LIST  P=16F677
	INCLUDE <P16F677.INC>
	__CONFIG _BOR_OFF & _FCMEN_OFF & _IESO_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTOSCIO

;/****************************************************************************
;* DESCRIPTION: Program variables and constant definitions.
;*****************************************************************************/ 

TEMPER		EQU 0x20			; Store temperature
UNITS		EQU 0x24			; UNITS
TENS		EQU 0x25			; TENS
HUNDREDS	EQU 0x26			; HUNDREDS
AUX		EQU 0x27			; GENERAL AUX. REGISTER
TEMPO0		EQU 0x28
TEMPO1		EQU 0x29
FLAGS		EQU 0x2B			; General use flags
TIMER		EQU 0x2D			; Timer register
buz_file	EQU 0x2E			; Buzzer file
buz_length	EQU 0x2F				; Buzzer length

#define		SHOWTEMP	FLAGS,6		; Show temperatue?
#define		SHOWTIME	FLAGS,7		; Show timer?

; Leds
#define		LED_CMN		PORTC,2		; Leds Anodes

#define		LED_UP		PORTA,4		; Led UP
#define		LED_TIMER	PORTB,6		; Led TIMER
#define		LED_TEMP	PORTB,5		; Led TEMP
#define		LED_DWN		PORTA,2		; Led DWN
#define		LED_LIGHT	PORTB,4		; Led LIGHT
#define		LED_TOASTER	PORTA,5		; Led TOASTER
#define		LED_ONOFF	PORTC,6		; Led ONOFF
#define		TRIS_LED_ONOFF	TRISC,6		; Led ONOFF TRIS

; Displays
#define		DISP1		PORTC,3		; Anode display DIS0
#define		DISP2		PORTC,4		; Anode display DIS1
#define		DISP3		PORTC,5		; Anode display DIS2

; Buzzer
#define		buz		PORTC,0		; Buzzer

;/****************************************************************************
;* DESCRIPTION: Start of program.
;***************************************************************************** 
	ORG	0x0000
	goto	START

;/****************************************************************************
;* DESCRIPTION: Decodes value in W register to display segments for PORTA.
;* return:      result in W
;*****************************************************************************/ 

DECDISP_A:
	addwf   PCL,F		; compute the jump value
				;	|7|6|5|4|3|2|1|0| -	Bits PORTA
				;	|-|-|B|E|-|A|-|-|
	retlw	B'00000000'	;	|-|-|B|E|-|A|-|-| -	0
	retlw	B'00010100'	;	|-|-|B|X|-|X|-|-| -	1
	retlw	B'00000000'	;	|-|-|B|E|-|A|-|-| -	2
	retlw	B'00010000'	;	|-|-|B|X|-|A|-|-| -	3
	retlw	B'00010100'	;	|-|-|B|X|-|X|-|-| -	4
	retlw	B'00110000'	;	|-|-|X|X|-|A|-|-| -	5
	retlw	B'00100000'	;	|-|-|X|E|-|A|-|-| -	6
	retlw	B'00010000'	;	|-|-|B|X|-|A|-|-| -	7
	retlw	B'00000000'	;	|-|-|B|E|-|A|-|-| -	8
	retlw	B'00010000'	;	|-|-|B|X|-|A|-|-| -	9


;/****************************************************************************
;* DESCRIPTION: Decodes value in W register to display segments, for PORTB.
;* return:      result in W
;*****************************************************************************/ 

DECDISP_B:
	addwf   PCL,F		; compute the jump value
				;	|7|6|5|4|3|2|1|0| -	Bits PORTB
				;	|C|F|D|G|-|-|-|-| -
	retlw	B'00010000'	;	|C|F|D|X|-|-|-|-| -	0
	retlw	B'01110000'	;	|C|X|X|X|-|-|-|-| -	1
	retlw	B'11000000'	;	|X|X|D|G|-|-|-|-| -	2
	retlw	B'01000000'	;	|C|X|D|G|-|-|-|-| -	3
	retlw	B'00100000'	;	|C|F|X|G|-|-|-|-| -	4
	retlw	B'00000000'	;	|C|F|D|G|-|-|-|-| -	5
	retlw	B'00000000'	;	|C|F|D|G|-|-|-|-| -	6
	retlw	B'01110000'	;	|C|X|X|X|-|-|-|-| -	7
	retlw	B'00000000'	;	|C|F|D|G|-|-|-|-| -	8
	retlw	B'00000000'	;	|C|F|D|G|-|-|-|-| -	9

;/****************************************************************************
;* DESCRIPTION: Little Delay to let display show digit.
;* return:      none
;*****************************************************************************/ 

H_keeping:
	bsf	buz		; piezo on
	movlw	.170
	movwf	buz_file
	decfsz	buz_file,f
	goto	$-1
	bcf	buz		; piezo off        
	movlw	.170
	movwf	buz_file
	decfsz	buz_file,f
	goto	$-1
	bcf	buz		; piezo off
	decf	buz_length	; 
	retlw	00

;/****************************************************************************
;* DESCRIPTION: binary_to_bcd - 8-bits
;* INPUT:	TEMPER   - 8-bit binary number
;* return:      HUNDREDS - the hundreds digit of the BCD conversion
;*		TENS     - the tens digits of the BCD conversion
;*		UNITS    - the ones digits of the BCD conversion
;*****************************************************************************/ 
BIN2BCD:

	movwf	AUX		; save the value to convert in AUX
	clrf	UNITS		;
	clrf	TENS		;
	clrf	HUNDREDS	; RESET variables
	movf	AUX,F		;
	btfsc	STATUS,Z	; Is the value to convert = 0?
	return			; Yes - Return
				; No
	incf	UNITS,F		; Increment unit
	movf	UNITS,W		;
	xorlw	0X0A		;
	btfss	STATUS,Z	; unit = 10d ?
	goto	$+3		; No
				; yes
	clrf	UNITS		; Reset unit
	incf	TENS,F		; Increment tens
	movf	TENS,W		;
	xorlw	0X0A		;
	btfss	STATUS,Z	; Tens = 10d ?
	goto	$+3		; No
				; Yes
	clrf	TENS		; Reset tens
	incf	HUNDREDS,F	; Increment hundreds
	decfsz	AUX,F		; End of convertion ?
	goto	$-.14		; No - go back to continue the convertion
	return			; Yes

;/****************************************************************************
;* DESCRIPTION: Program Initialization
;*****************************************************************************/ 

START:
	bcf	STATUS,RP0	; Bank 2
	bsf	STATUS,RP1	;
	clrf	ANSEL		; digital I/O
	clrf	ANSELH		; "	"	"
	bcf	STATUS,RP0	; Bank 2
	bsf	STATUS,RP1	;
	movlw	B'00000000'
	movwf	CM1CON0		; disable comparator
	movlw	B'00000000'	; Not necessary?
	movwf	CM2CON0		; disable 2nd comparator
	movlw	B'00000000'	; Not necessary?
	movwf	CM2CON1		; disable 3rd comparator
	bsf	STATUS,RP0	; Bank 1
	bcf	STATUS,RP1	;
	movlw	B'00001000'	;
	movwf	TRISA		;
	movlw	B'00000000'	;
	movwf	TRISB		;
	movlw	B'10000010'	;
	movwf	TRISC		;
	bcf	STATUS,RP0	; Bank 0
	bcf	STATUS,RP1	;
	bcf	SSPCON,SSPEN	; Disable Synchronous Serial Port

	; 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		;
	movlw	D'40'		; Start TIMER with 40 minutes
	movwf	TIMER		;
	clrf	UNITS
	clrf	TENS
	clrf	HUNDREDS

	movlw	D'250'
	movwf	buz_length

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

MAIN_LOOP:
	movf	TEMPER,W	; Put temperature in W
	call	BIN2BCD		; Decode Temperature to bcd
	bsf	LED_CMN		; Leds off
	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	H_keeping	; delay 2 ms
	movf	TENS,W		; copy tens to W
	call	DECDISP_A	; convert
	bsf	DISP1		; display 1 off
	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	H_keeping	; delay 2 ms
	movf	HUNDREDS,W	; copy hundeds to W
	call	DECDISP_A	; convert
	bsf	DISP2		; display 2 off
	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	H_keeping	; delay 2 ms
	bsf	DISP3		; display 3 off

	; Leds code:
	bcf	LED_UP		; led UP ON
	bcf	LED_DWN		; led DWN ON
	bcf	LED_TEMP	; led TEMP ON
	bcf	LED_TIMER	; led TIMER ON
	bcf	LED_LIGHT	; led LIGHT ON
	bcf	LED_TOASTER	; led TOASTER ON
	bcf	LED_CMN		; Leds on
	call	H_keeping	; delay 2 ms
	bsf	LED_CMN		; Leds off

	goto	MAIN_LOOP	; Back to main loop

	END
 
Last edited:
This is how the signals appear in osciloscope.
The upper trace is one display and the lower is the buzzer pin.
 

Attachments

  • housekeep.jpg
    housekeep.jpg
    42.2 KB · Views: 133
Don't worry about the 'scope waveforms, you may be triggering off the wrong line.
It just matters if the displays are as bright as possible and the tone is a constant, clear, even, smooth signal from the piezo.
 
Ok, the sound of the piezo is good, but seem out of frequency (below the 1KHz). In the scope the frequency is measured as 600 HZ.
 
In reality, the frequency is 955Hz.
I have to see what is going on with the driver circuit.

Now, what can we do? Will we see the keys?

If it's better for you, I can make a movie of the oven working, so you can see all the leds and operations stuff.
 
Last edited:
You can adjust the actual frequency of the piezo later.
Now organise the keys and the LEDs in the houseeeping routine by adding instructions to look at each key and if it is pressed, set a flag in a single 8-bit flag file for the 8 buttons. In SetUp, you zero this flag file
Create a flag file for the 8 LEDs and in SetUp, you zero this flag file.
Now, when you run H_keeping, look at the flag file for the LEDs and if a flag is "1" the appropriate LED is turned on. You can load this flag file with a value at the end of Set_Up to see if the appropriate LEDs come on.
Do this.
 
Defined the files and defines as:
Code:
leds_s	EQU	0x30	; Leds state
keys_s	EQU	0x31	; Keys state

; Leds
#define	LED_CMN		PORTC,2	; Leds Anodes

#define	LED_UP		PORTA,4	; Led UP
#define	LED_TIMER	PORTB,6	; Led TIMER
#define	LED_TEMP	PORTB,5	; Led TEMP
#define	LED_DWN		PORTA,2	; Led DWN
#define	LED_LIGHT	PORTB,4	; Led LIGHT
#define	LED_TOASTER	PORTA,5	; Led TOASTER
#define	LED_ONOFF	PORTC,6	; Led ONOFF

In the setup (start), I initialize the status of leds and keys, this way:
Code:
	movlw	B'01110000'	; Leds initial state (leds onoff, up, down and temperature on)
	movwf	leds_s		; Set leds state
	clrf	keys_s		; Zero keys state
Then, in H_keeping, I test each of the leds status by using:
Code:
btfsc	leds_s,6	; Is led on/off on?

btfsc	leds_s,5	; Is led up on?

btfsc	leds_s,4	; Is led down on?

btfsc	leds_s,3	; Is led light on?

btfsc	leds_s,2	; Is led toaster on?

btfsc	leds_s,1	; Is led timer on?

btfsc	leds_s,0	; Is leds temperature on?

Is this correct?
 
Code:
btfsc    leds_s,6    ; Is led on/off on?
goto    $+3
bsf     portA,4   ;LEDup
goto    $+2
bcf    portA,4     or for the LED to turn it off    this saves a lot of defining etc  
btfsc    leds_s,5    ; Is led up on?            perform the action right here and not have to look up
                                                               the result somewhere else
btfsc    leds_s,4    ; Is led down on?

btfsc    leds_s,3    ; Is led light on?

btfsc    leds_s,2    ; Is led toaster on?

btfsc    leds_s,1    ; Is led timer on?

btfsc    leds_s,0    ; Is leds temperature on?
 
Last edited:
Ok, now, the H_keeping routine is as below.
How do I enable the leds (using the led common enable pin - LED_CMN) using the right timming?

Code:
H_keeping:
	bsf	buz		; piezo on
	movlw	.170
	movwf	buz_file
	decfsz	buz_file,f
	goto	$-1
	bcf	buz		; piezo off        
	movlw	.170
	movwf	buz_file
	decfsz	buz_file,f
	goto	$-1
	bcf	buz		; piezo off
	decf	buz_length,F

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

	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

	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

	retlw	00
 
Last edited:
Got it!
Just changed the code, in main, after the display logic, o:

Code:
	; Leds code:
	bcf		LED_CMN			; Leds on
	call	H_keeping		; delay 2 ms
	bsf		LED_CMN			; Leds off
 
Now put a value in the LEDs flag and see if the correct LEDs come on. And then try other values.
 
Last edited:
Just did it, and all is working ok.

About the keys and leds:
When you conect the oven to mains supply, all leds and display are off.
To turn on the oven, you have to press the on/off button for 2 seconds, then it will put the oven in temperature mode (the display will show the starting temperature - which is 180 degrees, the active mode will be temperature set and the leds temperature, up and down wil be also on). In this state, the on/off led is blinking.
The keys up and down when pressed the first time, make the beep sound, but, if one of them (up or down keys) are kept pressed, the display will increase or decrease at speed of 2 or 3 per second, without beep.
The key Timer will change the mode to Time Set and the display will show the timer value which default is 40 minutes.
After you setup the temperature, time and set the toaster on or off, you press the on/off button to start cooking.
 
Last edited:
You can put in the preliminary values if you like but the next thing to do is create a debounce for the keys and get them to turn a LED on and off.
The keys are only detected once per scan. A scan is 8mS. This gives you the debounce time.
You need a Key_Pressed flag file and a Key_off flag file.
But before you do this you have to be able to detect debounce and to do this you need a blinking LED.
Select the LED that will blink and turn it on.
Now, in the LEDs part of the scan, create code that looks at the LED and if it is illuminated, a file is decremented.
Preload this file with .62 to create 500mS as 62 x 8mS = 500mS and when the file is zero, it get loaded with .62 and the LED is off for 500mS All this time the routine is looking to see if the LED should be flashing and if it should not be flashing, this part of the routine is jumped over.
Now we can organise the debounce.
 
I created the files:
Code:
Key_Pressed	EQU	0x32	; Key pressed flag
Key_off		EQU	0x33	; Key off flag
Led_blink	EQU	0x34	; Led blink time - for debounce

At the end of Setup (main start), I made:
Code:
	movlw	D'62'		; Value to preload to
	movwf	Led_blink	; Led blink time control

But, just one question:
The only led which will blink will be the on/off led, while waiting for an input.
When cooking, the led stops blinking and keeps on.
When cooking, if you press the on/off key, the oven enters in pause mode, so, without debounce because of the lack of a linking led, there will not be some problem?
 
You will have to have code before the blinking code that says to jump over the blinking routine. This can all be done afterwards. Just get the LED to blink and the key debounce section
 
Last edited:
At the H_keeping routine, I changed the part where the led on/off is tested to:

Code:
	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'62'		; Value to preload to
	movwf	Led_blink	; Led blink time control
	btfsc	leds_s,6	; Is led on/off on?
	goto	setledoff
	bsf	leds_s,6	; Led on/off in on
	goto	contled
setledoff:
	bcf	leds_s,6	; Led on/off in off

contled:
	btfsc	leds_s,5	; Is led up on?
	goto	$+3
code continues here...

The only problem is that the led is blinking twice a second.
 
The first time, I was wrong. The led was blinking 4 times a second.
Now, I had to increase the preload value to 255 to have it blinking at 1.15 Hz (+- 830 ms) - on for 415 ms and off for the same time - 415ms.
 
Now do the key identification to turn on the blinking LED and turn it off. This is just to prove the debounce feature where you hold the key for a long period of time to see the effect.

The unwanted code will be then be removed and applied to the other LEDs.
 
You mean, to test implementing the code for one key, to enable/disable the led blinking, so we can test the debounce?
When the key is pressed, I invert the control bit of the led control file, so it will stop blinking (I will use the bit 7 of leds_s because it's not been used yet)?
This code will be placed inside the H_keeping, right?
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top