【问题标题】:ATmega32U4: enabling interrupts hangsATmega32U4:启用中断挂起
【发布时间】:2016-10-24 08:57:59
【问题描述】:
#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,但它在运行我的代码之前再次将其关闭。

它似乎不可能调用未定义的中断处理程序。但我很困惑为什么它不会眨眼。

这是怎么回事?

【问题讨论】:

  • 你有调试器吗?
  • 要么是引导加载程序搞砸了中断,要么看门狗被配置为在中断模式下自动启动(参见熔断器)。
  • 旁注:将 uint16_t 变量初始化为 1e6 似乎很有趣。
  • @teroi 由于没有(全局)非易失性变量,内存屏障不会对生成的汇编代码产生任何影响。
  • 您在此处发布的代码不是问题的原因。您需要查看(或在此处为我们发布)引导加载程序以查看正在执行的操作...

标签: c microcontroller interrupt avr


【解决方案1】:

原来引导加载程序 [1] 使 USB 控制器处于启用状态并产生中断。

添加一个空的ISR(USB_GEN_vect) 修复了挂起,但导致闪烁的速度大大减慢,这可能是由于 ISR 实际上没有对首先导致中断的条件做任何事情,因此被重复调用。 在sei(); 之前添加USBCON = 0; 可以正常工作。

[1] 卡特琳娜,如前所述。引导加载程序的代码位于 https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/bootloaders/caterina/

【讨论】:

  • 这是MCU和bootloader组合的正确答案。为我解决了问题。
【解决方案2】:

如果 LED 保持亮起,则可能是看门狗定时器中断。你的微在闪烁发生之前重新启动。我记得,它可以使用保险丝位启用/禁用。

【讨论】:

  • 添加MCUSR &amp;= ~(1 &lt;&lt; WDRF); 和/或wdt_disable() 没有任何改变;我已经试过了。在主循环中添加wdt_reset() 也没有任何效果。 avrdude 将保险丝报告为E:CB, H:D8, L:FF,AFAICT 并不表示看门狗始终处于开启状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-03
  • 2017-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多