【发布时间】:2015-12-16 22:11:01
【问题描述】:
我试图在我的 ATmega32U4 leonardo 板上创建一个 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
}
有效的循环:
setupTimer();
for (;;) {
if (TIFR1 & (1 << OCF1A)) {
PORTC ^= (1 << PORTC7);
TIFR1 = (1 << OCF1A);
}
}
不起作用的中断:
#include <avr/interrupt.h>
ISR(TIMER1_COMPA_vect) {
PORTC ^= (1 << PORTC7);
}
我一定遗漏了一些东西,因为我在教程中看到了上面的代码应该可以工作。这里有一个有趣的观察结果是,如果我在调用 sei() 时同时在代码中同时包含循环和中断,则 LED 不会闪烁,就好像 OCF1A 寄存器被过早清除一样。
我很确定在这种情况下它无关紧要,但保险丝如下:E:CB,H:D8,L:FF。
我使用avr-g++编译,代码分散在几个文件之间。
【问题讨论】:
-
如果代码使用
_BV()宏作为位掩码而不是手动移动 1,我发现代码更易于阅读。
标签: timer avr atmega avr-gcc avrdude