PDA

View Full Version : Questions on Darrel's Instant Interrupts



rsocor01
- 4th November 2013, 14:23
Hi,

I've been using Darrel's Instant Interrupts for quite some time without any problems. The thing is that I've been using it with only one interrupt and one interrupt handler :cool:. Now, I'm working in a project where I need to use two interrupt handlers. Looking at Darrel's example in

http://www.picbasic.co.uk/forum/showthread.php?t=3251&p=17477#post17477

There are some question that I have :confused:.

1.) How do I know which one is a high priority interrupt and which one is a low priority interrupt? My program is a very time sensitive application.

2.) What happens when the program is servicing one interrupt handler and then another handler needs to be serviced? What happen to the interrupt counters in this case?

3.) My application is very time sensitive, so I need one of the interrupts to take priority. How do I do that?

Thank you,

Robert

LinkMTech
- 4th November 2013, 18:52
I've made some observations using multiple interrupts without specifying High or Low interrupt:

The interrupts were handled in the order as listed and if another interrupt occurred while the first was busy
then the latter would proceed immediately afterwards. Cool stuff!

The High/Low priorities probably come in when you need an interrupt to interrupt an interrupt. :D

rsocor01
- 6th November 2013, 12:57
Thank you Louie for your help. I will have to experiment and play with my interrupts to really understand what's going on :D.

I'm using a 16F1939. I found out from the melabs.com support help that a true high priority interrupt could only be achieved on the 18F's chips. That's not good for what I wanted to do, but I can find some workaround it.

The chip I'm using only has one timer, TMR1, that is 16 bits in resolution. All the other timers are only 8 bits in resolution. It would have been nice to have more than one timer with a 16 bits resolution.

Robert

rsocor01
- 15th November 2013, 07:25
Hi. I'm still pulling my hair out trying to combine two or more instant interrupts :eek:. The following code is from Darrel' example


LED1 VAR PORTD.0
LED2 VAR PORTD.1

INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _ToggleLED1, PBP, yes
INT_Handler TMR0_INT, _ToggleLED2, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor

INT_ENABLE TMR0_INT ; enable Timer 0 interrupts
INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts
ENDASM

OPTION_REG = OPTION_REG & $80 | 1 ' Set TMR0 Prescaler to 256, leave RBPU alone

Main:
GOTO Main

'---[INT - interrupt handler]---------------------------------------------------
ToggleLED1:
TOGGLE LED1
@ INT_RETURN

'---[TMR0 - interrupt handler]-------------------------------(Blinky Light)------
T0Count VAR WORD
ToggleLED2:
T0Count = T0Count + 1
IF T0Count = 512 THEN T0Count = 0 : TOGGLE LED2
@ INT_RETURN


I eliminated the Elapsed_INT.bas interrupt from his example. I'm using a 16F193x chip, so I know I can't have high priority interrupts. Only with 18F chips you can have those. So, my next questions are very simple, I hope.

1) When either one of the interrupt handlers is servicing it's interrupt, what happens to the other counter? Does it stop until the other interrupt handler is over, or does it keep counting?

2) And, what happens if an interrupt counter overflows while the other interrupt handler is been serviced? Does that counter goes back to zero and starts counting again, or it just waits until the other handler is over?


I hope I explained myself clear and that somebody can enlighten me here :o.

Thank you,

Robert

HenrikOlsson
- 15th November 2013, 08:20
Hi,

I'm using a 16F193x chip, so I know I can't have high priority interrupts. Only with 18F chips you can have those. So, my next questions are very simple, I hope.
Well, that depends on how you look at it. You can't have interrupts with different priorities. Consider ALL interrupts as high priority.

Your code doesn't make real sense because you're declaring two interrupts, INT_INT and TMR0_INT but then you enable TMR0_INT and TMR1_INT


1) When either one of the interrupt handlers is servicing it's interrupt, what happens to the other counter? Does it stop until the other interrupt handler is over, or does it keep counting?
Since TMR0 and TMR1 are hardware timer/counters they will "count" no matter what the software is doing (short of disabling the TMR/Counter of course). If one of them overflows and trips its interrupt while the other ISR is executing the "new" interrupt will be flagged and serviced when the current ISR is finished. DT-Ints handles this for you.

