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.

Input Counter Pic16F84A (Code problems)

Status
Not open for further replies.

loco

New Member
Hi,

My goal with this project i'm working on is to count the number of times a button is pressed in a timespan eg 1 second. These are the 2 approaches i've used that are simulated succesfully, but don't work when put on the chip

The first thing i tried is using the interrupt on RB0, when that was triggered it went into a loop for a couple seconds, then every time the interrupt was triggered it incremented a counter and at the end of the delay it used the counter value in a table to get which port to set to high.

Again, that worked in my simulations, but not on the chip.

The next approach i used was to use Timer0, and increment the counter just using RB0 but not as an interrupt. Put it in a loop looking for Rb0 to go high/low, and when the timer overflowed check the counter value against the table, but again my attempts have failed.

Has anyone got any idea as to what i'm obviously missing, as i am fairly new to pic programming. The latest code follows.

Code:
org			0x00	;This is where the PC points to on power up & reset
;**********************SETUP CONSTANTS***********************
INTCON		equ 0x0B	;Interrupt control register
TMR0		equ	0x01
STATUS		equ 0x03	;Banks
OPTION_REG	equ	0x81	;Option Reg
PC			equ 0x02	;Set Program Counter to 02h for table data
TRISA		equ 0x85	;Tristate A
PORTA		equ 0x05	;Port A
TRISB		equ 0x86	;Tristate B
PORTB		equ 0x06	;Port B
SWITCHCOUNTER		equ 0x0C
COUNTER		equ 0x0D
COUNTER2	equ 0x0E
COUNTER3	equ	0x0F
TEMP		equ	0x10


goto		main
;************************INTERRUPT ROUTINE*******************
org			0x04
	movwf	TEMP
	movlw	0x04
	subwf	SWITCHCOUNTER,W
	btfss	STATUS,0
	goto	carry_on
	goto	clear
retfie
	
carry_on
	movf	TEMP,w
	call	table
	movwf	PORTA
	call	Delay2		;This delay is the button press length
	call	ClosePorts
	call	SetVars
	bcf		INTCON,2 
retfie

clear
	call	SetVars
	bcf		INTCON,2 
retfie

main
;*****************SETUP INTERRUPT RESGISTERS*****************
bsf			INTCON,7	;Set the Global interrupt switch
bsf			INTCON,5	;TMR0 interrupt enabled
bcf			INTCON,2	;INTF - Clear flag
;**********************SETUP THE PORTS***********************
bsf			STATUS,5	;Switch to bank 1
movlw		0x01		;Set W to 000001
movwf		TRISB		;Put W into TRISB
movlw		0x00		;Set W to 000000
movwf		TRISA		;Put W into TRISA
movlw		b'11010100'
movwf		OPTION_REG
bcf			STATUS,5	;Switch to bank 0



call	SetVars

intLoop
	btfss	PORTB,0
	goto	intLoop

	call	Delay3

	btfsc	PORTB,0
	goto	$ -1

	incf	SWITCHCOUNTER
	call	enableInt
goto intLoop

SetVars
	clrf	TEMP
	clrf	SWITCHCOUNTER
	movlw	0xFF
	movwf	COUNTER
	movlw	0xFF
	movwf	COUNTER2
	movlw	0xFF
	movwf	COUNTER3
	call	disableInt
return


Delay2
	Loop2		decfsz	COUNTER,1
		goto 	Loop2
		decfsz	COUNTER2,1
		goto	Loop2
return

Delay3
	Loop3
		decfsz	COUNTER,1
		goto 	Loop3
return

ClosePorts
	bcf		PORTA,0
	bcf		PORTA,1
	bcf		PORTA,2
return

disableInt
	bcf		INTCON,7
	bcf		INTCON,5
return

enableInt
	clrf	TMR0
	bcf		INTCON,2
	bsf		INTCON,7
	bsf		INTCON,5

return

table
	movf	SWITCHCOUNTER,w
	addwf 	PC,1
	retlw	0x00
	retlw	0x01
	retlw	0x02
	retlw	0x04


end
 

Nigel Goodwin

Super Moderator
Most Helpful Member
First off, the 16F84 is LONG! obsolete, it was replaced by the 16F628 last century!.

Your interrupt code is very badly flawed, you don't do any context saving and restoring, so it will corrupt your main program. Also, you have THREE 'retfie' instructions, it's good practice to only have one of these.

What about key debouncing?, if you don't debounce them you'll get multiple counts for every press.
 

loco

