正在使用的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倍!如果我删除“切换触发”项目,信号就可以了。
答案 0 :(得分: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置位(一), MCU将跳转到中断向量。标志清除时 执行中断程序。或者,标志可以是 通过写一个逻辑的清除它。
尝试清除中断中的标志
EIFR = (1 << INT0);
不要使用
EIFR |= (1<< INT0); // DO NOT USE
这将清除所有挂起的标志。