Atmega328p定时器配置错误

时间:2015-11-05 19:03:02

标签: arduino microcontroller avr

我的Atmega328p中断有问题。我使用Arduino Nano 16 Mhz 5V,因此它不会成为硬件问题。 这是我的代码:

#include <avr/io.h>
#include <avr/interrupt.h>

volatile uint16_t counter;

int main(void)
{
    DDRB |= (1<<PB5);

    TCCR1B |= (1 << CS10);          // set prescaler to 1
    TIMSK1 |= (1 << TOIE1);         // set overflow interrupt
    sei();                          // enable interrupts


    while (1)
    {
        // Main loop
    }
}

ISR (TIMER1_OVF_vect)
{
    counter++;
    if (counter > 200)
    {
        counter = 0;
        PORTB ^= _BV(PB5);
    }
}

我希望尽可能经常使用,但是这个配置二极管每1秒闪烁一次 - 这太慢了,如果可能的话,我至少需要每10us或更少。它可以是任何其他计时器,我不在乎。

2 个答案:

答案 0 :(得分:0)

定时器1是一个16位定时器,这意味着在正常模式下,它以大约244Hz的速率溢出。再加上你每201次溢出只翻转LED状态,你的闪烁率为0.6Hz。如果你想以100kHz的速率闪烁,那么你需要切换到TOP为79的CTC / OCRA模式(模式4)并改为使用输出比较中断。或者您可以使用模式14或15,并将TOP设置为159并将OC寄存器设置为适当的值,而不必担心中断。

答案 1 :(得分:0)

你最好使用定时器的CTC模式,因为它将OCR寄存器设置为某个值,使你的中断在10us,并从溢出中断变为比较中断,如下所示:

#include <avr/io.h>
#include <avr/interrupt.h>

volatile uint16_t counter;

int main(void)
{
    DDRB |= (1<<PB5);
    OCR1A = 80-1; // at 16MHz you need 160 cycles to reach 10us pulse...
    TCCR1A = 0; // no output compare and WGM1 to 00
    TCCR1B |= (1 << WGM12)|(1 << CS10); // set prescaler to 1 and CTC mode
    TIMSK1 |= (1 << OCIE1A);         // set compare A interrupt
    sei();                          // enable interrupts


    while (1)
    {
        // Main loop
    }
}

ISR (TIMER1_COMPA_vect) // check this too
{ // what was the counter stuff for? it only made things slower...
    PORTB ^= _BV(PB5);
  // keep the ISR as quick as posible, it takes about 1us gettin' in & out
}

我只是想OCRA应该是80,还是我记得,它应该是79 ...