1

使用的 AVR 是 ATmega2560。

我有一个生成的脉冲宽度为 1 秒的输入信号。

该信号连接到我的 AVR (INT0) 上的外部中断引脚。

INT0 初始化如下:

代码:

DDRD &= ~(1 << PD0);
PORTD |= (1 << PD0);
EIMSK  = 1 << INT0; // enable
EICRA |= (1 << ISC00) | (1 << ISC01); // trigger on rising edge

sei(); //global interrupts

此外部中断的 ISR 的任务是 a) 确定哪个边沿(第一种情况应该是上升沿)和 b) 根据哪个边沿执行操作

ISR 看起来像这样:

代码:

ISR(INT0_vect)
{

if(EICRA == 0x02)
{
    // falling edge detected
    doFallingEdgeFunction_lightLED0();

    // quickly change the trigger to capture opposite edge
    EICRA |= (1 << ISC00) | (1 << ISC01); // trigger on rising edge

}

else if(EICRA == 0x03)
{
    doRisingEdgeFunction_lightLED1();

    // change trigger on falling edge
    EICRA = (1 << ISC01);
    EICRA &= ~(1 << ISC00);
}

}

它能够检测边缘;正确的 LED 会亮起,但由于某种原因,更改 ISR 中的边沿中断位会将我的输入信号减小到 0.1 秒宽度,而不是 1 秒的完整宽度。

在示波器上,我看到原始信号被镜像但宽度减少了 10 倍!如果我删除“切换触发器”项目,信号很好。

4

1 回答 1

0

从第 15.2.2 节,p. 114

注:1. n = 3、2、1 或 0。当改变 ISCn1/ISCn0 位时,必须通过清除 EIMSK 寄存器中的中断允许位来禁止中断。否则当位改变时会发生中断。

编辑:

EIFR——外部中断标志寄存器

• 位 7:0 – INTF7:0:外部中断标志 7 - 0

当 INT7:0 引脚上的边沿或逻辑变化触发中断请求时,INTF7:0 置位(一)。如果 SREG 中的 I 位和 EIMSK 中相应的中断使能位 INT7:0 置位(1),MCU 将跳转到中断向量。执行中断程序时清除该标志。或者,可以通过向其写入逻辑 1 来清除该标志。

尝试清除中断中的标志

EIFR = (1 << INT0); 

不要使用

EIFR |= (1<< INT0);  // DO NOT USE

这将清除所有挂起的标志。

于 2013-08-30T17:55:39.960 回答