Try asking here 16-Bit Core (instructions, reset, WDT, specifications...)
Try asking here 16-Bit Core (instructions, reset, WDT, specifications...)
One nice thing about 18F's is that you don't have to save W, BSR and STATUS when using High Priority Interrupts.
The hardware does it for you whenever an interrupt occurs by saving the values to "Shadow" registers.
At the end of the ISR just ...
RETFIE FAST ; return from interrupt, restore shadows
and they all get restored.
A plain RETFIE does not.
When using Low Priority interrupts you do need to save them.
But they can be anywhere in RAM, just use MOVFF to save/restore them.
DT
This is helpful as well http://ww1.microchip.com/downloads/e...Doc/39500a.pdf
You can use the fast return with auto restore for low pri ints too, but not if you have high pri & low pri interrupts enabled at the same time. The high pri interrupt can corrupt shadow values saved during the low pri interrupt.
Last edited by Bruce; - 15th May 2010 at 22:10.
That is so true ...
But so far, I haven't found a possible reason for anyone to have Low Priority interrupts, without High Priority.
Consequently, DT_INTS crashes if you try to only use LP ints, mainly because I haven't seen the need.
Is there a reason anyone can think of for using only Low Priority Interrupts?
Enquiring minds want to know.![]()
DT
I use low priority exclusivley unless I have more than 1 interrupt, and one 'or more' needs priority over the lower priority interrupt task.Is there a reason anyone can come up with for using only Low Priority Interrupts?
If you only have 1 interrupt enabled, I can't see why making it high priority VS low priority would be of any benefit!
Yikes. I haven't used DT_INTs much with 18F types, but that's good to know. What causes that to happen?Consequently, DT_INTS crashes if you try to only use LP ints
Last edited by Bruce; - 16th May 2010 at 03:50.
Ok,I use low priority exclusivley unless I have more than 1 interrupt, and one 'or more' needs priority over the lower priority interrupt task.
But since all the 18F's default to High Priority on power-up.
You have to first Enable Low Priorities by setting IPEN ...
RCON.7 = 1 ; enable interrupt priorities
And clear the corresponding priority bit for the interrupt you're using ...
IPR1.5 = 0 ; set RCIF to low priority
And always remember to use GIEL INTCON.6 instead of GIEH INTCON.7
Then, does that give you anything that the default High priority doesn't?
Other than more statements to write.
Well, DT_INTS doesn't really crash, it just won't compile with only LP ints because it's looking for something that isn't there. And I never saw a reason to try to change it.
Perhaps it's just a way of thinking and I could make DT_INTS allow LP_INTS only.
But if there's a valid reason, I will definitely do it.
Q: Is there a reason anyone can think of for using only Low Priority Interrupts?
DT
So far I had only thought of one interrupt to use for my project, and I figured I would set it at low priority since there seemed to be no reason to use high-priority when using only one interrupt. Then if later on I discovered that another interrupt was needed, I supposed it might be a higher priority and would then use high priority for it. So, yes, I may need only one interrupt and didn't know of a reason to set it at high priority.
Interestingly, I think, my PICBASIC PRO manual states in section 9.3 "In any case, you must restore these registers at the end of your assembler interrupt handler. If the 14-bit core PIC MCU has 2K or less of code space, or it is an PIC18 device, the registers are not saved. Your interrupt handler must save and restore any used registers." However, the on-line PICBASIC PRO manual doesn't have such a statement and I hadn't read that section of the on-line manual until this morning. I don't see anything about high or low priority interrupts in the manuals. I suppose MEL can't be expected to put "everything about everything" in their manual but interrupts are a particularly important topic, I think.
I wasn't planning on using the DT_INTS, figuring that my project is so simple that DT_INTS wouldn't be required. In retrospect, I probably should use DT_INTS but I need to get my code running right away (yesterday, of course) and our Procurement Department takes a couple of weeks or more to purchase anything and I don't want to spend my own $. BTW, I am a firm believer in macros but have always made my own macros.
So, in conclusion:
1. Use the high priority interrupts if possible.
2. For high priority interrupts, use RETFIE FAST ; return from interrupt, restore shadows.
3. If I have to use low-priority interrupts, I have to save the registers and they can be saved anywhere, using MOVFF to restore them. Also have to use "RCON.7 = 1 ; enable interrupt priorities. And clear the corresponding priority bit for the interrupt you're using ...IPR1.5 = 0 ; set RCIF to low priority. And always remember to use GIEL INTCON.6 instead of GIEH INTCON.7"
This all seems overly complex with all sorts of special rules, but I guess it comes with the high-capability of the beast. I come from the days of (even before) the DEC PDP8 and PDP9, and am overwhelmed with this complexity.
I just now discovered a very useful thread from 2006 with Darrel's info about interrupts. Not sure why I didn't see this earlier: http://www.picbasic.co.uk/forum/showthread.php?t=3251
Now to get back to my home "industrial controller" project with the dsPIC33F and the MPLAB GNU C compiler. That's beginning to seem simpler than using PICBASIC PRO. ;-)
Thanks again for all the very useful info!
Hi Darrel,
With RCON,IPEN = 0 it's in compatibility mode. I.E. no priority levels on any interrupts, and it's just as easy as say setting up & using interrupts on a 16F part.
There's no GIEH, GIEL, or any priority high/low bit settings to worry about. So, it's actually a bit easier than setting up & using high & low priority interrupts.
Here's an example;
And you still have the benefit of fast return with auto context restore even with low pri interrupts.Code:list p=18f452 include "p18f452.inc" CONFIG OSC=XT,OSCS=OFF,WDT=OFF,WDTPS=128,BOR=ON,BORV=45,LVP=OFF CBLOCK 0x08 MyVar ENDC ORG 0x000 BRA Init ORG 0x008 ; all ints vector here in compatibility mode BRA TMR_INT ; and high-pri vectors here when enabled ORG 0x018 ; low-pri int vector, but only when priority BRA LOW_PRI ; interrupts are enabled Init CLRF MyVar ; clear MyVar CLRF PORTB ; Clear PORTB CLRF TRISB ; PORTB all outputs MOVLW 0x07 MOVWF ADCON1 ; disable A/D MOVLW B'11000111' ; TMR0 on, 8-bit, prescaler, 1:256 MOVWF T0CON BCF RCON,IPEN ; disable priority interrupts BCF INTCON,TMR0IF ; since RCON,IPEN=0, we don't need to worry about any priority ; bit settings for any interrupt source, and we refer to GIE,PEIE ; VS GIEH,GIEL because we're in "compatibility" mode. We don't ; have to mess with anything related to high or low priority ; interrupts. Compatibility mode is just as easy as interrupts on ; 16F parts. BSF INTCON,TMR0IE ; enable Timer0 interrupt BSF INTCON,PEIE ; peripheral ints enabled BSF INTCON,GIE ; global enabled Main MOVFF MyVar,PORTB ; show count on PORTB LEDs BRA Main TMR_INT ; default int vector for all interrupts INCF MyVar ; when in compatibility mode BCF INTCON,TMR0IF RETFIE FAST LOW_PRI ; never gets here because priority ints INCF MyVar ; are not enabled when RCON,IPEN = 0 BCF INTCON,TMR0IF RETFIE FAST END
Maybe I should have said - I use NO priority levels or compatibility mode VS only low priority interrupts. The only time I enable priority levels is when I have more than one interrupt, and one or more needs to interrupt the less important interrupt assigned to the low vector.
Otherwise it's easier to just use compatibility mode with no priority levels to worry about.
I know you're already aware of this, but I figured it would be good to post so folks reading this didn't get confused between using priority levels - I.E. high & low VS compatibility mode where there are no priority levels enabled.
Last edited by Bruce; - 16th May 2010 at 20:15.
I'll take that as a NO.
No reason to have ONLY Low Priority interrupts. (suggested in post #4).
DT
Bookmarks