ATmega32U4:启用中断挂起
ATmega32U4: enabling interrupts hangs
#include <avr/io.h>
#include <avr/interrupt.h>
void delay() {
volatile uint16_t i;
for (i=1e6; i; i--);
}
int main(void) {
DDRB = 255;
/* sei(); */
while (1) {
PORTB ^= 1;
delay();
}
}
上面的程序使 LED 闪烁。在 sei();
未注释的情况下,它不会。我没有启用任何中断源,数据表说它们默认情况下都是关闭的,虽然引导加载程序 (Caterina) 确实使用了 TIMER1_COMPA,但它在 运行 我的代码之前再次将其关闭。
它似乎不可能调用未定义的中断处理程序。但是我很困惑为什么它不会像眨眼那样远。
这是怎么回事?
如果 LED 一直亮着,可能是看门狗定时器中断。在闪烁发生之前,您的微控制器已重新启动。我记得,它可能是 enabled/disabled 使用保险丝位。
原来引导加载程序[1]使 USB 控制器处于启用状态并生成中断。
添加一个空的 ISR(USB_GEN_vect)
修复了挂起但导致闪烁速度大幅减慢,这可能是由于 ISR 实际上没有对首先导致中断的条件做任何事情,因此被重复调用。
在 sei();
之前添加 USBCON = 0;
工作正常。
[1] 如前所述,卡特琳娜。引导加载程序的代码位于 https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/bootloaders/caterina/
#include <avr/io.h>
#include <avr/interrupt.h>
void delay() {
volatile uint16_t i;
for (i=1e6; i; i--);
}
int main(void) {
DDRB = 255;
/* sei(); */
while (1) {
PORTB ^= 1;
delay();
}
}
上面的程序使 LED 闪烁。在 sei();
未注释的情况下,它不会。我没有启用任何中断源,数据表说它们默认情况下都是关闭的,虽然引导加载程序 (Caterina) 确实使用了 TIMER1_COMPA,但它在 运行 我的代码之前再次将其关闭。
它似乎不可能调用未定义的中断处理程序。但是我很困惑为什么它不会像眨眼那样远。
这是怎么回事?
如果 LED 一直亮着,可能是看门狗定时器中断。在闪烁发生之前,您的微控制器已重新启动。我记得,它可能是 enabled/disabled 使用保险丝位。
原来引导加载程序[1]使 USB 控制器处于启用状态并生成中断。
添加一个空的 ISR(USB_GEN_vect)
修复了挂起但导致闪烁速度大幅减慢,这可能是由于 ISR 实际上没有对首先导致中断的条件做任何事情,因此被重复调用。
在 sei();
之前添加 USBCON = 0;
工作正常。
[1] 如前所述,卡特琳娜。引导加载程序的代码位于 https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/bootloaders/caterina/