中断/堆栈指针/ PIC单片机

时间:2018-07-23 16:23:40

标签: embedded interrupt pic isr stack-pointer

我目前正在使用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;   
    }
}

1 个答案:

答案 0 :(得分:3)

您使用堆栈帧操作的实现在PIC16F1829上不起作用。这些控制器为调用堆栈使用单独的内存空间。

要实现建议的功能,需要将32级调用堆栈的副本保存到常规RAM内存中,并为动画列表中的下一个例程还原32级调用堆栈的副本。这可能似乎效率太低。

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