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
@ 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