中断/堆栈指针/PIC 微控制器

Interrupt / Stack Pointers / PIC Microcontroller

我目前正在使用 PIC16F1829 微控制器。但是,我坚持使用中断例程的适当执行方法。我希望中断例程退出所有函数(LED 动画)中的无限循环,这些函数在 main() 超级循环中被列为不同的切换情况。我应该使用一个全局变量,函数将在检测到中断标志后检查并更改它,还是可以为此目的只使用堆栈指针?我目前已经使用堆栈指针操作编写了 ISR,但是请问您是否可以告诉我这是不是一个好方法?

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;   
    }
}

您使用堆栈帧操作的实现不适用于 PIC16F1829。这些控制器为调用堆栈使用单独的内存 space。

要实现您的建议,需要将 32 级调用堆栈的副本保存到通用 RAM 内存中,并为动画列表中的下一个例程恢复 32 级调用堆栈的副本。这可能看起来效率太低了。

请学习 protothreads 的概念,这是在单个执行线程上的资源有限控制器中实现并发行为的有用方法。