Hallo
Gleich vorweg: Ich bin ziemlich unmusikalisch, ein mäsiger Mathematiker und ich besitze kein M32. Aber ich kann versuchen, dir (mehr oder weniger gut) die Funktion von beep() erklären:
Basis ist der Timer2 der im CTC-Mode mit Perscaler /256 betrieben wird. Die Funktion des OC2-Pins steht dabei auf togglen:
Code:
void beep(uint8_t pitch, uint16_t time)
{
controlStatus.beep = true;
sound_timer = time;
OCR2 = 255-pitch;
// CTC-Mode, toggle OC2, prescaler /256
TCCR2 = (1 << WGM21) | (1 << COM20) | (1 << CS22) | (1 << CS21);
}
(Die Funktion beep() aus der Datei RP6ControlLib.c)
Der Prescaler teilt den Kontrollertakt und erzeugt den Countertakt. Bei jedem Countertakt zählt der Counter das Zählregister TCNT2 um einen Schritt weiter. Wenn das Zählregister gleich dem Wert im OCR2-Register ist, wird der Ausgang OC2 (an dem der Lautsprecher angeschlossen ist) umgeschaltet und das Zählregister startet wieder bei 0. Wenn wir uns nun auf die Formeln stürzen, müssen wir noch beachten, dass eine Schwingung aus zwei Counterdurchläufen besteht, der OC2-Pin also zweimal umgeschaltet werden muss und dass der maximale Wert für OCR2 255 ist (Timer2 hat 8 Bit):
Höchste Frequenz bei OCR2=1:
16000000MHz/256 Prescaler/2 Halbwellen=31250 Hz
Tiefste Frequenz bei OCR2=255:
16000000MHz/256 Prescaler/2 Halbwellen/255 Countertakte= ca. 120 Hz
Berechnung des OCR2-Wertes aus der gewünschten Frequenz des Tones:
16000000MHz/256 Prescaler/2 Halbwellen/ Tonfrequenz ergibt für den Kammerton "A" 31250Hz/440Hz ca. 71
Da die beep()-Funktion den Parameter nicht direkt ins OCR2-Register schreibt, müssen wir den Parameter noch anpassen:
beep(255-(31250/440), dauer)
(Keine Gewähr für diese Berechnung;)
Gruß
mic
Lesezeichen