1

我下面有一些代码有一个小错误,我不知道如何修复。基本上发生的事情是我的高 ISR 在设置标志后运行了两次。它只运行两次并且是一致的。子例程应该只运行一次,因为当 RB 上的输入更改时设置了标志,并且例程在 RB 的输入更改一次后运行两次。测试是在 MPLAB v8.6 中使用工作簿功能进行的。

#include <p18f4550.h>
#include <stdio.h>  

void init(void)
{   
    RCONbits.IPEN =1;       //allows priority    
    INTCONbits.GIE = 1;     //allows interrupts
    INTCONbits.PEIE = 1;    //allows peripheral interrupts
    INTCONbits.RBIF = 0;  //sets flag to not on
    INTCONbits.RBIE = 1; //enables RB interrupts
    INTCON2bits.RBPU = 1; //enable pull up resistors
    INTCON2bits.RBIP = 1;   //RB interrupts is high priority
    PORTB = 0x00;  
    TRISBbits.RB7 = 1; //enable RB7 as an input so we can throw interrupts when it changes. 
}

#pragma code
#pragma interrupt high_isr
void high_isr(void)
{
    if(INTCONbits.RBIF == 1)
    {
        INTCONbits.RBIF = 0;  
        //stuff
    }
}

#pragma code    
#pragma code high_isr_entry = 0x08
void high_isr_entry(void)
{_asm goto high_isr _endasm}


void main(void)
{
    init();
    while(1);   
}   
4

1 回答 1

2

RB7 中断标志​​根据最后锁存值和引脚当前状态的比较设置。在数据表中,它说“将引脚与上次读取 PORTB 时锁存的旧值进行比较。RB7:RB4 的‘不匹配’输出被或在一起以产生带有标志位的 RB 端口更改中断。”

为了清除不匹配条件,数据表继续说“对 PORTB 的任何读取或写入(MOVFF (ANY), PORTB 指令除外)。这将结束不匹配条件。”

然后等待一个 Tcy(执行 nop 指令),然后清除标志。这记录在数据表的第 116 页。

因此,在这种情况下,最简单的修复方法是在中断例程中声明一个虚拟变量并将其设置为 RB7,如下所示:

#pragma interrupt high_isr
void high_isr(void)
{
    unsigned short dummy;

    if(INTCONbits.RBIF == 1)
    {
        dummy = PORTBbits.RB7;  // Perform read before clearing flag
        Nop();
        INTCONbits.RBIF = 0;
        // rest of your routine here
        // ...
于 2013-10-24T03:07:05.873 回答