New Member
yeah :( that's the problem living in africa, we're about a century behind everyone else :p I'll look into improving those factors, thank you for your help, this is my first time using interrupts so i'm not all clued up. Let me give these suggestions a bash. Thanks
 

loco

New Member
Ok, as far as i can tell, i've added some debounce code, tidied the interrupt up a bit, it still has 2 retfie's tho. It works with in the simulation, but goes crazy when i put it in the circuit, i have 3 led's hooked up to RA0, RA1 and RA2, the theory is that when i press the button once RA0 lights up for x time, when i press it twice RA1, and 3 times RA2. But in the circuit it doesn't do that at all? The led's just randomly flash for a while, and aren't very responsive to the button presses?

Code:
org			0x00	;This is where the PC points to on power up & reset
;**********************SETUP CONSTANTS***********************
INTCON		equ 0x0B	;Interrupt control register
TMR0		equ	0x01
STATUS		equ 0x03	;Banks
PCLATH		equ	0x0A	
OPTION_REG	equ	0x81	;Option Reg
PC			equ 0x02	;Set Program Counter to 02h for table data
TRISA		equ 0x85	;Tristate A
PORTA		equ 0x05	;Port A
TRISB		equ 0x86	;Tristate B
PORTB		equ 0x06	;Port B
SWITCHCOUNTER		equ 0x0C
COUNTER		equ 0x0D
COUNTER2	equ 0x0E
COUNTER3	equ	0x0F
TEMP		equ	0x10
s_temp		equ	0x11
w_temp		equ	0x12
p_temp		equ	0x13

goto		main
;************************INTERRUPT ROUTINE*******************
org			0x04
	movwf	TEMP

	movwf	w_temp
	swapf	STATUS,W
	movwf	s_temp
	movfw	PCLATH
	movwf	p_temp

	movlw	0x04
	subwf	SWITCHCOUNTER,W
	btfss	STATUS,0
	goto	carry_on
	goto	clear

	
carry_on
	movf	TEMP,w
	call	table
	movwf	PORTA
	call	Delay2		;This delay is the button press length
	call	ClosePorts
	call	SetVars
	bcf		INTCON,2 

	movfw	p_temp
	movwf	PCLATH
	swapf	s_temp,W
	movwf	STATUS
	swapf	w_temp,f
	swapf	w_temp,W
retfie

clear
	call	SetVars
	bcf		INTCON,2
	movfw	p_temp
	movwf	PCLATH
	swapf	s_temp,W
	movwf	STATUS
	swapf	w_temp,f
	swapf	w_temp,W
retfie

main
;*****************SETUP INTERRUPT RESGISTERS*****************
bsf			INTCON,7	;Set the Global interrupt switch
bsf			INTCON,5	;TMR0 interrupt enabled
bcf			INTCON,2	;INTF - Clear flag
;**********************SETUP THE PORTS***********************
bsf			STATUS,5	;Switch to bank 1
movlw		0x01		;Set W to 000001
movwf		TRISB		;Put W into TRISB
movlw		0x00		;Set W to 000000
movwf		TRISA		;Put W into TRISA
movlw		b'11010100'
movwf		OPTION_REG
bcf			STATUS,5	;Switch to bank 0



call	SetVars

intLoop
	btfss	PORTB,0
	goto	intLoop
	call	Delay3
	btfss	PORTB,0
	goto	intLoop

	btfsc	PORTB,0
	goto	$ -1
	call 	Delay3
	btfsc	PORTB,0
	goto	$ -1

	incf	SWITCHCOUNTER
	call	enableInt
goto intLoop

SetVars
	clrf	TEMP
	clrf	SWITCHCOUNTER
	movlw	0xFF
	movwf	COUNTER
	movlw	0xFF
	movwf	COUNTER2
	movlw	0xFF
	movwf	COUNTER3
	call	disableInt
return


Delay2
	Loop2		decfsz	COUNTER,1
		goto 	Loop2
		decfsz	COUNTER2,1
		goto	Loop2
return

Delay3
	Loop3
		decfsz	COUNTER,1
		goto 	Loop3
return

ClosePorts
	bcf		PORTA,0
	bcf		PORTA,1
	bcf		PORTA,2
return

disableInt
	bcf		INTCON,7
	bcf		INTCON,5
return

enableInt
	clrf	TMR0
	bcf		INTCON,2
	bsf		INTCON,7
	bsf		INTCON,5

return

table
	movf	SWITCHCOUNTER,w
	addwf 	PC,1
	retlw	0x00
	retlw	0x01
	retlw	0x02
	retlw	0x04


end
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Top