RB Port Change Interrupt - 16F84a

For C and ASSEMBLY users to post questions and code snippets for programming in C and ASSEMBLY. And for any other C or ASM course related questions.

Moderators: Benj, Mods

Post Reply
econnections
Posts: 35
Joined: Fri Dec 26, 2008 4:02 pm
Contact:

RB Port Change Interrupt - 16F84a

Post by econnections »

Hi,

The simple code below is intended to capture which button is pressed between RB7-RB4 that initiated an interrupt. During the interrupt the value of portb is saved to TEMP and the upper and lower nibble swapped of TEMP swapped. TEMP is then sent to porta for viewing. When any of the switches for RB7-RB4 is pressed the corresponding bit is set on PORTA and its LED illuminated. However, the LED is only turned on for the time the putton is pressed. Why is is this happening? I had expected the value on PORTA to remain until the next interrupt.

I hope my meny questions are helping others. I am now getting real value out of my development board and all the software I purchased and a lot of fun. Thank you for the great help you have been able to offer.

Code: Select all

; The following line embeds configuration data into the PICmicro
	__CONFIG H'3FF9'                ; XT mode
;	__CONFIG _CP_OFF & _XT_OSC & _WDT_OFF & _PWRTE_OFF
; At start LED A0 should illunimate to show programm has started. When RB7-RB4 trigger interrupt this should 
; illuminate a corresponding bit on portA to should which switch was pressed.
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 

INCLUDE "C:\PROGRA~1\MPLAB\P16F84A.INC"

#DEFINE PAGE0	BCF	STATUS,5
#DEFINE PAGE1	BSF	STATUS,5

TEMP	EQU	H'21'
	ORG 	0
	GOTO 	5
	ORG 	4
	GOTO 	INT_ROUTINE


		
	ORG 	5
	CLRF	PORTA		
	CLRF	PORTB
	BCF 	INTCON,RBIF 	;CLEAR RB PORT CHANGE INTERRUPT FLAG
	BSF 	INTCON,RBIE 	;ENABLE RB PORT CHANGE INTERRUPT
	BSF 	INTCON,GIE 	;ENABLE GLOBAL INTERRUPT

	PAGE1
	MOVLW 	H'F0'
	MOVWF 	TRISB 		;CONFIG PORTB AS INPUTS
	MOVLW 	H'0'
	MOVWF 	TRISA 		;CONFIG PORTA AS OUTPUTS
	PAGE0
	MOVLW 	H'1'
	MOVWF 	PORTA 		;TURN ON LED A0


WAIT	
	GOTO 	WAIT




INT_ROUTINE
	PAGE0
	MOVFW	PORTB
	MOVWF	TEMP
	SWAPF	TEMP,0		;SWAP UPPER AND LOWER NIBBLE OF TEMP AND SAVE IN WREG
	MOVWF	PORTA
	BCF 	INTCON,RBIF 	;CLEAR RB PORT CHANGE INTERRUPT FLAG
	RETFIE
	END

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: RB Port Change Interrupt - 16F84a

Post by Benj »

Hello

The port change interrupt will fire whenever the port value changes. Therefore the interrupt fires when you press the button and again when you release. To get around this you could stay in the interrupt routine until the switch is released or you can put in the start of your interrupt routine to only do something if a switch is pressed etc.

econnections
Posts: 35
Joined: Fri Dec 26, 2008 4:02 pm
Contact:

Re: RB Port Change Interrupt - 16F84a

Post by econnections »

Hi Ben,

The key word here is 'change'. I had wronly assumed the interrupt triggered on a rising edge when infact as you stated it triggers on both rising amd falling edge. Many thanks again.

econnections
Posts: 35
Joined: Fri Dec 26, 2008 4:02 pm
Contact:

Re: RB Port Change Interrupt - 16F84a

Post by econnections »

Ben,
I made changes to the program so that an action is only performed when the switch is pressed. It is included here for help to anyone learing about Port Change Interrupts.

Code: Select all

; The following line embeds configuration data into the PICmicro
	__CONFIG H'3FF9'                ; XT mode
;	__CONFIG _CP_OFF & _XT_OSC & _WDT_OFF & _PWRTE_OFF
; USING RB PORT CHANGE INTERRUPT. 
; IF SWITCHES ARE ATTACHED TO RB7.4 THEN PRESSING OR RELEASING ANY OF THESE SWITCHES
; WILL CREATE A PORTB CHANGE AND A CALL TO INT_ROUTINE. IN THIS EXAMPLE THE AUTHOR ONLY WANTED 
; THE PRESS EVENT TO PERFORM AN ACTION (INCREMENT TEMP AND SHOW ON PORTB). STATUS BIT 2 (ZERO) WAS 
; CHECKED AND IF CLEAR THIS INDICATED PORTB HAD A VALUE AND THAT ALLOWED A SWITCH PRESS TO INCREMENT 
; THE VARIABLE TEMP. WHEN THE SWITCH WAS RELEASED STATUS BIT-2 WAS FOUND TO BE SET AND USED TO SKIP 
; THE INCREMENT OF TEMP. 
; A 0.25 SEC DELAY ROUTINE WAS ADDED TO PREVENT BOUNCE BUT THE COUNTER WORKED CORRECTLY WITHOUT IT. 
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 

INCLUDE "C:\PROGRA~1\MPLAB\P16F84A.INC"

#DEFINE PAGE0	BCF	STATUS,5
#DEFINE PAGE1	BSF	STATUS,5

	cblock 0x24
	d1
	d2
	d3
	endc


TEMP	EQU	H'21'

	ORG 	0
	GOTO 	5
	ORG 	4
	GOTO 	INT_ROUTINE


	ORG 	5
	CLRF	PORTA		
	CLRF	PORTB
	BCF 	INTCON,RBIF 	;CLEAR RB PORT CHANGE INTERRUPT FLAG
	BSF 	INTCON,RBIE 	;ENABLE RB PORT CHANGE INTERRUPT
	BSF 	INTCON,GIE 	;ENABLE GLOBAL INTERRUPT
	CLRF	TEMP

	PAGE1
	MOVLW 	H'F0'
	MOVWF 	TRISB 		;CONFIG PORTB AS INPUTS
	MOVLW 	H'0'
	MOVWF 	TRISA 		;CONFIG PORTA AS OUTPUTS
	PAGE0

WAIT	
	GOTO 	WAIT



INT_ROUTINE
	PAGE0
	MOVF	PORTB,1
	BTFSS	STATUS,2
	GOTO	SKIP
	INCF	TEMP	
	MOVF TEMP,0
	MOVWF	PORTA
	CALL 	DELAY_0.25_SECS
SKIP	BCF 	INTCON,RBIF 	;CLEAR RB PORT CHANGE INTERRUPT FLAG
	BCF	INTCON,7
	RETFIE




DELAY_0.25_SECS
			; Delay = 0.25 seconds
			; Clock frequency = 3.2768 MHz

			; Actual delay = 0.25 seconds = 204800 cycles
			; Error = 0 %


			;204798 cycles
	movlw	0xFF
	movwf	d1
	movlw	0xA0
	movwf	d2
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	Delay_0

			;2 cycles
	goto	$+1

			; Generated by http://www.golovchenko.org/cgi-bin/delay (December 7, 2005 version)


	RETURN

	END

Post Reply