Bin für Kritik natürlich offen.
Ok, dann lege ich mal los.
* Warum ist i ein uint32_t? uint8_t würde reichen.
* Warum das uint32_t bei prescale[]? uint16_t würde reichen.
(wenn du das änderst, muss aber auch die Zeile der nenner-Berechnung geändert werden)
* Warum ist prescale[] eine automatic- und keine static-Variable?
* Wozu soll die Funktion round() da gut sein? "16000000/nenner" ist eine Integer-Division und hat immer ein ganzzahliges Ergebnis. Da gibt es für round() rein gar nichts zu runden.
All diese Punkte produzieren keinen Fehler, drücken aber auf die Performance. Was allerdings ein Fehler ist, ist dass du bei der OCR-Berechnung für den CTC-Modus ein "-1" vergisst.
Noch was: Du scheinst 0 für "Erfolg" und 1 für "Fehler" zu verwenden. Das finde ich etwas ungeschickt, weil es genau entgegen der boolschen Logik ist (0 = False, 1 = True). Ich würde auch nicht den Prescaler-Wert speichern, sondern den Index, denn den kann man im restlichen Code dann direkt verwenden.
So in etwa würde die Funktion bei mir aussehen:
Code:
uint8_t autodetect (uint8_t *ocr, uint8_t *pre, uint16_t freq) {
static uint16_t prescale[] = {1,8,32,64,128,256,1024}; //mögliche Values für Timer2 lt Datenblatt...
for (uint8_t i = 0; i < 7; i++) {
uint32_t nenner = 2UL * prescale[i] * freq;
if (nenner >= (F_CPU/256)) {
*ocr = ((F_CPU+(nenner/2)) / nenner) - 1;
*pre = i + 1;
return 1;
}
}
return 0;
}
Und im restlichen Code dann:
Code:
uint8_t prescaler_index;
uint8_t ocr_value;
if (!autodetect(&ocr_value,&prescaler_index,isr_frequency))
return 0;
TCCR2 |= (prescaler_index<<CS20);
OCR2 = ocr_value;
Lesezeichen