PDA

View Full Version : Interrupt doesn't fire



Normnet
- 19th May 2009, 05:17
Why doesn't interrupt fire?
SerOut2 shows timer is running.
MPASM
PBP v2.5C
PB PL

Norm



' 18F452

@ __CONFIG _CONFIG1H, _OSCS_OFF_1H & _HSPLL_OSC_1H
@ __CONFIG _CONFIG2L, _BORV_45_2L & _BOR_ON_2L & _PWRT_ON_2L
@ __CONFIG _CONFIG2H, _WDT_ON_2H
@ __CONFIG _CONFIG4L, _STVR_ON_4L & _LVP_OFF_4L & _DEBUG_OFF_4L


DEFINE OSC 40 ' REQUIRES PLL ' USE 10 MHz CRYSTAL & DECLARE: XTAL = 40
PAUSE 1000 'ALLOW POWER TO STABILIZE

Clear

@wTimer1 = TMR1L
wTimer1 var word EXT
LED VAR PortA.1
i VAR WORD

ADCON1 = %00001111 'ALL_DIGITAL

'********************
'INTERRUPT REGISTER'S
wTIMER1 = 0
RCON.7 = 0 ' 0 DISABLES PRIORITY LEVELS ON INTERRUPTS (16F COMPATABILITY)
T1CON = %10000001 '%xx00xxx = 1:1 PRESCALE
PIE1 = %00000001 'enable TMR1 overflow interrupt
INTCON = %11000000 'enable global and peripheral interrupts
'********************

TRISA.5 = 0
TRISA.4 = 1
TRISA.3 = 1
TRISA.2 = 0
TRISA.1 = 0
TRISA.0 = 0
TRISB=%00000000
TRISC=%00010000 ' xxx1xxxx MSSP SPI data in
TRISD=%00000000
TRISE.2 = 1
TRISE.1 = 1
TRISE.0 = 1


ON INTERRUPT GoTo SET_PORT_INTERRUPT
GOTO MAIN


'**** INTURRUPT ROUTINE ****
Disable ' Disable interrupts during interrupt handler
SET_PORT_INTERRUPT:

SerOut2 PORTA.2,16416,["SET_PORT_INTERRUPT",13]
TOGGLE LED
wTimer1 = 500

INTCON.2 = 0 ' Reset timer interrupt flag
Resume
'**** END INTURRUPT ROUTINE ****


MAIN:

FOR i = 1 TO 100
PAUSE 10
NEXT

SerOut2 PORTA.2,16416,["MAIN LOOP wTimer1 = ",DEC wTimer1,13]
' 16416 = 19200

GOTO MAIN
END

Bruce
- 19th May 2009, 07:36
Hi Norm,

You have interrupt checking disabled. Add ENABLE after RESUME in your interrupt handler.

Also PIR1.0 is the Timer1 interrupt flag bit. Not INTCON.2....;o}

Normnet
- 19th May 2009, 10:04
Works good.

Require fastest interrupt.

Does this interrupt execute at end of current command or does it immediately
jump to the interrupt handler?

Main code will follow a "Repeat : Until wTIMER1 < 65500" so interrupt cannot disrupt.

Norm

Bruce
- 19th May 2009, 15:59
With ON INTERRUPT it only checks for an interrupt condition and jumps to your interrupt
handler after each PBP command has finished. If you need fast reaction times to
interrupts, use DTs' interrupt code or use assembler interrupts.

FYI: With Timer1 in 16-bit read/write mode, you don't want to use EXT to create your word
to read/write Timer1. EXT works on the low byte first, then the high byte.

With RD16 set, to write to Timer1, you write to TMR1H first, then write to TMR1L. Reading
Timer1 with RD16 set, you read TMR1L first, then read TMR1H.

In 8-bit mode EXT will work fine. In 16-bit mode it won't since you're always writing to and
reading low byte first.

Normnet
- 20th May 2009, 08:53
Fastest Interrupt?




'18F452

@ __CONFIG _CONFIG1H, _OSCS_OFF_1H & _HSPLL_OSC_1H
@ __CONFIG _CONFIG2L, _BORV_45_2L & _BOR_ON_2L & _PWRT_ON_2L
@ __CONFIG _CONFIG2H, _WDT_ON_2H
@ __CONFIG _CONFIG4L, _STVR_ON_4L & _LVP_OFF_4L & _DEBUG_OFF_4L

DEFINE OSC 40 ' REQUIRES PLL ' USE 10 MHz CRYSTAL & DECLARE: XTAL = 40
PAUSE 1000 'ALLOW POWER TO STABILIZE

Clear

LED VAR PortA.1
i VAR WORD
wREAD_TR1 VAR WORD
wWRITE_TR1 VAR WORD
wWRITE_TR1 = 1000

ADCON1 = %00001111 'ALL_DIGITAL

'********************
'INTERRUPT REGISTER'S
RCON.7 = 0 ' 0 DISABLES PRIORITY LEVELS ON INTERRUPTS (16F COMPATIBILITY)
' T1CON = %10000001 '%xx00xxx = 1:1 PRESCALE
T1CON = %10110001 '%xx00xxx = 1:8 PRESCALE
PIE1 = %00000001 'enable TMR1 overflow interrupt
INTCON = %11000000 'enable global and peripheral interrupts
'********************

TRISA.5 = 0
TRISA.4 = 1
TRISA.3 = 1
TRISA.2 = 0
TRISA.1 = 0
TRISA.0 = 0
TRISB=%00000000
TRISC=%00010000 ' xxx1xxxx MSSP SPI data in
TRISD=%00000000
TRISE.2 = 1
TRISE.1 = 1
TRISE.0 = 1

' Define interrupt handler
DEFINE INTHAND myint

GOTO MAIN

'**** ASSEMBLY INTERRUPT ROUTINE ****
Asm
myint
EndAsm

'SerOut2 PORTA.2,16416,["SET_PORT_INTERRUPT",13]
TOGGLE LED
TMR1H = wWRITE_TR1.HIGHBYTE
TMR1L = wWRITE_TR1.LOWBYTE

Asm
bcf PIR1, 0 ; Clear interrupt flag
retfie ; Return from interrupt
EndAsm
'**** END ASSEMBLY INTURRUPT ROUTINE ****


MAIN:
'wWRITE_TR1 = 32000
wWRITE_TR1 = 500

FOR i = 1 TO 1000
PAUSE 1
NEXT

REPEAT
wREAD_TR1.LOWBYTE = TMR1L
wREAD_TR1.HIGHBYTE = TMR1H
UNTIL wREAD_TR1 < 50000 'TMR1 NON INTERFEARANCE WITH SEROUT2

SerOut2 PORTA.2,16416,["MAIN LOOP wREAD = ",DEC wREAD_TR1,13]
' 16416 = 19200
GOTO MAIN


END