I am trying to get PWM output from PB7 pin with timer0 on Atmega2560 with no luck. It should generate tone for the connected repro.My PWM settings are:
DDRB = 0b11100000;
PORTB = 0b00000000;
OCR0A = 0x04;
TCCR0A = (0 << COM0A1) | (1 << COM0A0) | (1 << WGM01) | (0 << WGM00);
TCCR0B = (0 << WGM02) | (0 << CS02) | (0 << CS01) | (0 << CS00);
and then I have this function, which should generate the sound:
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));
}
}
but nothing happens when i call it with tone parameter. Can you please help me?
Based on your comments, you are using ~12MHz clock as the input to your timer, and from your code, you are using 8 bit timer 0 in CTC mode with OCR0A as your top. You have OC0A set to toggle on a compare match.
According to the 2560 datasheet, the frequency of your timer is given by:
F_CLK/(2*(1 + OCR0A)) | F_CLK ~= 12MHz
This is an 8 bit timer, so that means that your minimum frequency that your PWM can generate is given by:
12e6/(2*(1 + 255)) ~= 20KHz
You simply aren't going to be able to generate an audible tone with that configuration unless you slow down the clock you are using for your timer or use a timer that can count higher.
1) Use a 16 bit counter (i.e. timer1). That will give you a min frequency of ~90Hz and a max frequency of ~6MHz, which should give you plenty of range to generate tones:
/* 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) Use the internal clock source as the timer clock instead of an external source. Unless you changed fuse bits or you are changing it in the code somewhere, the clock will be 1MHz. Prescaling the clock by 8 gives you a frequency range of ~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);