【问题标题】:AVR CTC Timer Frequency Apparent InaccuracyAVR CTC 定时器频率明显不准确
【发布时间】:2018-11-04 22:43:40
【问题描述】:

我是 AVR 设备编程的初学者,试图摆脱低效的 _ms_delay() 和 _us_delay() 阻塞功能,我一直在尝试使用内置定时器来控制基本 LED 的时序在 16 位定时器上使用 CTC 定时器模式闪烁程序。我的目标是让 LED 以 2 Hz 的频率闪烁,点亮 0.5 秒,熄灭 0.5 秒。

根据ATMega328P datasheet,CTC 输出的频率应该是 f_CTC = f_Clock/(2N(OCR1A+1),因为我的芯片是 328P Xplained mini,它的默认 CPU 速度是 16 MHz,使用上述公式,在 N=64 的情况下,实现我想要的频率所需的 OCR1A 值应该是 62499。考虑到所有这些,我编写了以下代码:

#include <avr/io.h>

int main(void)
{
    // Setup for timer TC1 (16-bit) in CTC mode to run at 2 Hz
    TCCR1A = 0x00;
    OCR1A = 62499; // Sets time resolution to 0.5 s
    TCCR1B = 0x0b;
    TCCR1C = 0x00;

    // Set pin directions
    PORTD &= ~(1<<PORTD6);
    DDRD |= (1<<DDD6);

    while (1) 
    {
        if(TIFR1 & (1<<OCF1A))
        {
             PORTD ^= (1<<PORTD6);
        }
        TIFR1 |= (1<<OCF1A);
    }
}

但是,当我运行代码时,LED 以 1 Hz 的频率闪烁,我可以通过手机进行计时。此外,当我将 OCR1A 更改为 31249 时,它应该将频率增加到 4 Hz,它似乎以 8 Hz 的频率闪烁,或者每秒开关 4 次。我觉得我对 CTC 模式的工作原理有一些误解,如果有人可以简单地向我解释一下,或者我的代码有任何其他问题,我将不胜感激。

【问题讨论】:

  • "我的目标是让 LED 以 2 Hz 的频率闪烁,亮 0.5 秒,灭 0.5 秒。"您描述的模式是 1 Hz,因为它每秒重复一次。
  • 只是一个侧面说明:只要您的 AVR 没有比忙着等待更好的事情要做,那就没有错。这里没有效率低下这样的东西。
  • @tofro 好点...我只是知道作为一个新手程序员(我是)很容易养成坏习惯,所以在我的 AVR 确实需要的情况下做一些我想做的事情:)

标签: timer frequency avr timing atmega


【解决方案1】:

我注意到一件事可能会导致您看到的问题。

您正在使用TIFR1 |= (1&lt;&lt;OCF1A); 行来清除OCF1A 位。您非常频繁地运行该行,因此当 OCF1A 被设置时,您的代码很可能会在 if 语句看到它被设置之前立即清除它。您无法控制该位何时设置;它可以在循环中的任何时候发生。

只有在验证 OCF1A 为 1 后才能清除它,如下所示:

if (TIFR1 & (1 << OCF1A))
{
    PORTD ^= (1 << PORTD6);
    TIFR1 |= (1 << OCF1A);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-18
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多