我的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或更少。它可以是任何其他计时器,我不在乎。
答案 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 ...