中断发生在中断启用之前发生的更改

时间:2016-07-10 04:08:15

标签: c interrupt atmega

我使用Arduino Uno和Atmega328p微控制器。我试图将INT1用作软件中断。我根据外部信息手动将INT1的相关PORTD3设置为高电平或低电平。我想要的是在器件启动时将引脚设置为高电平或低电平,然后在启用中断之前将引脚置为高电平时启用引脚上的中断而不会产生中断。

在我启用中断的地方似乎并不重要 - 如果我在某个时刻改变了引脚的状态,一旦启用就会发生中断。以下是代码片段:

int main(void)
{
    DDRD |= (1<<DDD7)|(1<<DDD3);//7 for siren 3 for software int1
    USART_Init(MYUBRR);//Initialize USART
    while(door!='C'  && door!='O'){//get door state on startup
        door = getDoorState();
    }
    if(door=='O')
        PORTD |= 1<<PORTD3;
    else
        PORTD &= ~(1<<PORTD3);
    EIFR &= ~(1<<INTF1);//clear flag bit before enable, I'd heard this may help????
    EIMSK |= (1<<INT1);//enable door switch interrupt
    EICRA |= (1<<ISC00)|(1<<ISC10);//int1 and int0 set for any logical change

    sei();//global interrupt enable

    while (1) 
        {}
}

一旦通过调用sei()启用全局中断,如果PORTD3为高电平,则无论PORTD3设置为高电平还是sei(),都会发生中断。在理想情况下,调用sei()不应该在此代码中引起中断。

2 个答案:

答案 0 :(得分:0)

4386427是正确的。通过将其设置为1而不是零来清除该位。对我来说似乎是违反直觉的,所以它把我扔了,但它现在有效。

EIFR |= (1<<INTF1);

答案 1 :(得分:0)

EIFR &= ~(1<<INTF1)不正确。

这样做的正确方法是EIFR = 1<<INTF1

数据表说:通过向其写入'1'来清除该标志。