Hi All:
My course work gives the following code to program ATmeag 1284P chip for sound output via a speaker. But for some reason the output tone (tune?) or frequency is incorrect -- way off. I tried several speakers, the same wrong tune. Can anyone please help? The code itself works but jut the output after calling the, for example, set_PWM(500) function (500 Hz), i hear something much lower in frequency tune.
void set_PWM(double frequency) {
// Keeps track of the currently set frequency
// Will only update the registers when the frequency
// changes, plays music uninterrupted.
static double current_frequency;
if (frequency != current_frequency) {
if (!frequency) TCCR3B &= 0x08; //stops timer/counter
else TCCR3B |= 0x03; // resumes/continues timer/counter
// prevents OCR3A from overflowing, using prescaler 64
// 0.954 is smallest frequency that will not result in overflow
if (frequency < 0.954) OCR3A = 0xFFFF;
// prevents OCR3A from underflowing, using prescaler 64 // 31250 is largest frequency that will not result in underflow
else if (frequency > 31250) OCR3A = 0x0000;
// set OCR3A based on desired frequency
else OCR3A = (short)(8000000 / (128 * frequency)) - 1;
TCNT3 = 0; // resets counter
current_frequency = frequency;
}
}
void PWM_on() {
TCCR3A = (1 << COM3A0);
// COM3A0: Toggle PB6 on compare match between counter and OCR3A
TCCR3B = (1 << WGM32) | (1 << CS31) | (1 << CS30);
// WGM32: When counter (TCNT3) matches OCR3A, reset counter
// CS31 & CS30: Set a prescaler of 64
set_PWM(0);
}
void PWM_off() {
TCCR3A = 0x00;
TCCR3B = 0x00;
}