【问题标题】:1 MHz timer on a 16 MHz ATmega853516 MHz ATmega8535 上的 1 MHz 定时器
【发布时间】:2013-05-19 19:01:23
【问题描述】:

我似乎无法理解这一点,尽管对我来说这看起来很容易。 我在我的 Atmel ATmega8535 中制作了很多计时器,但这个让我很受打击。 另外,我看过很多计算等,但并不是我想要的。

很简单:

我的 ATmega8535 以 16 MHz 运行,而我只需要一个 1 MHz 的计时器,因此我可以在某些引脚上以 1 MHz 的频率输出一些数据。

那么我该如何进行呢? 下面的计算听起来不错(找到here)。

Target Timer Count = (1 / Target Frequency) / (1 / Timer Clock Frequency) - 1
                   = (1 / 1000000) / (1 / 16000000) - 1
                   = 0.000001 / 0.0000000625 - 1
                   = 16 - 1
                   = 15

那么这将导致

void initTimer()
{
    // 8 bit timer 2 setup
    TCCR2 = (1<<CS20); // Timer clock = system clock/1
    TIFR  =  1<<TOV2;  // Clear TOV2/ clear pending interrupts
    TIMSK =  1<<TOIE2; // Enable timer 2 overflow interrupt
    sei();
}

ISR(TIMER2_OVF_vect) // 16 bit timer 2 overflow interrupt vector
{
    TCNT2 = 256-15;   // Make sure every overflow resets the TCNT2 to the 1 MHz setup
    addUpSomething++; // Do something (...not relevant to this sample)
}

如何正确进行这些计算?这会产生一个 1 MHz 的计时器吗?

【问题讨论】:

  • 我没有看到任何启动计时器的代码。
  • 你的意思是 SEI(); ?完全正确,我忘记了,我会编辑原帖
  • 我不知道SEI 是什么。但是您的示例似乎配置了几个中断,并设置了一个中断处理程序。但是那里没有真正初始化计时器状态并开始运行的代码。
  • 我添加了 TCCR2,预分频器设置为 1(无预分频)。这将启动计时器

标签: timer avr atmel atmega


【解决方案1】:

您在中断函数中执行的操作很可能比中断之间的间隔时间长。当您在 16 MHz 设备上有一个 1 MHz 定时器时,您在定时器中断之间有 16 个时钟滴答,这对于做任何有意义的事情来说并不是很多。

此外,您还需要调用中断函数的开销(仅此一项可能超过 16 个滴答声,但我不知道),这使您做某事的时间少于 16 个滴答声。当您的中断函数中运行的代码所占用的时间超过中断之间的间隔时,您基本上会将您的定时器频率降低一个未知的数量,并为您的主代码留下非常少的 CPU 时间。

我建议降低计时器频率,以便您的计时器中断有足够的时间运行,并为您的主代码(如果需要)留出足够的 CPU 时间,或者选择以更高 CPU 频率运行的设备。

【讨论】:

  • 感谢您的正确回答。我在 AVRStudio 模拟器中也注意到了这一点。我想我必须找到另一种以较慢速度输出数据的方式。不过,我认为我的计算是正确的吗? :-)
  • 是的,每 16 个时钟周期调用一次定时器中断。在 16 MHz 设备上,这意味着 16 MHz/16=1 MHz 定时器频率。
猜你喜欢
  • 1970-01-01
  • 2011-05-05
  • 1970-01-01
  • 1970-01-01
  • 2018-07-04
  • 1970-01-01
  • 2020-09-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多