gpt4 book ai didi

c++ - AVR CTC 模式下的 16 位定时器

转载 作者:太空宇宙 更新时间:2023-11-04 11:42:22 25 4
gpt4 key购买 nike

我正在尝试使用 Arduino Uno 开发板(ATmega328,16 MHz)实现这一目标。所以我通过互联网搜索并想出了这样的东西:

unsigned long Time=0;

int main (void)
{
Serial.begin(9600);

cli();

TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;

OCR1A = 15999; // Compare value

TCCR1B |= (1 << WGM12)| (1 << CS10); // Prescaler
TIMSK1 |= (1 << OCIE1A); // Enable timer compare interrupt

sei();

while(1) {

Serial.println(TCNT1);
}

return 0;
}


ISR(TIMER1_COMPA_vect)
{
Time++;
Serial.println(Time);
}

我试图达到 1 kHz 的频率,因此我将能够创建几毫秒长的间隔。

这就是为什么我选择比较值为 15999(所以 16000-1)并且预分频器等于 1,所以我得到(至少我认为是正确的计算):

Frequency = 16.000.000 MHz/16000 = 1000 Hz = 1 kHz

现在的问题是,即使 Serial.println(TCNT1) 显示我计数到 16000 的数字,回到零,达到 16000,回到零,..., Serial.println(Time) 刚数到 8,它就停止计数,尽管 TCNT1 仍在计数。

我想过某处有某种溢出,但我想不出在哪里;我想到的唯一一件事是比较值可能太大,正如我所想的那样 - 显然不是这种情况,因为 2^16 -1=65.535>15999

例如,如果我制作预分频器(假设为 64)并保留比较值,Time 将按预期计数。所以我想知道:为什么 ISR() 停止在值为 8 时被调用,但在启动预分频器时仍然有效?

最佳答案

我不确定,但根据您使用的 Arduino 版本,println 调用会被阻塞。如果调用它的速度快于它在 ISR 中完成的速度,堆栈就会溢出。

如果您想要更高分辨率的计时,可以尝试在您的 Loop() 中对 getMicroseconds 结果进行差分。您应该在 Loop() 中循环比每毫秒一次快得多。

如果您想每毫秒执行一次操作,请捕获开始微秒,然后在 Loop() 函数的条件中从当前微秒中减去它。当你看到超过 1000 人做任务时...

关于c++ - AVR CTC 模式下的 16 位定时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20888246/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com