【问题标题】:interrupt switch (PIC)中断开关 (PIC)
【发布时间】:2015-04-02 02:41:48
【问题描述】:
#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 输入用于开关。 当某些例程运行时,开关不能正常运行。 如果您使用中断,这是可能的。但是我不知道如何正确使用它。

【问题讨论】:

  • 许多从 PIC 编程开始的人偶然发现看门狗处于活动状态并在他们的代码中寻找错误,没有注意到活动的看门狗每 50 毫秒(左右)重置程序的事实。您可以在该下载工具中关闭看门狗(复选框)。

标签: switch-statement interrupt pic


【解决方案1】:

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

通过轮询(您似乎在做的事情),您可以定期检查某些“事物”的状态并采取行动。

对于中断,发生的“事情”会导致您的主执行线程暂停,并运行中断服务例程 (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 流向执行的主线程。

【讨论】:

  • 根据中断敏感输入的触发模式(边沿或电平触发),您还可能在使用中断时遇到您描述的轮询问题。此外,一旦您使用中断,您的代码就会变得不确定。这就是为什么一些(例如军事、医学)诉诸轮询并证明他们的循环和最长的代码路径在他们“实时”所需的边界内的原因。
  • 但我无法理解您的代码。那是伪代码?
  • @최인혁,是的,它是伪代码,我会在答案中明确说明。我认为这会更好地说明这一点,因为汇编代码几乎肯定会更大并且可能会妨碍理解。
  • 是的,我也这么认为。谢谢你。再试一次再试一次,哈哈哈
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多