【问题标题】:Why isn't PWM signal coming out?为什么没有PWM信号输出?
【发布时间】:2017-10-05 21:55:14
【问题描述】:

我正在做一个项目,为此我需要来自两个不同 ADC 的两次测量以及与它们相关的两个不同 PWM 信号。测量值存储在变量freqduty 中。正如名称所述,我希望一个 PWM 信号的频率根据freq 的值而变化,而另一个必须根据duty 改变其占空比。问题是第一个信号可以正常工作,但第二个不行。

我正在使用 ATmega328p。我尝试使用常量值而不是变量duty,但同样的事情发生了。代替 PWM 信号,输出引脚 (OC0B) 始终设置为高电平,即 5 V DC。功能真的很简单:

//Timer0 configuration
TCCR0A = 0b00100011;
TCCR0B = 0b00001001; //Fast PWM, no prescaler, non-inverted, out OC0B
OCR0B = duty;

我已经三重检查了TCCR0 寄存器的值,但一切似乎都是正确的。什么可能导致这种行为?

【问题讨论】:

  • this web page 上对此进行了广泛的讨论。
  • 您可能想使用模式 3 而不是模式 7。或者您忘记设置 OCR0A
  • @EdgarBonet 对不起我的无知,但你是什么意思?我不明白您所说的“模式 3”或 7 是什么意思。另外,如果我想使用 B 输出,为什么要设置 OCR0A

标签: c avr atmega pwm


【解决方案1】:

将我的评论扩展为完整的答案。

page 140 of the datasheet 上有一个表格列出了所有 “波形生成模式”。您在问题集中显示的代码 定时器进入模式 7:快速 PWM,TOP = OCR0A。在这个 模式下,定时器从零计数到 OCR0A 中存储的值,然后 回滚到零并重新开始。您可以使用此模式生成 OC0B 上的 PWM 信号。然后,您将能够控制两个信号 周期(通过设置 OCR0A 寄存器)和脉冲宽度(通过 OCR0B)。 如果设置 OCR0A 失败,则默认为零,不起作用。

如果您对 256 个时钟周期感到满意并且不希望 要更改它,您可以将 255 写入 OCR0A。或者,你 可以将定时器设置为模式 3:快速 PWM,TOP = 0xff。在 此模式,周期为 256 个周期,与值无关 存储在 OCR0A 中。

下面是一个简单的测试程序,演示了模式 3 的使用。 它产生一个脉宽为 64 个 CPU 周期的 PWM 信号, 周期为 256 个周期。

#include <avr/io.h>

int main(void)
{
    uint8_t duty = 64;

    // Set pin PD5 = OC0B as output.
    DDRD  |= _BV(PD5);

    // Configure Timer 0.
    OCR0B  = duty - 1;    // set duty cycle
    TCCR0A = _BV(COM0B1)  // non-inverting PWM on OC0B
           | _BV(WGM00)   // mode 3: fast PWM, top = 0xff
           | _BV(WGM01);  // ditto
    TCCR0B = _BV(CS00);   // clock at F_CPU

    for (;;) ;
}

【讨论】:

    猜你喜欢
    • 2021-02-16
    • 1970-01-01
    • 1970-01-01
    • 2012-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    • 2019-12-21
    相关资源
    最近更新 更多