Hallo nochmal,
also falls es jemanden interessiert, ich habe das ganze für Meine Zwecke (Ausgabefrequenz habe ich mal auf zwischen 35 bis 2100 Hz festgelegt) folgendermaßen realisiert:
Code:
//toggled zwei Ausgänge
ISR(TIMER2_COMP_vect)
{
MOT_A_PORT ^= (1<<MOT_A_C_PIN);
MOT_B_PORT ^= (1<<MOT_B_C_PIN);
}
...
uint8_t autodetect(uint16_t *ps, uint8_t *ocr, uint16_t freq)
{
uint32_t i, ocra;
uint32_t nenner;
uint32_t prescale[] = {1,8,32,64,128,256,1024}; //mögliche Values für Timer2 lt Datenblatt...
for (i = 0; i < 7; i++)
{
nenner = 2*prescale[i]*freq;
ocra = round((16000000/nenner));
//wenn Wert gefunden wurde, der in OCRA passt, schreiben und Funktion beenden
//nach Tests war immer der erste ermittelte Wert der genaueste für die Ausgabefrequenz. Alle folgenden waren ungenauer...
if (ocra < 255)
{
*ps = prescale[i];
*ocr = ocra;
return 0;
}
}
return 1;
}
...
// irgendwo im Programm
uint8_t ocr_value;
uint16_t prescaler;
if (autodetect(&prescaler, &ocr_value,isr_frequency) == 1) return 1;
else
{
if (prescaler == 1) TCCR2 |= (1<<CS20);
else
if (prescaler == 8) TCCR2 |= (1<<CS21);
else
if (prescaler == 32) TCCR2 |= (1<<CS21) | (1<<CS20);
else
if (prescaler == 64) TCCR2 |= (1<<CS22);
else
if (prescaler == 128) TCCR2 |= (1<<CS22) | (1<<CS20);
else
if (prescaler == 256) TCCR2 |= (1<<CS22) | (1<<CS21);
else
if (prescaler == 1024) TCCR2 |= (1<<CS22) | (1<<CS21) | (1<<CS20);
}
TCCR2 |= (1<<WGM21); //setze CTC Modus
OCR2 = ocr_value;
TIMSK |= (1<<OCIE2); //starte Timer
Bin für Kritik natürlich offen.
Viele Grüße,
Simon
Lesezeichen