However, if there would've been TWO or more interrupts triggered from the same source during the time that another interrupt is serviced the "new" interrupt will only be serviced once. For example, your timer interrupt fires and the ISR for that interrupt is executed. While the timer ISR is executing the external interrupt fires, this is then flagged to be executed as soon as the timer ISR is done. But before the code gets to servicing the external interrupt it fires again - this second external interrupt request will then be "lost".


2) And, what happens if an interrupt counter overflows while the other interrupt handler is been serviced? Does that counter goes back to zero and starts counting again, or it just waits until the other handler is over?

I think I covered that in [1] above.

/Henrik.

LinkMTech
- 15th November 2013, 21:26
Correct your interrupts as Henrik mentioned and I also noticed your T0count variable buried between the two interrupts and might be okay? but thought I'd point that out.



LED1 VAR PORTD.0
LED2 VAR PORTD.1

INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _ToggleLED1, PBP, yes
INT_Handler TMR0_INT, _ToggleLED2, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor

INT_ENABLE TMR0_INT ; enable Timer 0 interrupts
INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts
ENDASM

OPTION_REG = OPTION_REG & $80 | 1 ' Set TMR0 Prescaler to 256, leave RBPU alone

Main:
GOTO Main

'---[INT - interrupt handler]---------------------------------------------------
ToggleLED1:
TOGGLE LED1
@ INT_RETURN

'---[TMR0 - interrupt handler]-------------------------------(Blinky Light)------
T0Count VAR WORD
ToggleLED2:
T0Count = T0Count + 1
IF T0Count = 512 THEN T0Count = 0 : TOGGLE LED2
@ INT_RETURN


Another thing to keep in mind; the timers need to be updated each time at the interrupt if it was preloaded with something other than default. Incomplete example:



T0H = $48 ' 1sec overflow value for TMR0
T0L = $E4

' After DT_INTS setup
T0CON = %00000111 ' TMR0 OFF and 1:256 prescaler. Bit7 ON/OFF
@ INT_ENABLE TMR0_INT ; Enable Timer 0 interrupts

Timer0:
TMR0H = T0H ' High byte loaded
TMR0L = T0L ' Low byte loaded
TMR0_OVF = TMR0_OVF + 1 ' Overflow increment counter
IF TMR0_OVF = TOT_0 THEN ' Increment counter reaches TOT value
'Do something
ENDIF
@ INT_RETURN

rsocor01
- 16th November 2013, 00:48
Thank you guys. Actually the code I posted was some code to illustrate my point. But obviously is had some errors. Please, disregard that code. I'm using PBP 2.60 and a PIC16F1939. My actual code is as follows.


'************************************************* ***************
'* SET UP DT INTERRUPTS *
'************************************************* ***************
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR2_INT, _ClockCounter, PBP, yes
INT_Handler T1GATE_INT, _CheckSensors, PBP, yes
endm
INT_CREATE ;Creates the interrupt processor
ENDASM

'************************************************* ***************
'* TMR0 TIME BASE SETUP *
'* ENABLE TMR0 TIMER INTERRUPTS *
'************************************************* ***************
OPTION_REG = %01000010 'Bit 2-0, 110= prescaler rate 1:8 (TMRO INTERRUPTS EVERY 0.512 mSec)
'Bit 7, enable individual pull-ups in port B.
INTCON = %01100000 'enable TMR0 interrupts. enables all unmasked peripheral interrupts
T1CON = %11000101 'Timer1 initialization
T1GCON = %11100001 'Timer1 gate init /Toggle Mode/TMR0 time base
PIR1.7 = 0 'Clear Gate Interrupt Flag. Timer1 gate is active (TMR1GIF BIT)
PIE1.7 = 1 'Enables the Timer1 Gate Acquisition complete interrupt (TMR1GIE BIT)

PIE1.1 = 1 'Enables the Timer2 to PR2 match interrupt
T2CON = %00000100 'Timer2 is on

TMR0 = 0 'TMR0 overflows every (256-TMRO)*(Prescaler rate)(4*(1/16)uS)=0.512 mSec.

