中断开关(PIC)

时间:2015-04-02 02:41:49

标签: switch-statement interrupt pic

#define SW1 RB5
int IOFlag = 2; //while in out

void SW(){
    if(!RB5)
        __delay_ms(50);
        while(!RB5);
            __delay_ms(50);
        IOFlag++;
}

void main(){
    SW();
    while(IOFlag % 2 != 0){
        SW();
        //some routines..
    }
}

我使用pic16f73,RB5输入用于切换。 某些例程正在运行时,交换机无法正常运行。 如果使用中断,则可以。但是,我不知道如何正确使用它。

1 个答案:

答案 0 :(得分:0)

您需要了解轮询和中断之间的区别。

通过轮询(您似乎在做什么),您会定期检查某些“事物”的状态并对其采取行动。

对于中断,发生“事情”会导致您的主要执行线程被暂停,并且中断服务例程(ISR)会运行。

轮询具有潜在的长延迟的缺点,即发生事件和发现事件之间的时间。实际上,如果事物是​​瞬时开关,你甚至可以输掉事件 - 你打开它然后关闭然后,当代码检查它时,它就会关闭。

如果您了解这些含义,现在您可以仍然使用轮询。有时最简单的解决方案是更频繁地进行轮询。

例如,如果您的//some routines..个作业之一是一个长时间运行的循环,您可以从那里进行轮询:

for (int i = 0; i < numThings; i++) {
    doSomethingQuickWitn (thing[i]);
    SW(); // Poll here as well
}
// Rather than here.

然而,对于_minimal延迟,使用中断通常更好,并且一旦你围绕这个概念理解是合理的

您的ISR(将在给定事件上运行,中断执行的主线程)只需存储事件已发生的事实并以某种方式将其传达给主线程。

如果您不关心事件发生的次数,则会有一个标记来执行此操作。您的ISR只是设置标志,您的主要执行线程会定期检查它是否已设置,然后清除它(禁用中断以避免竞争条件)。这就像(伪代码):

global val switchHit = false;

main:
    interrupt (7, intFn)       // call intfn() on interrupt 7
    while true:
        disableInts()          // disallow interrupts for a short while
        if switchHit:
            handleSwitch()     // switch was hit, do something (quickly)
            switchHit = false  // mark as not hit
        enableInts()           // and re-allow interrupts

        doLotsOfOtherStuff()

intfn:
    switchHit = true           // notify main

请注意,我不担心ISR中的竞争条件,通常 在那里自动禁用中断。

更复杂的信息传输可能涉及计数而不是标志,甚至是某种消息队列,从ISR流向执行的主线程。