PDA

View Full Version : 16F1827 ASM Interrupt



abbtech
- 15th February 2011, 22:37
I am using a 16F1827 I need to use the ASM style interrupt routine to free up some program space. There are two pins that will fire if they go high. Either fires the interrupt properly, the existing output can be turned low properly but for some reason changing the input to an output and making it high is not functioning and the LED flashing routine doesn't change based on the interrupt as it should. I am sure I am missing something simple but I just can't seem to figure it out...

The interrupt is very simple, all I am needing to do is:

Change an input to an output
Make the new output high
Make an existing output low
Determine which one of two interrupts got tripped and goto a LED flashing routine for user feedback
Continue in an endless loop flashing the indication LED




'setup the interrupts
DEFINE INTHAND intRoutine 'where to go when an interrupt fires
IOCBP = %00001100
INTCON = %10011000 ' Enable interrupt





;the following is the interrupt routine
ASM
intRoutine

;turn off interrupts
MOVLW b'00000000'
MOVWF INTCON

;disable all interrupts that were previously enabled
MOVLW b'00000000'
MOVWF IOCBP

;RB3 is currently an input, change it to an output and make it high
;prior to this operation TRISB would be 11111110
MOVLW b'11110110'
MOVWF TRISB

;turn on RB3 (doesn't go high)
BSF PORTB,3

;turn off detection power (this is working fine)
BCF PORTA,0

;check to see what tripped the interrupt
;(this always goes to detectionFlash even when lighting activated the interrupt)
;IOCBF.2 = detection
;IOCBF.3 = lighting
BTFSS IOCBF,3
GOTO detectionFlash
GOTO lightingFlash

lightingFlash
BSF _overCurrentLED
CALL Delay
BCF _overCurrentLED
CALL Delay
CALL Delay
GOTO lightingFlash

detectionFlash
BSF _overCurrentLED
CALL Delay
BCF _overCurrentLED
CALL Delay
BSF _overCurrentLED
CALL Delay
BCF _overCurrentLED
CALL Delay
CALL Delay
GOTO detectionFlash

endASM

Darrel Taylor
- 15th February 2011, 23:07
When it gets to the ISR, it could be in any bank at the time.
INTCON is available from any bank, but ...

PORTB is in BANK0.
TRISB is in BANK1.
IOCBF is in BANK7.

Use BSR to change banks.

cncmachineguy
- 16th February 2011, 00:40
Could also use BANKSEL reg_name

For instance:


BANKSEL TRISB
bla
bla
bla
BANKSEL IOCBF
bla
bla
bla


works just like BSR but no need to lookup the bank number.

abbtech
- 16th February 2011, 01:03
Thanks Darrel that clears up why things were not working as I expected!

Most things are working great now except one very strange thing. The LED that is to be used to indicate this interrupt state (on RB0) works fine when RB3 has initiated the interrupt however when RB2 has initiated the interrupt when I attempt to flash RB0 it somehow turns off RB2 which is the pin that was changed from an input to an output and made high.

In the code shown below I am using the wrong LED (RA6) to indicate the RB2 interrupt condition and everything works fine other than the wrong LED flashing.

I am thinking that there is some strange property that RB0 has but I am very confused why it doesn't mess up when RB3 has initiated the interrupt.



;the following is the interrupt routine
ASM
intRoutine

;turn off interrupts
MOVLW b'00000000'
MOVWF INTCON

;disable all interrupts that were previously enabled
MOVLB 0x07 ;select BANK 7
MOVLW b'00000000'
MOVWF IOCBP

;RB3 is currently an input, change it to an output and make it high
;prior to this operation TRISB would be 11111110
MOVLB 0x01 ;select BANK 1
MOVLW b'11110110'
MOVWF TRISB

;turn on RB3 (doesn't go high)
MOVLB 0x00 ;select BANK 0
BSF PORTB,3

;turn off detection power (this is working fine)
BCF PORTA,0

;check to see what tripped the interrupt
;IOCBF.2 = detection
;IOCBF.3 = lighting
MOVLB 0x07 ;select BANK 7
BTFSS IOCBF,3
GOTO detectionFlash
GOTO lightingFlash

lightingFlash
MOVLB 0x00 ;select BANK 0
BSF PORTB,0
CALL Delay
BCF PORTB,0
CALL Delay
CALL Delay
GOTO lightingFlash

detectionFlash
MOVLB 0x00 ;select BANK 0
BSF PORTA,6 ;this is the wrong LED but works properly when this one is selected instead of PORTB,0
CALL Delay
BCF PORTA,6
CALL Delay
BSF PORTA,6
CALL Delay
BCF PORTA,6
CALL Delay
CALL Delay
GOTO detectionFlash

endASM

abbtech
- 16th February 2011, 06:47
Thanks for the code example cncmachineguy.

I have it working properly now. I am thinking there must be some type of race condition with the way I had it coded. I have added a delay right after B3 was made high and everything works fine. Without the delay B3 goes low as soon as B0 is made high.

Thanks for the help guys!