Timer AVR ATmega32U4定时器比较中断未触发

Timer AVR ATmega32U4定时器比较中断未触发,timer,avr,atmega,avr-gcc,avrdude,Timer,Avr,Atmega,Avr Gcc,Avrdude,我试图在我的ATmega32U4莱昂纳多板上创建CTC定时器中断。当我连续检查OCF1A的值时我检测输出何时达到所需值没有问题,但是一旦我将代码移动到中断中,中断就不会触发。 计时器设置: #include <avr/io.h> void setupTimer() { TCCR1B |= (1 << WGM12); // CTC mode TCCR1B |= ((0 << CS10) | (0 << CS11) | (1 <

我试图在我的ATmega32U4莱昂纳多板上创建CTC定时器中断。当我连续检查
OCF1A的值时
我检测输出何时达到所需值没有问题,但是一旦我将代码移动到中断中,中断就不会触发。
计时器设置:

#include <avr/io.h>

void setupTimer()
{
    TCCR1B |= (1 << WGM12); // CTC mode
    TCCR1B |= ((0 << CS10) | (0 << CS11) | (1 << CS12)); // set up prescaler
    OCR1A = 6249; // 100 ms set up output compare value for interrupt
    TIMSK1 |= (1 << OCIE1A); // enable interrupt on clock compare
}
#包括
void setupTimer()
{
TCCR1B |=(1您有两个问题:

  • 您需要确保
    main()

  • 设置完所有内容后,您需要通过
    sei()
    启用中断

  • 下面是一个工作示例(我将LED端口更改为
    PB5
    ,因为我已经在Arduino Uno上进行了测试,并且已经内置了LED)

    #包括
    #包括
    空干管()
    {
    
    DDRB |=1这个问题今天也让我困惑。通过搜索我找到了你的问题。我在各地做了更多搜索,但没有找到这个问题的答案。我原以为我一定忘了启用一些电路或设置一些标志。最后,通过LED作为我的调试器,我找到了原因

    问题出在引导加载程序上,而不是你的代码。要让它工作,你只需从USB拔下主板(在通过引导加载程序编写代码之后),并重新插入,使引导加载程序在通电时直接跳转到您的代码,并在那里工作。引导加载程序在上载代码时一定做了一些花哨的工作,但在这种情况下,之后工作并不顺利


    作为参考,我使用了一个ProMicro板,我相信Caterina bootloader与您使用的Leonardo板相同。

    鉴于有人在这个问题被问到两年后通过谷歌来到这里,我想我应该分享我自己在这个问题上的发现

    我的问题中提供的代码是正确的,假设在
    setupTimer()之后的某个地方调用了
    sei()
    中断应该正确触发。问题正如他的回答所述-引导加载程序弄乱了一些寄存器,从而阻止了代码正确运行。然而,我对这个问题的解决方案与我的情况略有不同,即使在拔下并重新插上boar之后,中断也不会触发d(有可能引导加载程序在我提出这个问题后的两年内发生了变化)


    防止代码和引导加载程序之间发生冲突的最简单方法是简单地删除引导加载程序。通过使用USBasp程序员,您可以简单地将自己的代码加载到主板上,从而确保它是CPU上唯一运行的东西。

    我发现如果使用
    \u BV()
    macro用于位掩码,而不是手动移位1。是的,我知道并且我做了你提到的两件事,我只是在问题中只包含了代码中最相关的部分。中断不触发的问题仍然存在,我可以看到3种可能的来源:代码、生成文件或保险丝。在这一点上,除非我缺少一些weird注册表设置问题可能与代码无关,我不确定是否可能通过makefile或fuse设置导致此类问题。
    setupTimer();
    for (;;) {
        if (TIFR1 & (1 << OCF1A)) {
            PORTC ^= (1 << PORTC7);
            TIFR1 = (1 << OCF1A);
        }
    }
    
    #include <avr/interrupt.h>
    
    ISR(TIMER1_COMPA_vect) {
        PORTC ^= (1 << PORTC7);
    }
    
    #include <avr/interrupt.h>
    #include <avr/io.h>
    
    void main ()
    {
        DDRB |= 1 << DDB5;
    
        TCCR1B |= 1 << WGM12;
        TCCR1B |= 1 << CS12;
        OCR1A = 6249;
        TIMSK1 |= 1 << OCIE1A;
    
        sei();
        for(;;);
    }
    
    ISR(TIMER1_COMPA_vect)
    {
        PORTB ^= 1 << PORTB5;
    }