PDA

View Full Version : Handeling multiple Interrupts



BobSpencerr
- 27th February 2007, 23:15
Hi people,

I have a 16f877 in which I am trying to use different interrupts for the timers.
My interrupt code is below but it wont do what I need. If I remove timer1 section then the timer0 section works and visa versa.
Can you see anything I have done wrong?

DEFINE INTHAND ROLLOVER

wsave var BYTE $020 SYSTEM
wsave1 var BYTE $0a0 SYSTEM
wsave2 var BYTE $120 SYSTEM
wsave3 var BYTE $1a0 SYSTEM
ssave var BYTE BANK0 SYSTEM
psave var BYTE BANK0 SYSTEM
i_hour var BYTE
i_minu var BYTE
i_sec var BYTE
i_tic var BYTE
i_sec0 var BYTE
i_tic0 var BYTE
'PowerLed var Portd.2

GOTO AFTERINT 'Jump past interrupthandler

asm

rollover
movwf wsave
swapf STATUS, W
clrf STATUS
movwf ssave
movf PCLATH, W
movwf psave

; interrupt code follows here
btfsc PIR1,0
goto timer1Interrupt
btfsc INTCON,2
goto timer0Interrupt
goto restoreall

timer1Interrupt
;Timer 1
movlw 0x58
movwf TMR1L
movlw 0x9e ;restart timer from ffff - 9e58 => 5Hz if using 4MHz
movwf TMR1H
decfsz _i_tic,f
goto slutint1
incf _i_sec,f
movlw 5 ;5 = 1Hz if using 4MHz (change to 10 for 8MHz and so on)
movwf _i_tic
movf _i_sec,w
slutint1
bcf PIR1,0 ;zero tmr1 interrupt flag
endasm
if i_sec = 60 then
i_sec = 0
endif
toggle portd.2
asm
goto restoreall

timer0Interrupt
; Timer 0
movlw 00010000
movwf option_reg
decfsz _i_tic0,f
goto slutint2
incf _i_sec0,f
movlw 1 ;5 = 1Hz if using 4MHz (change to 10 for 8MHz and so on)
movwf _i_tic0
movf _i_sec0,w
slutint2
bcf intcon,2
bcf PIE1,0 ;zero tmr0 interrupt flag
endasm
if i_sec0 = 60 then
i_sec0 = 0
endif
toggle portd.3
asm
goto restoreall

;end of interruptcode
; restorecode follows here
restoreall
movf psave,w ;restore
movwf PCLATH
swapf ssave,w
movwf STATUS
swapf wsave,f
swapf wsave,w
retfie
endasm


AFTERINT:

INTCON = %00000000 'all interrupts off
PIR1 = %00000000 'zero tmr1 interrupt flag
PIE1 = %00000001 'enable timer1 interrupt
TMR1L = $58
TMR1H = $9e
i_sec = 0
i_sec0 = 0
i_tic = 5 'this value should be the same as the value of line 8 in the ISR
i_tic0 = 5
T1CON = %00110001 'timer1 on, prescaler=1/8
INTCON = %11010000 'interrupt on

skimask
- 27th February 2007, 23:20
My interrupt code is below but it wont do what I need. If I remove timer1 section then the timer0 section works and visa versa.
Can you see anything I have done wrong?

Off the top of my head, and maybe to give you a head start, and I haven't looked thru the code entirely, TMR0 interrupts happen a lot more often than TMR1. Maybe your int routine kicks out without checking TMR1 before it kicks out. Also, when the int routine does kick out, TMR0 might have kick over again, another int for TMR0, but TMR1 doesn't get hit.
Before you kick out of the TMR0 routine, go back and check your INT bits again. TMR0 might not be there, but TMR1 might. And you need a loop to run in the AFTERINT portion. Just a '10 goto 10' type thing will suffice.
And again...I'll look a bit harder at your code and see if I can spot anything obvious...or not...

BobSpencerr
- 27th February 2007, 23:31
Thanks for the time
Appreciate it

BobSpencerr
- 28th February 2007, 01:31
Now that I think about it, skimask
The timer0 interrupt is the one not being delt with and not the other way around. If the tmr0 int happens more often then I would expect to see it happen and maybe miss the others.

Would you not agree?

skimask
- 28th February 2007, 01:56
Now that I think about it, skimask
The timer0 interrupt is the one not being delt with and not the other way around. If the tmr0 int happens more often then I would expect to see it happen and maybe miss the others.

Would you not agree?

Isn't that what I said? :)

"TMR0 interrupts happen a lot more often than TMR1."

The only reason I said TMR0 would happen more often is because it's 8 bit (usually). At any rate, you probably need to re-enter the interrupt routine to check on other interrupt sources in case they happen in the middle of your initial interrupt routine.

BobSpencerr
- 28th February 2007, 01:58
Hmmm.....
Sort of. But if what you say is correct then the TMr0 interrupt would be seen and not the tmr1.
I am seeing the Tmr1 and not the Tmr0.

Am I missing something in what your saying?

skimask
- 28th February 2007, 01:59
Hmmm.....
Sort of. But if what you say is correct then the TMr0 interrupt would be seen and not the tmr1.
I am seeing the Tmr1 and not the Tmr0.

