Hi Harold The context save is a news flash to me (as is most PIC programming stuff) well at least in the C18 realm. I of course had to do it in the programs I wrote in assembler but the way I understand it is that the compiler is supposed to do that for me. But I can't see what it would hurt give this idea a try and it makes sense from the symptoms.........weird undefined behavior as if the stack were corrupted. There is no reason I can't do the same context save/restore/read/write to those same registers as I would in assembly.......eh? I don't have time to try it today but in the next few days I'll try that. Mucho thanks Harold. Phillip Things should be as simple as possible but no simpler Phillip Coiner CTO, GPS Source, Inc. Your source for quality GNSS Networking Solutions and Design Services, Now! -----Original Message----- From: piclist-bounces@mit.edu [mailto:piclist-bounces@mit.edu] On Behalf Of Harold Hallikainen Sent: Monday, December 04, 2006 4:53 PM To: Microcontroller discussion list - Public. Subject: RE: [PIC] Problems with C18 interrupt code Well, I don't know if this is it, but here are some comments... I like writing interrupt service routines in assembly since the various C functions are not guaranteed to be reentrant. Your interrupt may mess up some intermediate value in mainline code. Are you doing an interrupt context save? With my writing the ISR in assembly, I know exactly which registers I mess with (typically w, bsr, fsr0, status, etc.). I have a subroutine that saves these away and another that restores them when I'm done. What does the PORTB=PORTB line do for us? I guess there's also a possibility of the PORTB bit changing during the ISR. I'd probably copy it to a local variable, then do all the checking on the unchanging local. Another write wrote about having trouble with two ISRs, both as high priority. I've generally made everything high priority and had no trouble. Sometimes my main ISR does a context save, then calls each individual ISR, which does a flag check, clear flag and execute if true or exit if false. Other times I've had the flag test in the main ISR and only call the individual ISR if the flag is set (then clear it in the individual ISR). Even though it's a bit slower, I tend to like doing the test inside the individual ISR since code is more compartmentalized. Good luck! Harold > > #include > #pragma config OSC = XT, OSCS = OFF, PWRT = ON, BOR = OFF, WDT = OFF, > STVR = OFF, LVP = OFF, DEBUG = OFF > > //-------------------------------------------------------------------------- > -- > > void main (void); > void InterruptHandlerHigh (void); > > union { > struct { > unsigned Timeout:1; //flag to indicate a TMR0 timeout > unsigned None:7; > } Bit; > unsigned char Byte; > } Flags; > > //========================= > union { > struct { > unsigned char B0; > unsigned char B1; > unsigned char B2; > unsigned char B3; > } byte; > unsigned long b1234; > } pulse_count; > > > //========================= > union { > struct { > unsigned RB0:1; > unsigned RB1:1; > unsigned RB2:1; > unsigned RB3:1; > unsigned RB4:1; > unsigned RB5:1; > unsigned RB6:1; > unsigned RB7:1; > }; > unsigned char old_portb; > } old_portb_bits; > > //-------------------------------------------------------------------------- > -- > // Main routine > > void main () { > Flags.Byte = 0; > INTCON = 0x28; //disable global and enable TMR0 interrupt and RB > INTCON2 = 0x85; //TMR0 high priority > RCONbits.IPEN = 1; //enable priority levels > TMR0H = 0; //clear timer and set TMR0H > TMR0L = 0; //clear timer low byte and also updates high byte from > TMR0H > T0CON = 0x88; //set up timer0 - no prescaler > INTCONbits.GIEH = 1; //enable interrupts > TRISB = 0x7E; //PORTB bits 0 and 7 are output, the rest are input > TRISC = 0; //PORTC bits are output > PORTC = 0; > > old_portb_bits.old_portb = 0; > pulse_count.b1234 = 0; > > while (1) { > PORTC = pulse_count.byte.B0; > } > } > > //-------------------------------------------------------------------------- > -- > // High priority interrupt vector > > #pragma code InterruptVectorHigh = 0x08 > void > InterruptVectorHigh (void) > { > _asm > goto InterruptHandlerHigh //jump to interrupt routine > _endasm > } > > //-------------------------------------------------------------------------- > -- > // High priority interrupt routine > > #pragma code > #pragma interrupt InterruptHandlerHigh > > void InterruptHandlerHigh () { > > if (INTCONbits.TMR0IF) { //check > for > TMR0 overflow > INTCONbits.TMR0IF = 0; //clear > interrupt flag > } > > if (INTCONbits.RBIF) { > PORTB = PORTB; > INTCONbits.RBIF = 0; > if (PORTBbits.RB4 == 1 && old_portb_bits.RB4 == 0) > (unsigned > long)pulse_count.b1234++; > old_portb_bits.old_portb = PORTB; > } > } > > -- > http://www.piclist.com PIC/SX FAQ & list archive > View/change your membership options at > http://mailman.mit.edu/mailman/listinfo/piclist > > -- > http://www.piclist.com PIC/SX FAQ & list archive > View/change your membership options at > http://mailman.mit.edu/mailman/listinfo/piclist > -- FCC Rules Updated Daily at http://www.hallikainen.com - Advertising opportunities available! -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist