Hallo liebe Foren-Mitglieder! Ich habe folgendes Problem: Derzeit versuche ich einen Frequenzzähler mit einem ATmega16 zu realisieren. Meine Idee war es zu Übungszwecken, erstmal die beiden 8-Bit Counter für das Zählen einer relativ niedrigen Frequenz zu verwenden. Dabei ergab sich jedoch schon folgende Problematik: Um eine Zeitbasis von 2.5µs zu realisieren, wollte ich den Timer0 direkt mit der Taktfrequenz (12MHz) des Mikrocontrollers, also mit Prescaling-Faktor von 0 im CTC-Modus bis auf 30 Zählen lassen (im Compare-Register, wurde somit 30, als maximaler Zählerstand eingestellt). Wenn der Zähler nun den Wert 30 erreicht hat, sollte er einen Interrupt auslösen, welcher ein LED-Band (an PortC) toggelt. Die LEDs sollten dabei mit einer theoretischen Frequenz von 200kHz "blinken", welches ich mit einem Oszilloskop überprüfen wollte: Herleitung der 200kHz Toggelfrequenz F_blink = (F_CPU/Compare-Wert)/2 | | | Taktfrequenz des µC | | maximaler Zählerstand | /2 (weil getoggelt) Die Messung ergab jedoch eine Frequenz von 178kHz. Ich habe die Messung zur Sicherheit noch an einem anderen µC überprüft und es stellte sich exakt die selbe Frequenz ein. Ich kann mir das nicht erklären! Hat vielleicht jemand eine Idee, wie diese Frequenz-Toleranz von 11% zustande kommen kann?? Danke bereits im Voraus für die Antworten. PS: Die Quarzfrequenz habe ich bereits überprüft, sie war OK & im Anhang ist noch der Quelltext zu finden!!
>Um eine Zeitbasis von 2.5µs zu realisieren, wollte ich den Timer0 direkt >mit der Taktfrequenz (12MHz) des Mikrocontrollers, also mit Also mit 83.3 ns pro Maschinenzyklus und damit 30 Takten für deine 2.5us. Such dir ne andere Aufgabe.
Hallo, ben91 schrieb: > Um eine Zeitbasis von 2.5µs zu realisieren, wollte ich den Timer0 direkt > mit der Taktfrequenz (12MHz) des Mikrocontrollers, also mit > Prescaling-Faktor von 0 im CTC-Modus bis auf 30 Zählen lassen (im > Compare-Register, wurde somit 30, als maximaler Zählerstand > eingestellt). > Wenn der Zähler nun den Wert 30 erreicht hat, > sollte er einen Interrupt auslösen, > welcher ein LED-Band (an PortC) toggelt. > Die LEDs sollten dabei mit einer theoretischen Frequenz von 200kHz > "blinken", welches ich mit einem Oszilloskop überprüfen wollte: > > Herleitung der 200kHz Toggelfrequenz F_blink = (F_CPU/Compare-Wert)/2 > | | | > Taktfrequenz des µC | | > maximaler Zählerstand | > /2 (weil > getoggelt) Das Datenblatt sagt da (F_CPU/Compare-Wert)-1 > Die Messung ergab jedoch eine Frequenz von 178kHz. > Ich habe die Messung zur Sicherheit noch an einem anderen µC überprüft > und es stellte sich exakt die selbe Frequenz ein. > Ich kann mir das nicht erklären! > Hat vielleicht jemand eine Idee, wie diese Frequenz-Toleranz von 11% > zustande kommen kann?? Denke mal darüber nach, wieviele Takzyklen den AVR für die IRQ-Bearbeitung bleiben und schau ins Datenblatt und ins ASM-Listing, daß der Compiler erzeugt, wieviele er braucht. Probiere es z.B. mal mit 50kHz, ob es da passt. Gruß aus Berlin Michael
HI OCR=30 ist schon mal falsch. Das muss 29 sein. Wo der Restfehler herkommt kann ich jetzt auch nicht sagen. MfG Spess
@ ben91 (Gast) >Um eine Zeitbasis von 2.5µs zu realisieren, wollte ich den Timer0 direkt >mit der Taktfrequenz (12MHz) des Mikrocontrollers, also mit >Prescaling-Faktor von 0 im CTC-Modus bis auf 30 Zählen lassen (im >Compare-Register, wurde somit 30, als maximaler Zählerstand >eingestellt). Und dir ist klar, dass du damit alle 30 Takte einen Interrupt hast? Wieviel Befehle soll denn die CPU mit diesen 30 Takten ausführen? >Die Messung ergab jedoch eine Frequenz von 178kHz. Tja, dann braucht dein Interrupt halt mehr als 30 Takte. Was in C auch fast normal ist. Dein Konzept ist unbrauchbar. MFG Falk
Zähl mal die Takte deiner Interrupt-Routine (generierten Assemblercode ansehen und den Sprung zur Interrupt-Routine nicht vergessen!). Vermutlich wird als Ergebnis rauskommen, dass das 34 oder 35 Takte sind... Andreas
Hallo,
erst mal danke für die Zahlreichen Antworten!
Michael U. schrieb:
> Das Datenblatt sagt da (F_CPU/Compare-Wert)-1
... dann sollte sich laut deiner Theorie bei meinem Programm eine
Frequenz von ca. 199kHz einstellen (anstelle der gemessenen 178kHz)
Ich habe noch einen wichtigen Aspekt vergessen, zu erwähnen:
Wenn ich den Compare-Wert auf z.B. 40 erhöhe,
dann stimmt die daraus errechnete theoretische Frequenz exakt mit dem
gemessenen Wert überein!!
>Wenn ich den Compare-Wert auf z.B. 40 erhöhe, >dann stimmt die daraus errechnete theoretische Frequenz exakt mit dem >gemessenen Wert überein!! Dann schafft dein Programm es mit 40 Takten halt gerade mal so;)
Holger schrieb:
>Dann schafft dein Programm es mit 40 Takten halt gerade mal so;)
... tja, dass hab ich mir eben auch gedacht,
bis zu einem Compare-Wert von 35 stimmt die Frequenz nicht,
jedoch bei allem was darüber liegt(zB. 36),
stimmt die Frequenz plötzlich exakt mit dem errechneten Wert überein?!
ben91 schrieb: > jedoch bei allem was darüber liegt(zB. 36), > stimmt die Frequenz plötzlich exakt mit dem errechneten Wert überein?! Ist das so schwer zu kapieren? Damit hast du jetzt erfolgreich rausgefunden, dass die minimale Zeit zwischen zwei Aufrufen deines Interrupts 37 Takte beträgt. Schneller geht's nur, wenn die Interruptroutine kürzer wird. Ein Prozessor ist kein Mensch, der eine Aufgabe nach Einarbeitung irgendwann schneller erledigen könnte. Da du aber noch andere Sachen machen willst als nur mit einem Pin rumzuwackeln (und dementsprechend der Code dann länger wird), ergibt sich die logische Folge, dass dein ganzes Konzept so nicht aufgeht, und du nochmal zurück ans Reissbrett musst. Andreas
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.