正常模式下的定时器触发AVR128DB48的中断

问题描述

我试图将AVR128DB48上的定时器触发中断设置为每秒8k次。我用来初始化时钟的初始化代码如下。

//clock init
//24Mhz/64 = 375k
//(1/375k)*top=(1/8000)
//top = 46
TCA0.SINGLE.PER = 46;
//enables overflow interrupt
TCA0.SINGLE.INTCTRL |= 0x1;
//sets clock divider to 64 enables clock
TCA0.SINGLE.CTRLA |= TCA_SINGLE_RUNSTDBY_bm | TCA_SINGLE_ENABLE_bm | (5<<1);

这几乎与文档所说的初始化代码一样。为了测试中断,我将此函数用作中断处理程序

ISR(TCA0_OVF_vect)
{
    outputval = !outputval;
    if (outputval){
        PORTC.OUT |= 2;
    }
    else{
        PORTC.OUTCLR |= 2;
    }    
    return;
}

当我将此引脚连接到示波器并测量频率时,它将读取35k的输出频率。如果我将per值更改为任何值,它也始终会显示35k。我用100和200之类的值进行了测试,结果均相同。我还更改了时钟分频器,但仍然得到35k的相同结果。如果我没有设置使能位,则不会得到任何输出我有什么想念的吗?中断OVF不会执行我认为的操作吗?我已经阅读了几次文档,并且我相信我所做的一切都正确。

解决方法

如kkrambo所指出的那样,问题在于AVR128DB48不会由中断控制器自动清除此中断标志,因此您需要在中断处理程序末尾清除该标志,然后再返回。如果您不这样做,它将连续不断地尝试为中断服务。这是通过将1写入中断标志来完成的,对于该外设,此中断(OVF)由以下代码完成:

console.log(dateTime.toISOString())

因此,整个中断的修订代码为:

TCA0.SINGLE.INTFLAGS |= 0x1;