View previous topic :: View next topic |
Author |
Message |
future
Joined: 14 May 2004 Posts: 330
|
Does interrupt dispatcher tests all interrupts? |
Posted: Sat Oct 30, 2004 11:42 pm |
|
|
Hi,
I have this 18F452 40Mhz program that has:
Code: | enable_interrupts(int_ad);
enable_interrupts(int_ext);
enable_interrupts(int_rda);
enable_interrupts(int_timer0);
enable_interrupts(int_timer2); |
The generated interrupt dispatcher is:
Compiler 3.211
Code: | 0008: MOVWF 05
000A: MOVFF FD8,06
000E: MOVF FE9,W
0010: MOVWF 07
0012: MOVF FEA,W
0014: MOVWF 08
0016: MOVF FE1,W
0018: MOVWF 09
001A: MOVF FE2,W
001C: MOVWF 0A
001E: MOVF FD9,W
0020: MOVWF 0B
0022: MOVF FDA,W
0024: MOVWF 0C
0026: MOVF FF3,W
0028: MOVWF 14
002A: MOVF FF4,W
002C: MOVWF 15
002E: MOVF FE0,W
0030: MOVWF 0D
0032: MOVLB 0
0034: MOVF 00,W
0036: MOVWF 0F
0038: MOVF 01,W
003A: MOVWF 10
003C: MOVF 02,W
003E: MOVWF 11
0040: MOVF 03,W
0042: MOVWF 12
0044: MOVF 04,W
0046: MOVWF 13
0048: BTFSS FF2.5
004A: GOTO 0054
004E: BTFSC FF2.2
0050: GOTO 0694
0054: BTFSS F9D.1
0056: GOTO 0060
005A: BTFSC F9E.1
005C: GOTO 0566
0060: BTFSS FF2.4
0062: GOTO 006C
0066: BTFSC FF2.1
0068: GOTO 046E
006C: BTFSS F9D.6
006E: GOTO 0078
0072: BTFSC F9E.6
0074: GOTO 07B4
0078: BTFSS F9D.5
007A: GOTO 0084
007E: BTFSC F9E.5
0080: GOTO 06B2
0084: BTFSS F9D.4
0086: GOTO 0090
008A: BTFSC F9E.4
008C: GOTO 0754
0090: BTFSS FA0.4
0092: GOTO 009C
0096: BTFSC FA1.4
0098: GOTO 07E8
009C: MOVF 0F,W
009E: MOVWF 00
00A0: MOVF 10,W
00A2: MOVWF 01
00A4: MOVF 11,W
00A6: MOVWF 02
00A8: MOVF 12,W
00AA: MOVWF 03
00AC: MOVF 13,W
00AE: MOVWF 04
00B0: MOVF 0D,W
00B2: MOVWF FE0
00B4: BSF 0D.7
00B6: MOVF 07,W
00B8: MOVWF FE9
00BA: MOVF 08,W
00BC: MOVWF FEA
00BE: MOVF 09,W
00C0: MOVWF FE1
00C2: MOVF 0A,W
00C4: MOVWF FE2
00C6: MOVF 0B,W
00C8: MOVWF FD9
00CA: MOVF 0C,W
00CC: MOVWF FDA
00CE: MOVF 14,W
00D0: MOVWF FF3
00D2: MOVF 15,W
00D4: MOVWF FF4
00D6: MOVF 05,W
00D8: MOVFF 06,FD8
00DC: RETFIE 0 |
So I ask, why would the compiler add tests to interrupts that are never used?
I need to get a 50khz interrupt rate with timer 2, so I am trying to optimize the code. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sun Oct 31, 2004 2:06 am |
|
|
Should just add the ones that you have defined like
#int_timer2
Be careful not to enable an interrupt that you don't have a handler for. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Oct 31, 2004 6:23 am |
|
|
The created interrupt dispatcher is based upon the interrupt handlers that you have in your code, the functions starting with #intxxx. The dispatcher is NOT based on the interrupts that you enable with the function enable_interrupts(...).
In your example code you enable 5 interrupts while in the dispatcher there are 7 interrupt handlers, the two missing ones are for UART_TX and EEPROM. For a short as possible dispatcher remove these two unused interrupt handlers from your code.
For a really fast interrupt handler, have you considered changing your tmr2 interrupt to a high priority interrupt? As long as you don't have other high priority interrupts there is no dispatcher required and the interrupt will be much faster. |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Sun Oct 31, 2004 9:37 am |
|
|
I have considered to use fast interrupts in the past (have many posts here), but gave up as I got a lot of unexplainable behaviors.
Now I tried again and a simple "#int_timer2 fast" makes the program to stop working.
It does not communicate via serial port and the led blinks much faster.
Code: | #int_timer2 fast
void timer2_isr(void) {
//;===========================================;//
/*; 20uS ;*/ mms++; ///
//;===========================================;//
//;===========================================;//
/*; 1mS ;*/ if(mms==50) { mms=0; ms++; ///
//;===========================================;//
//;===========================================;//
/*; 100mS ;*/ if(ms==100) { ms=0; tenth++; ///
//;===========================================;//
//;===========================================;//
/*; 1S ;*/ if(tenth==10) { tenth=0; rtm.sec++;///
//;===========================================;//
led=~led; // i'm alive!
}}}} |
|
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sun Oct 31, 2004 10:43 am |
|
|
Check to make sure that the return does a RETFIE 1. There was a bug in some compilers. |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Sun Oct 31, 2004 10:57 am |
|
|
Retfie 1 is in place.
PIC18F@40Mhz
Compiler 3.211
Code: | setup_timer_2(t2_div_by_1,0xC8,1); // 20uS period |
if I change to:
Code: | #int_timer2 fast
void timer2_isr(void) {
led=~led; // i'm alive!
//;===========================================;//
/*; 20uS ;*/ mms++; ///
//;===========================================;//
//;===========================================;//
/*; 1mS ;*/ if(mms==50) { mms=0; ms++; ///
//;===========================================;//
//;===========================================;//
/*; 100mS ;*/ if(ms==100) { ms=0; tenth++; ///
//;===========================================;//
//;===========================================;//
/*; 1S ;*/ if(tenth==10) { tenth=0; rtm.sec++;///
//;===========================================;//
}}}} |
The 'LED' blinks at 171khz. This explains why the 1S timing is so wrong. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sun Oct 31, 2004 11:06 am |
|
|
Your commenting style seriously obsures the code. You might take a more traditional approach that lends itself to be very easy to read.
Code: |
#int_timer2 fast
void timer2_isr(void) {
mms++; // Increment mms every 20uS
if(mms==50) // Every 50 uS gives us 1mS
{
mms=0;
ms++;
if(ms==100) // Every 100mS gives us 0.1S
{
ms=0;
tenth++;
if(tenth==10) // Every 10 tenths gives 1S
{
tenth=0;
rtm.sec++;
led=~led; // Toggle the LED to show i'm alive!
}
}
}
}
|
|
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Sun Oct 31, 2004 11:26 am |
|
|
I chose this way to comment because it is easier to read when more code is added and the timing sections get visually separated.
The traditional way is hard to read when I add for example, 12 var tests in the 20uS section and some things in the others... I get lost. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sun Oct 31, 2004 12:53 pm |
|
|
Try running it at 10MHz and see how well it works. It may be the crystal that you used. Search this forum and you will find some info on it. |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Sun Oct 31, 2004 12:59 pm |
|
|
I dont think that is the crystal or parts, I have 4 identical boards and all does the same thing.
They work fine without fast interrupts, but normal interrupts are limiting speed. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Oct 31, 2004 3:47 pm |
|
|
Just curious. With normal interrupts your timer2 is running at the required 50kHz, but with fast interrupts it is running at 171kHz? Very strange. Could this be a compiler bug not clearing the interrupt flag? I don't have v3.211, so could you check the end of the fast interrupt routine for me? It should look something like Code: | 00CA: BCF F9E.1
00CC: RETFIE 1 |
|
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Sun Oct 31, 2004 4:32 pm |
|
|
I think you are right.
With timer2 fast...
main loop speed 0loops/s
timer2 interrupt rate 342khz (toggles 2 times for a complete cycle)
Without fast...
main loop speed ~700loops/s
timer2 interrupt rate 50khz
Code: | 0000: GOTO 0A56
*
0008: GOTO 056A
000C: NOP
000E: NOP
0010: NOP
0012: NOP
0014: NOP
0016: NOP
0018: MOVWF 05
001A: MOVFF FD8,06
001E: MOVF FE9,W
0020: MOVWF 07
0022: MOVF FEA,W
0024: MOVWF 08
0026: MOVF FE1,W
0028: MOVWF 09
002A: MOVF FE2,W
002C: MOVWF 0A
002E: MOVF FD9,W
0030: MOVWF 0B
0032: MOVF FDA,W
0034: MOVWF 0C
0036: MOVF FF3,W
0038: MOVWF 14
003A: MOVF FF4,W
003C: MOVWF 15
003E: MOVF FE0,W
0040: MOVWF 0D
0042: MOVLB 0
0044: MOVF 00,W
0046: MOVWF 0F
0048: MOVF 01,W
004A: MOVWF 10
004C: MOVF 02,W
004E: MOVWF 11
0050: MOVF 03,W
0052: MOVWF 12
0054: MOVF 04,W
0056: MOVWF 13
0058: BTFSS FF2.5
005A: GOTO 0064
005E: BTFSC FF2.2
0060: GOTO 0690
0064: BTFSS FF2.4
0066: GOTO 0070
006A: BTFSC FF2.1
006C: GOTO 0472
0070: BTFSS F9D.6
0072: GOTO 007C
0076: BTFSC F9E.6
0078: GOTO 07B0
007C: BTFSS F9D.5
007E: GOTO 0088
0082: BTFSC F9E.5
0084: GOTO 06AE
0088: BTFSS F9D.4
008A: GOTO 0094
008E: BTFSC F9E.4
0090: GOTO 0750
0094: BTFSS FA0.4
0096: GOTO 00A0
009A: BTFSC FA1.4
009C: GOTO 07E4
00A0: MOVF 0F,W
00A2: MOVWF 00
00A4: MOVF 10,W
00A6: MOVWF 01
00A8: MOVF 11,W
00AA: MOVWF 02
00AC: MOVF 12,W
00AE: MOVWF 03
00B0: MOVF 13,W
00B2: MOVWF 04
00B4: MOVF 0D,W
00B6: MOVWF FE0
00B8: BSF 0D.7
00BA: MOVF 07,W
00BC: MOVWF FE9
00BE: MOVF 08,W
00C0: MOVWF FEA
00C2: MOVF 09,W
00C4: MOVWF FE1
00C6: MOVF 0A,W
00C8: MOVWF FE2
00CA: MOVF 0B,W
00CC: MOVWF FD9
00CE: MOVF 0C,W
00D0: MOVWF FDA
00D2: MOVF 14,W
00D4: MOVWF FF3
00D6: MOVF 15,W
00D8: MOVWF FF4
00DA: MOVF 05,W
00DC: MOVFF 06,FD8
00E0: RETFIE 0 |
Code: | ......... led=~led; // show them i'm alive!
068C: BTG F83.1
......... }}}}
.........
068E: BCF F9E.1
0690: RETFIE 1 |
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Oct 31, 2004 5:39 pm |
|
|
The timer2 interrupt flag is reset in your code, still you get lots of high priority interrupts. Very strange....
I see two possible explanations:
1) Making Timer2 a fast interrupt screws the compiler up resulting in wrong period settings for Timer2. Very unlikely as this has always worked before.
2) Somewhere in your code you are manually enabling a 2nd high priority interrupt which is never cleared. This is more likely as you have been experimenting with Fast interrupts before. |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Sun Oct 31, 2004 7:00 pm |
|
|
I dont think that fast interrupts works with these 452, all my tries failed.
The code is so simple that I cant imagine where is the error...
I give up again.
Thank you. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Oct 31, 2004 7:48 pm |
|
|
Aaarrgh!!! Stupid me!
I forgot a third possibility for your code to generate high priority interrupts and not clearing them and I think that is what's happening:
3) The int0 (external) interrupt is always configured as a high priority interrupt.
When your hardware generates an Int0 interrupt it is seen as a high priority interrupt but your high priority interrupt handler does not check where the interrupt is comming from and sees it as an Timer2 interrupt. The Int0 is never cleared and continuously generates new interrupts. |
|
|
|