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.

Junebug INT2 problem

Status
Not open for further replies.

futz

Active Member
I've got INT0 working fine to detect Switch 1. But when I make the changes to use INT2 to detect Switch 2, all that happens when I press the button is the program crashes and I have to reset. INT0 still works.

Here's the code:
Code:
		list	p=18F1320
		include	<p18f1320.inc>
		CONFIG	OSC=INTIO2,WDT=OFF,MCLRE=ON,LVP=OFF,DEBUG=ON

		cblock	0x00
			d1
			d2
			d3
			seqnum
		endc

		org		0x0000
		goto	init

		org		0x0008			;Interrupt Service Routine
isr1	tstfsz	INTCON,INT0IF	;is it INT0?
		goto	int0			;yes, go handle it	
int2	nop						;no, handle the INT2 interrupt
		nop						;nop's are temporary
		bcf		INTCON3,INT2IF
		retfie	FAST
int0	incf	seqnum			;switches to next LED sequence
		movlw	3				;is seqnum 3?
		cpfslt	seqnum			;skip if seqnum < 3
		clrf	seqnum			;seqnum = 3, clear it
		bcf		INTCON,INT0IF	;clear INT0 flag
		retfie	FAST

init	bsf		OSCCON,IRCF2	;set to 8MHz clock
		bsf		OSCCON,IRCF1
		bsf		OSCCON,IRCF0
		movlw	0x7f			;set PortA to all digital
		movwf	ADCON1
		clrf	TRISA			;set PortA pins to output
		movlw	b'00100101'		;set PortB pins (switches = inputs)
		movwf	TRISB
		clrf	LATA			;turn off all LEDs
		clrf	seqnum			;set seqnum=0
		clrf	INTCON2			;enable weak pull-ups and falling edges
		movlw	b'10010000'		;enable INT2 interrupt
		movwf	INTCON3
		bcf		RCON,IPEN		;disable irq priority levels
		movlw	b'10010000'		;enable interrupts (INT0)
		movwf	INTCON

Main	movlw	0				;calls correct LED sequence
		cpfseq	seqnum			;according to seqnum value
		goto	next1
		call	seq1
next1	movlw	1
		cpfseq	seqnum
		goto	next2
		call	seq2
next2	movlw	2
		cpfseq	seqnum
		goto	next3
		call	seq3
next3	goto	Main

;		bcf		OSCCON,IDLEN	;Run mode enabled
;		bcf		OSCCON,SCS1		;Primary oscillator
;		bcf		OSCCON,SCS0
;		sleep

seq1	call	led6		;descending LEDs
		call	led5
		call	led4
		call	led3
		call	led2
		call	led1
		return

seq2	call	led1		;ascending LEDs
		call	led2
		call	led3
		call	led4
		call	led5
		call	led6
		return

seq3	call	led1		;pairs of LEDs
		call	led2
		call	led6
		call	led5
		call	led3
		call	led4
		return

led1	bsf		LATA,RA0	;blinks led1
		bcf		LATA,RA6
		bsf		TRISA,7
		call	Delay
		call	alloff
		return

led2	bcf		LATA,RA0	;blinks led2
		bsf		LATA,RA6
		bsf		TRISA,7
		call	Delay
		call	alloff
		return

led3	bsf		TRISA,0		;blinks led3
		bsf		LATA,RA6
		bcf		LATA,RA7
		call	Delay
		call	alloff
		return

led4	bsf		TRISA,0		;blinks led4
		bcf		LATA,RA6
		bsf		LATA,RA7
		call	Delay
		call	alloff
		return

led5	bcf		LATA,0		;blinks led5
		bsf		TRISA,6
		bsf		LATA,RA7
		call	Delay
		call	alloff
		return

led6	bsf		LATA,0		;blinks led6
		bsf		TRISA,6
		bcf		LATA,RA7
		call	Delay
		call	alloff
		return

alloff	clrf	TRISA		;all leds off
		clrf	LATA
		return

Delay	movlw	0x01
		movwf	d1
		movlw	0x7f
		movwf	d2
		movlw	0x01
		movwf	d3
