We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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 */ /* ... */ }