INTCON = %10100000 'Enable Interrupts

@ INT_ENABLE TMR2_INT
@ INT_ENABLE T1GATE_INT


'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
'< INTERRUPT ROUTINES >
'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

CheckSensors:

T1CON.0 = 0 'Stop/Clears Timer1 before reading TMR1

' DO SOMETHING.......

TMR1L = 0 'Reset Timer1
TMR1H = 0
T1CON.0 = 1 'Restart/Enable Timer1 (TMR1ON BIT)
TMR0 = 0 'RESET TMR0 TO 0
INTCON.2 = 0 'Re-enable TMR0 interrupts. Bit 2, 0= clears overflow, 1= overflow ocurred

@ INT_RETURN


ClockCounter:

TOGGLE PORTC.0 '######## TESTING #########

TMR2 = 0 'Reset TMR2 register back to zero.
PIR1.1 = 0 'A timer2 to PR2 match occurred and it's been cleared in software
@ INT_RETURN







Hi,

Well, that depends on how you look at it. You can't have interrupts with different priorities. Consider ALL interrupts as high priority.



Well, ideally I would like TMR2 to be of a high priority since it is keeping record of the timming. I would like the handler of TMR2 to interrupt the other handler if posible. I included the line "TOGGLE PORTC.0 '######## TESTING #########" to be able to see in an oscilloscope what is going on. When connecting PORTC.0 to the scope, this is kind of what I saw.

7135

Obviously, the handler for TMR2 is not been taken care of all the time, which is what I would like it to do. Making the other handler CheckSensors smaller in size is pretty much impossible right now. This is a 15k words program and I would have to rewrite everything again.

Any ideas? Suggestions?

Robert

richard
- 16th November 2013, 01:43
the ClockCounter interrupt could be made a bit faster since it uses no pbp code it can be called an asm interrupt and secondly
the interrupt flag is being cleared twice

INT_Handler TMR2_INT, _ClockCounter, ASM, no


might help.

ps
if the do something in the checksensor int takes longer than the tmr2 time out period you are wasting your time ever trying to get it to work.
why not just set a flg here and then process the "do something " in an interruptable routine

rsocor01
- 17th November 2013, 07:53
ps
if the do something in the checksensor int takes longer than the tmr2 time out period you are wasting your time ever trying to get it to work.

Well, I'm learning something new which is the whole idea :cool:. But, yes it looks like you are right about that. The only option to really make it work would be to upgrade to an 18F pic, which I've been told can support a high priority interrupt. In other words, it can interrupt an interrupt. Please, somebody correct me if I'm wrong about this.


the ClockCounter interrupt could be made a bit faster since it uses no pbp code it can be called an asm interrupt and secondly the interrupt flag is being cleared twice

What do you mean by no PBP code? Isn't TOGGLE a PBP command?

Also, where do you see that I'm clearing the interrupt flag twice?


why not just set a flg here and then process the "do something " in an interruptable routine

That would be the best solution. I have to start working on that.

Robert

richard
- 17th November 2013, 08:24
robert
you are right about the toggle but I assumed I that in the "production" version that line would be removed. if you can do this the interrupt latency can be reduced heaps .i'm sure henrik has a posting about this issue for his pid project , its worth looking at .
and yes pic18 high priority int can interrupt a low priority int but imo its better policy to make interrupts a short as possible and set flags to indicate that further processing is necessary .
what clock speed are you using ? the chip can do 32mhz that helps too

isn't pir1.1=0 resetting the tmr2 int flag
and
_Handler TMR2_INT, _ClockCounter, PBP, yes
the yes on the end resets the flag too
its a bit redundant if time is that critical

rsocor01
- 18th November 2013, 07:44
what clock speed are you using ? the chip can do 32mhz that helps too

I'm using 16MHz, but I will try 32MHz right away like you suggested. Also, I will make my interrupt routine as short as possible.


isn't pir1.1=0 resetting the tmr2 int flag
and
_Handler TMR2_INT, _ClockCounter, PBP, yes
the yes on the end resets the flag too
its a bit redundant if time is that critical


Hmm, I wasn't sure what that yes was for :o.