I'm using Keil compiler for 8051Warp uP. I would like to make a jump from an interrupt routine back to the main function, this way: main () { init_function(); if (setjmp(env)!=0) { // Recovery procedure here ... } while (1) { // body of my program ... } } void irq (void) interrupt (12) { if (condition) longjmp (env,1); } void init_function() { IE = 0xA0; IEN1 = 0xC4; IP = 0x00; IP1= 0x40; } I'm experiencing the following problem. Right after the longjmp instruction, the execution actually restarts at the setjmp instruction point (as i wish), but no more interrupt can be serviced after this jump. It looks like the IE.7 bit has been reset in some way. Anyway, even if i set the IE / IE1 registers after the jump, no more interrupt are serviced by the uP. Somebody could help me? Thanx.
...And a high priority ISR needs to know if it interrupted a low priority ISR and if so, don't perform the return address replacement. Let the low priority ISR do that.
Sheesh! ...And in main() after the call to init_function(), you'll want to reset SP to its initial value.
I know, I'm becoming tedious, but to properly terminate the interrupt posture and ensure that interrupts are disabled upon ISR return, you'd still want to do the ISR return address replacement I described above, but you'd also want to RETI to a CLR EA instruction. The MCU will always execute one instruction after the RETI, the CLR EA in this case. So the init_function() would look something like:
void init_function( void ) { initialSP = SP - 2; restartAddrMSB = *(SP - 0); restartAddrLSB = *(SP - 1); /* ... */ }
void main( void ) { init_function(); EA = 0; /* CLR EA */ SP = initialSP; /* No effect on 1st through */ /* ... */ EA = 1; /* Ready to rumble */ /* ... */ }