为什么PWM信号不出来?

Why isn't PWM signal coming out?

我正在做一个项目,我需要来自两个不同 ADC 的两个测量值和两个与之相关的不同 PWM 信号。测量值存储在变量 freqduty 中。顾名思义,我希望一个 PWM 信号的频率根据 freq 的值而变化,而另一个必须根据 duty 改变其占空比。问题是第一个信号正常,但第二个信号不正常。

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

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

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

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

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

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

下面是一个简单的测试程序,演示了模式 3 的使用。 它生成一个 PWM 信号,其中脉冲宽度为 64 CPU 个周期,并且 周期为 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 (;;) ;
}