在 vector、SEI 和 intflags 仍然设置后中断停止执行。 (AtMega4809)

Interrupts stop executing after vector, SEI and intflags are still set. (AtMega4809)

我的系统有几个中断,包括TC捕获、外部中断和ADC转换中断。特别是有一个向量,在执行时,即使在 reti() 指令之后,也会阻止任何向量执行。

TCB2 捕获中断向量(向量 25)是系统中唯一停止一切导致 WDT 复位的向量。

全局中断标志为 1,激活中断的 INTFLAGS 在中断发生时正确设置。但是没有向量被执行。 这适用于所有中断。

我尝试稍微更改向量,确保存在 reti() 指令并确保向量 table 没有改变。 我也已经确保代码在 reti() 之后继续正常执行。唯一似乎不起作用的是向量。

volatile uint8_t new_input_regs = 0x00;

/*[Other code, including other vectors without this issue]*/

void __vector_25() {

    new_input_regs = PORTD_IN;  //Get PORTD input values
    TCB2_CTRLA &= ~(0x01); //Clear TC enable and flags
    TCB2_INTFLAGS = 0xFF;

    asm("WDR"); //Reset the WD timer

    event_type = EVENT_INPUT_INTERRUPT; //Set the event
    reti();     
}

执行后,所有中断停止工作,直到复位(由于没有中断执行,这最终也会导致看门狗复位)。[​​=15=]

有关寄存器和矢量的更多信息 table 此处:https://imgur.com/a/SpLKrgT

多亏了评论,我注意到 ISR 过于优化,甚至在没有 returns 的 assemble 的单个块中跳过 retis 和合并向量。默认向量函数(如上面使用的 __vector_25())无法按预期工作,导致 ISR 未终止并且即使手动编写也会丢失 reti()。这会导致完全意外的行为。

我已将矢量定义更改为 ISR(_VECTOR(25)) 并删除了函数末尾的 reti()。中断已恢复正常工作。

感谢您的帮助。