Delay_0	decfsz	d1,f
		goto	$+6
		decfsz	d2,f
		goto	$+6
		decfsz	d3,f
		goto	Delay_0
		return

		end
 
Last edited:
I just edited the first post to add the code, rather than post it all again. There's nothing much in there that's very interesting. All the irq stuff was in the init and isr. But you never know. You might spot something that I missed.

Try setting the int vector to 0x018
I've got priority interrupts disabled, so all interrupts should vector to $08, right?
 
You should, try using the debugger. You never know if a sneaky bit is set or not.

One note is
Code:
isr1    tstfsz    INTCON,INT0IF    ;is it INT0?

should be

isr1    btfsc    INTCON,INT0IF    ;is it INT0?
tstfsz is a byte test instruction, btfsc is a bit test.

I modified your source and removed the LED stuff, seems the btfsc should do the trick.
Code:
    list    p=18F1320
    include    <p18f1320.inc>
    CONFIG    OSC=INTIO2,WDT=OFF,MCLRE=ON,LVP=OFF,DEBUG=ON
        org    0x0000
        goto    init

        org    0x0008        ;Interrupt Service Routine
isr1    nop                     ;put a breakpoint here
        btfsc    INTCON,INT0IF    ;is it INT0?
        goto    int0        ;yes, go handle it    
int2    nop            ;no, handle the INT2 interrupt
        nop            ;nop's are temporary
        bcf    INTCON3,INT2IF
        retfie    FAST
int0    bcf    INTCON,INT0IF    ;clear INT0 flag
        retfie    FAST
init    movlw   0x72
        movwf   OSCCON
        movlw    0x7f        ;set PortA to all digital
        movwf    ADCON1
        clrf    TRISA        ;set PortA pins to output
        movlw    b'00100101'    ;set PortB pins (switches = inputs)
        movwf    TRISB
        clrf    LATA        ;turn off all LEDs
        clrf    INTCON2        ;enable weak pull-ups and falling edges
        movlw    b'10010000'    ;enable INT2 interrupt
        movwf    INTCON3
        bcf    RCON,IPEN    ;disable irq priority levels
        movlw    b'10010000'    ;enable interrupts (INT0)
        movwf    INTCON
Main    bra     $
        end
 
Last edited:
blueroomelectronics said:
tstfsz is a byte test instruction, btfsc is a bit test.
Also, in my opinion the ISR was too long. After your mod it's short enough. Address locations 0x08 to 0x17 are assigned to high priority interrupts in the PIC18, I usually place the interrupt code elsewhere in program memory and use a GOTO (at location 0x08) to jump there.

EDIT: I'm talking of the original program, futz, correct me if I'm wrong. Anyway, it's good practice to use the techique I've described, especially if the ISR will be longer.
 
Last edited:
eng1 said:
Also, in my opinion the ISR was too long. After your mod it's short enough. Address locations 0x08 to 0x17 are assigned to high priority interrupts in the PIC18, I usually place the interrupt code elsewhere in program memory and use a GOTO (at location 0x08) to jump there.
Probably, but with priority interrupts disabled it doesn't matter how long it is. I'm a newb so it's not well written, and I can see that it's a bad habit to get into. It'll byte me on the a$$ later, I'm sure. :D
 
futz said:
Probably, but with priority interrupts disabled it doesn't matter how long it is.
Well, I don't usually use interrupt priorities, so all interrupts are high priority by default; but I always redirect the ISR with a GOTO instruction placed at location 0x08, as I said, and jump over address 0x18... just my habit, perhaps? I am not sure that the h.p. ISR can spread over address 0x18 even if you don't use priorities.
 
Last edited:
eng1 said:
Well, I don't usually use interrupt priorities, so all interrupts are high priority by default; but I always redirect the ISR with a GOTO instruction placed at location 0x08, as I said, and jump over address 0x18... just my habit, perhaps? I am not sure that the h.p. ISR can spread over address 0x18 even if you don't use priorities.
It's a good habit. I'm not gonna argue with that. But with priority interrupts disabled you CAN ignore the 0x18 thing. It doesn't get used, so your ISR can use that memory if you want.

My little program does it and works perfect (now that my foolish coding error has been fixed).
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top