Reputation: 69
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;
}
}
Upvotes: 3
Views: 927
Reputation: 1225
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.
Upvotes: 3