## ATmega328P - Problems using timer 2 for tone generation

5 posts / 0 new
Author
Message

New to the forum, so please forgive me if this is the wrong place for seeking help. I cannot for the life of me understand why this is not working. I'm simply trying to use timer 2 for tone generation and what I get is a very faint and strange tone (almost like its modulated somehow as there is a "pulsing" to it). Here's my simple code:

```#include <Arduino.h>

#define SPEAKER_PORT PORTC
#define SPEAKER_BIT 2

void setup()
{
pinMode(A2, OUTPUT);

TCCR2A = _BV(WGM21);  // CTC mode
TCCR2B = _BV(CS20);   // clk/1

OCR2A = 200;  // 8-bit timer, so keep less than 256
bitSet(TIMSK2, OCIE2A);  // enable OCR2A interrupt
}

void loop()
{
// NOP
}

ISR(TIMER2_COMPA_vect)
{
SPEAKER_PORT ^= _BV(SPEAKER_BIT);
}```

Any obvious mistakes? Thanks for your input!

This topic has a solution.
Last Edited: Thu. Nov 14, 2019 - 02:45 AM
This reply has been marked as the solution.

What frequency do you expect? 16000000/256 is way beyond my hearing! Try using a larger prescaler like 1024

That's a good point. I'll try that.

Just to elaborate:

freq = 16000000 /1024/n/2

Where 16000000 is the crystal freq (I'm assuming an Arduino uno board), 1024 is the prescaler, n is the compare value for CTC mode and 2 since you need a high and low for a complete period.

Based on this, the frequency range is 30.5Hz to 7812.5Hz which is within the range of human hearing.

If you want a fractional divisor, you will need to change the OCR value each cycle - this is called 'dithering'. To divide by 11.5, one cycle is 11, next cycle is 12, next is 11... rinse and repeat. For divide by 11.25, one cycle is 12,next is 11,next is 11,next is 11,next is 12 and so on.