为什么PWM信号不会出现?

时间:2017-10-05 21:55:15

标签: c avr atmega pwm

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

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

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

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

1 个答案:

答案 0 :(得分:0)

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

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的使用。 它产生一个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 (;;) ;
}