【问题标题】:AVR (debugging) PWM generationAVR(调试)PWM 生成
【发布时间】:2017-10-06 05:53:56
【问题描述】:

我编写了一个简单的程序来生成占空比为 50% 的 PWM 波。然后我去 AtmelStudio 进行调试。除了 OCR0 之外的所有寄存器都被分配了相应的值。为什么 OCR0 没有分配任何值。 ATmega32,快速 PWM。

#include <avr/io.h>
int main(void)
{
DDRB = (1 << PB3);
TCCR0 |= (1 << WGM01) | (1 << WGM00) | (1 << COM01);
OCR0 = 127;
TCCR0 |= (1 << CS02);
return 0;
}

【问题讨论】:

  • 你永无止境的循环在哪里?
  • 是什么让您认为写入值的尝试没有成功?硬件规范是否将 OCR0 寄存器描述为可读的?它可能是只写的吗?
  • @tilz0R 请详细说明。什么是永无止境的循环?
  • @Lundin> 编译器(即 avr-gcc)在其文档中使用 int main(void) 和 return0;。它在微控制器上确实有意义,它具有 C 运行时库赋予它的任何意义。在大型系统上,它是“使用该错误代码清理并终止进程”,但运行时库可以完美地定义“以非零值退出主程序,我将疯狂地闪烁一些红色 LED” i>.
  • 别误会我的意思,我也不喜欢看到这种情况,即使我确实想冻结设备,我宁愿将其置于待机/睡眠模式。我只是想指出它是有效的,只要平台文档这么说它就有意义。它会生成与手册 for(;;) {} 完全相同的二进制文件。所以没有理由在这件事上叫他出来。实际上,使用 c++ 时它做得更好的一件事是:它在 main() 的范围内调用对象的析构函数,而手动无限循环不会这样做。

标签: c embedded avr


【解决方案1】:

不管怎样。

您正在 Atmega32 上使用 8 位 counter0。让我们看看你是如何设置的:

// Set Pin B3 as output, others as input
DDRB = (1 << PB3);

// Set Clear on compare match + Fast PWM mode + Counter stopped
TCCR0 |= (1 << WGM01) | (1 << WGM00) | (1 << COM01);

// Set comparator value to 127
OCR0 = 127;

// Enable clkIO/256 from prescaler, turning on the counter
TCCR0 |= (1 << CS02);

好的。首先,有几点:

  • 在初始设置时,您通常希望分配值而不是或它,以确定其状态。
  • 即使在此之后,设置它而不是 or-ing 也可以避免无用的读取。对此寄存器的行为没有影响,但性能可能会更好一些。
  • 文档建议仅在正确设置后启用输出,以避免虚假输出。所以你应该把第一行移到最后。

我将阅读数据表的that version。

现在,在快速 PWM 模式下,根据表 38 和 40,计数器的行为如下:

  • 从 BOTTOM 计数到 MAX(0 到 0xFF)。
  • OCR0 仅用于触发 OC0 引脚,不用于复位计数。
  • OCR0 具有双缓冲。它的实际值直到下一个周期才会更新。

这可能是您的问题。如果其中任何一个是真的:

  • 计数器无法正常启动(如果 CS2-0 不正确,由于 or-ing 而不是设置它们,可能会发生这种情况)。
  • 计数器提前停止(因为您的程序结束,如果工作室检测到它,它可能会在此时禁用它 - 我不使用工作室,所以我无法确定)。

那么你写入双缓冲区的值可能永远不会进入实际的寄存器。唉,数据表没有详细解释这是如何处理的。也不知道在双缓冲处于活动状态时读取 OCR0 是返回当前值还是等待值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多