PB7上的Atmega2560 PWM

时间:2017-06-06 08:52:21

标签: c embedded atmega atmel pwm

我试图通过Atmega2560上的timer0从PB7引脚获得PWM输出而没有运气。它应该为连接的repro生成音调。我的PWM设置是:

DDRB    = 0b11100000;
PORTB   = 0b00000000;

OCR0A = 0x04;
TCCR0A = (0 << COM0A1) | (1 << COM0A0) | (1 << WGM01) | (0 << WGM00);
TCCR0B = (0 << WGM02) | (0 << CS02) | (0 << CS01) | (0 << CS00);

然后我有这个功能,它应该产生声音:

void SoundOutput(unsigned int uintTone)
{
    if (uintTone != 0)
    {
        LED_2(1);
        OCR0A = uintTone;

        TCCR0B |= (1 << CS02) | (1 << CS01) | (1 << CS00);
    }
    else
    {
        TCCR0B &= ~((1 << CS02) | (1 << CS01) | (1 << CS00));
    }
}

但是当我用音调参数调用它时没有任何反应。你能帮我么?

1 个答案:

答案 0 :(得分:1)

根据您的评论,您使用~12MHz时钟作为定时器的输入,并且从您的代码中,您在CTC模式下使用8位定时器0,OCR0A作为您的顶部。您已将OC0A设置为在比较匹配时切换。

根据2560数据表,您的计时器的频率由下式给出:

F_CLK /(2 *(1 + OCR0A))| F_CLK~ = 12MHz

这是一个8位定时器,因此这意味着PWM可以产生的最小频率由下式给出:

12e6 /(2 *(1 + 255))〜= 20KHz

除非您减慢用于计时器的时钟或使用可以计数更高的计时器,否则您无法使用该配置生成可听音。

1)使用16位计数器(即timer1)。这将为您提供~90Hz的最小频率和~6MHz的最大频率,这将为您提供足够的范围来生成音调:

/* WGM BITS = 0100: CTC Mode */
/* COMA BITS = 01: Toggle OC1A on compare match */
/* CS BITS = 111: External clock source on rising edge */

TCCR1A = (0 << COM1A1) | (1 << COM1A0) | (0 << WGM01) | (0 << WGM00);
TCCR1B = (1 << WGM12) | (1 << WGM13) | (1 << CS02) | (1 << CS01) | (1 << CS00);

2)使用内部时钟源作为定时器时钟而不是外部源。除非您更改了熔丝位或者您在某处更改了代码,否则时钟将为1MHz。将时钟预分频为8可以得到~250Hz - ~60KHz的频率范围。

/* WGM BITS = 010: CTC Mode */
/* COMA BITS = 01: Toggle OC1A on compare match */
/* CS BITS = 010: Prescale the internal clock by 8 */

TCCR0A = (0 << COM0A1) | (1 << COM0A0) | (1 << WGM01) | (0 << WGM00);
TCCR0B = (0 << WGM02) | (0 << CS02) | (1 << CS01) | (0 << CS00);