为什么 atmega32 的中断 INT2 不起作用?

问题描述 投票:0回答:2

在我的项目中,我使用了

atmega32
的所有外部中断。但是,
INT2
不起作用。读取输入,但与其余的
INT0
INT1
外部中断不同,什么也没有发生。

代码

int main(void) 
{
    DDRC = 0xFF;                                                                           
    
    GICR|= (1 << INT0) | (1 << INT1) | (1 << INT2);
    GICR|= (1 << INT2); 
    MCUCR |= (1 << ISC10) | (1 << ISC11)|(1 << ISC00) | (1 << ISC01);
    MCUCSR |= (1 << ISC2);  //Activating all interrupt to react to rising edges
    sei(); 

    while(1)    
    {     
        
    }    
    return 0;
}

ISR(INT0_vect)
{
    PORTC ^= (1 << PC3); 
    _delay_ms(2000);
    PORTC ^= (1 << PC3);
}

ISR(INT1_vect) 
{
    PORTC ^= (1 << PC0);
    _delay_ms(2000);
     PORTC ^= (1 << PC0);
}

ISR(INT2_vect)
{
    PORTC ^= (1 << PC1); 
    _delay_ms(2000);
    PORTC ^= (1 << PC1);
}

那么出了什么问题以及为什么它不起作用?

interrupt avr atmega32
2个回答
0
投票

如果您查看第 51 页的 ATmega32 数据表,您可以看到中断的优先级顺序

  • 2 $002 INT0 外部中断请求 0
  • 3 $004 INT1 外部中断请求 1
  • 4 $006 INT2 外部中断请求 2

ATmega 架构没有 NVI 控制器(如 ARM 控制器),因此中断的优先级无法重新排序。正如您在数据表中看到的,对于外部中断,INT0 具有最高优先级,INT2 具有最低优先级。这意味着当同时调用 INT0、INT1 和 INT2 时,将首先服务 INT0,然后服务 INT1,至少服务 INT2。

如果您在示例中先触发 INT0,然后触发 INT2,至少触发 INT1,则中断的执行顺序将是:

  • INT0
  • INT1
  • INT2

如果您先触发 INT1,然后触发 INT2,然后触发 INT0,则中断的执行顺序将是:

  • INT1
  • INT0
  • INT2

您的示例中的一个大错误是您在中断中设置了延迟。请永远不要这样做。中断应该是一个非常短的例程,并且永远不要实现延迟!!!

ISR(INT0_vect)
{
  PORTC ^= (1 << PC3);
}

// ...
GICR|= (1 << INT0) | (1 << INT1) | (1 << INT2);
// GICR|= (1 << INT2); // This is not necessary

//...
MCUCSR |= (1 << ISC2);  // Does not activate all interrupts! It activates INT2 to detect a rising edge!

注意事项: 如果您在外部中断上使用按钮,它们可能会反弹,因此中断将被调用多次!


0
投票

延迟不是问题 很明显,他放它是为了看动作,只是为了看动作 如果删除延迟中断两个将不会运行,否则, 下降沿或上升沿 我有同样的问题,但没有#iinclude

© www.soinside.com 2019 - 2024. All rights reserved.