Am I missing something in what your saying?

Hold on....thinking....

skimask
- 28th February 2007, 02:03
Your original code with a few changes.

DEFINE INTHAND ROLLOVER

wsave var BYTE $020 SYSTEM : wsave1 var BYTE $0a0 SYSTEM : wsave2 var BYTE $120 SYSTEM : wsave3 var BYTE $1a0 SYSTEM : ssave var BYTE BANK0 SYSTEM : psave var BYTE BANK0 SYSTEM
i_hour var BYTE : i_minu var BYTE : i_sec var BYTE : i_tic var BYTE : i_sec0 var BYTE : i_tic0 var BYTE : 'PowerLed var Portd.2

GOTO AFTERINT 'Jump past interrupthandler

asm
rollover
movwf wsave
swapf STATUS, W
clrf STATUS
movwf ssave
movf PCLATH, W
movwf psave

; interrupt code follows here
recheckints
btfsc PIR1,0
goto timer1Interrupt
btfsc INTCON,2
goto timer0Interrupt
goto restoreall

timer1Interrupt
;Timer 1
movlw 0x58
movwf TMR1L
movlw 0x9e ;restart timer from ffff - 9e58 => 5Hz if using 4MHz
movwf TMR1H
decfsz _i_tic,f
goto slutint1
incf _i_sec,f
movlw 5 ;5 = 1Hz if using 4MHz (change to 10 for 8MHz and so on)
movwf _i_tic
movf _i_sec,w
slutint1
bcf PIR1,0 ;zero tmr1 interrupt flag
endasm
if i_sec = 60 then
i_sec = 0
endif
toggle portd.2
goto recheckints
asm

timer0Interrupt
; Timer 0
movlw 00010000
movwf option_reg
decfsz _i_tic0,f
goto slutint2
incf _i_sec0,f
movlw 1 ;5 = 1Hz if using 4MHz (change to 10 for 8MHz and so on)
movwf _i_tic0
movf _i_sec0,w
slutint2
bcf intcon,2
bcf PIE1,0 ;zero tmr0 interrupt flag
endasm
if i_sec0 = 60 then
i_sec0 = 0
endif
toggle portd.3
goto recheckints
asm

;end of interruptcode
; restorecode follows here
restoreall
movf psave,w ;restore
movwf PCLATH
swapf ssave,w
movwf STATUS
swapf wsave,f
swapf wsave,w
retfie
endasm

AFTERINT:

INTCON = %00000000 'all interrupts off
PIR1 = %00000000 'zero tmr1 interrupt flag
PIE1 = %00000001 'enable timer1 interrupt
TMR1L = $58 : TMR1H = $9e : i_sec = 0 : i_sec0 = 0
i_tic = 5 'this value should be the same as the value of line 8 in the ISR
i_tic0 = 5
T1CON = %00110001 'timer1 on, prescaler=1/8
INTCON = %11010000 'interrupt on

MAINLOOP:
pauseus 1 : goto mainloop

END '<- VERY Important to have this part!

Try that. Added new labels to recheck the interrupt flags and a loop for the program to run while it waits for stuff to handle.

BobSpencerr
- 28th February 2007, 02:08
I realy do appreciate your help here.
As you no doubt know, it can get realy frustrating when things Should work but dont.

Ill try this code tonight

skimask
- 28th February 2007, 03:46
I realy do appreciate your help here.
As you no doubt know, it can get realy frustrating when things Should work but dont.

Ill try this code tonight



Ok, it's this thread.
Hurry up! Get on it! Some readers (me in particular) are dying to know! :)

BobSpencerr
- 28th February 2007, 03:50
I work in a University.
The programmer is at home.
I am itching to try it too but we will have to be patient now wont we.

BobSpencerr
- 28th February 2007, 08:36
No good dude.
Didnt work either.

I am going to rewrite it all starting with tmr0 interrupt when I can find info on its use.
Then I will impliment the tmr1.

Thanks anyway for the time.

BobSpencerr
- 28th February 2007, 23:08
Yes.........
after 3 hours of looking at the same thing I spotted it.
I miised a line that starts the TMR0.
The option register had to be set and she sprang into life.

Thanks for the help.
Now onto the next step.

skimask
- 28th February 2007, 23:15
Yes.........
after 3 hours of looking at the same thing I spotted it.
I miised a line that starts the TMR0.
The option register had to be set and she sprang into life.

Thanks for the help.
Now onto the next step.

Sweet deal. I was just about to start rewriting things...saved me some time...

BobSpencerr
- 1st March 2007, 01:07
Thanks for the help mate.

Ive started a real bun fight in the other forum about Darrel Taylors software.
I must be more careful about how I word questions in here in future.


Anyway, thanks again for the help. I can deal with all of the interrupts easily now.

skimask
- 1st March 2007, 01:12
Thanks for the help mate.

Ive started a real bun fight in the other forum about Darrel Taylors software.
I must be more careful about how I word questions in here in future.


Anyway, thanks again for the help. I can deal with all of the interrupts easily now.

I don't think there's might of a 'bun fight' (WTH?) going on...much anyways.. :)