Search code examples
embeddedinterruptpicisrstack-pointer

Interrupt / Stack Pointers / PIC Microcontroller


I am currently working with the PIC16F1829 micro controller. However, I am stuck on interrupt routine appropriate execution method. I want the interrupt routine to exit out of the infinite loop in all of the functions (LED animations), that are listed as different switch cases in the main() superloop. Should I use a global variable that the function would check and change it after interrupt flag has been detected or can I just use the stack pointers for this purpose? I have currently the ISR written using the stack pointer manipulation, but could you please let me know if this is the good approach?

void interrupt ISR(void){
    if (TMR0IF && TMR0IE){          // (16MHz / (4 * 16 * 256))     [ 1.024 ms ]
        TMR0IF = 0;                 // Clear Overflow Flag

        if (++counter > 4531){      // 19531 * 1.024 ms             [ ~ 20 sec ]
            LED_Animation++;        // Change the animation at a fixed time interval
            counter = 0;

            while (STKPTR > 1){     // STKPTR incremented due to an Interrupt

                TOSH = 0;           // TOSH:TOSL points to the Top of a Stack [ 0x00 ]
                TOSL = 0;
                STKPTR--;           // Current value of the Stack Pointer
            }   
        }
    }
} 

void main(){

STKPTR++;                           // Save this location in the stack

Sys_Init();

while(1){

    switch(LED_Animation) {

        case 0:     LED_LizzardFeed();  break;
        case 1:     LED_Paparazzi();    break;
        case 2:     LED_FillnClear();   break;
        case 3:     LED_Slide();        break;
        case 4:     LED_MeetUp();       break;
        case 5:     LED_Chaser();       break;

        default:    LED_Animation = 0;   
    }
}

Solution

  • Your implementation using stack frame manipulation does not work on a PIC16F1829. These controllers use a separate memory space for the call stack.

    To implement what you have suggested would require saving a copy of the 32-level call stack to the general RAM memory and restoring a copy of the 32-level call stack for the next routine in the animations list. This is possible be seems a bit too inefficient.

    Please study the concept of protothreads, the are a useful method to achieve concurrent behavior in a resource limited controllers on a single execution thread.