在正常模式下触发 AVR128DB48 中断的定时器
Timer In Normal Mode to Trigger an Interrupt on the 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。如果我将每个值更改为任何值,它也总是读取 35k。我用 100 和 200 这样的值测试了所有相同的结果。我还更改了时钟分频器,但仍然得到 35k 的相同结果。如果我不设置启用位,我就不会得到任何输出。有什么我想念的吗?中断 OVF 是否没有像我想的那样做?我已经多次阅读文档,我相信我做的一切都是正确的。
正如 kkrambo 所指出的,问题在于 AVR128DB48,中断控制器不会自动清除此中断标志,因此您需要在 return 之前在中断处理程序的末尾清除标志.如果您不这样做,它将不断尝试一遍又一遍地为中断服务。这是通过将 1 写入中断标志来完成的,对于这个外围设备和这个中断(OVF),通过下面的代码完成:
TCA0.SINGLE.INTFLAGS |= 0x1;
因此,整个中断的修改代码为:
ISR(TCA0_OVF_vect)
{
outputval = !outputval;
if (outputval){
PORTC.OUT |= 2;
}
else{
PORTC.OUTCLR |= 2;
}
TCA0.SINGLE.INTFLAGS |= 0x1;
return;
}
我正在尝试在 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。如果我将每个值更改为任何值,它也总是读取 35k。我用 100 和 200 这样的值测试了所有相同的结果。我还更改了时钟分频器,但仍然得到 35k 的相同结果。如果我不设置启用位,我就不会得到任何输出。有什么我想念的吗?中断 OVF 是否没有像我想的那样做?我已经多次阅读文档,我相信我做的一切都是正确的。
正如 kkrambo 所指出的,问题在于 AVR128DB48,中断控制器不会自动清除此中断标志,因此您需要在 return 之前在中断处理程序的末尾清除标志.如果您不这样做,它将不断尝试一遍又一遍地为中断服务。这是通过将 1 写入中断标志来完成的,对于这个外围设备和这个中断(OVF),通过下面的代码完成:
TCA0.SINGLE.INTFLAGS |= 0x1;
因此,整个中断的修改代码为:
ISR(TCA0_OVF_vect)
{
outputval = !outputval;
if (outputval){
PORTC.OUT |= 2;
}
else{
PORTC.OUTCLR |= 2;
}
TCA0.SINGLE.INTFLAGS |= 0x1;
return;
}