www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timerfrequenzberechung Mega8


Autor: Stefan J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallöchen !!

hab mal eine ich denke einfache Frage :

Ich verwende z.b. den 16Bit Timer des AVR Mega8.
Immer wenn der Timer das Ende erreicht hat, wird ein Interrupt
ausgelöst.
Wie berechnet sich nun aber die Frequenz, wie häeufig dieser
ausgelöst wird ?

Ich dachte so : (Frequenz des AVR  Prescale  Stufen Zähler) /2

Das würde als Bsp. ergeben : (4MHz  1  64393)/ 2 = 1749,78 Hz

Messtechnisch kommt bei mir mit dem Oszi aber 1652,87 Hz raus.

Irgenwo ein Fehler in der Berechnung ?


Stefan

Autor: leo9 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
verwundert, mein Rechner spuckt für
4000000  1  64393 / 2 = 31 aus, wie kommst du auf 1749 ?
warum 64393, der 16bit Timer läuft doch bei 256*256=65536 über?

grüsse leo9

Autor: Tom Bayer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann mir auch nicht so richtig erklären wie du darauf kommst und vor
allem was für ein Ergebnis du misst. Bei 4MHz zäht dein Counter ohne
Prescale alle 250ns einen Wert nach oben. Wenn du diesen Wert jetzt mal
deinen Stufen nimmst(das sind 2^16=65536)kommt man auf
16,384ms->61,035Hz. Formel also fsignal=fosz/presc./Stufen
Grüße Tom

Autor: Stefan J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, war falsch herrum.

(4MHz  1  1143)/ 2 = 1749,78 Hz

Also immer wenn der Interrupt auslöst, wird der Zähler auf 64393
voreingestellt.
Somit ereben sich dann bis zum Ende (65536-64393) 1143 Schritte.

Und ein Ausgang wird nach der Voreinstellung wechselnd auf 0/1 gesetzt.

Autor: Stefan J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso, ich versuche möglist genau 1750 Hz an einem Ausgang
hinzubekommen.

Autor: leo9 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Setzt du den Wert in der Interrupt-Routine oder verwendest du die
Capture-Compare Funktionen.
Bei ersterem wäre der Fehler klar. Vom Auftreten des Überlaufs über
Aufruf der Int-Routine bis zum setzten vergehen je nach Code ein paar
us und die machen dein Signal "langsamer".
Bei zweiterem mußt du wohl im Datenblatt nachlesen und den Geier in der
Konfig des Timers suchen.
Welchen Compiler verwendest du und wie schaut der source aus?

grüsse leo9

Autor: Stefan J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja ich setze den Wert in der Interrupt Routine. Hab ich mir
auch schon gedacht das es wohl einige Zeit dauert bis der Ausgang
angesprochen wird und das Signal wechselt.

Aber ich werde mal versuchen mich an die 1750 Hz so ranzutasten.

Gruß
Stefan

Autor: leo9 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Herantasten ist s......e, die Dauer bis zu deiner Routine ist variabel
(je nach dem während welchem Befehl der Int. auftritt). Wenn du schon
selber setzten willst, addiere bitte in deiner Int-Routine die 64...
zum aktuellen-Timer Wert dazu, damit ist die Reaktionszeit konstant.

grüsse leo9

Autor: Stefan J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie 64 dazu ? g

"damit ist die Reaktionszeit konstant"
Wie meinst du das ?


Gruß
Stefan

Autor: Tom Bayer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Korrigiert mich wenn ich mich irre. Wenn man z.B eine LED mit einer
Frequenz von 1750Hz zum leuchten bringen will muss man sie an und
wieder ausschalten und das ist die Frequenz. Also 1750Hz -> eine
Periode dauert 571us -> halbe Periode an, halbe aus -> 571us/2=285us.
Nun dauert bei 4MHz eine Periode 250ns -> 285us/250ns=ca.1142 Geht man
von einer bestimmten Zeit aus die gebraucht wird um die Aktion
auszuführen, die man aber an den Takten genau sieht nimm einfach als
eingestellten Wert 2^16-x=1145 und danach in der Interruptroutine
zuerst Zähler wieder mit Wert initialisieren und danach Ausgang
komplementieren. Fertig

Autor: Stefan J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Bascom Code sieht so aus (Als einfaches Beispiel) :


On Timer1 Ontimer1
Config Timer1 = Timer , Prescale = 1
Enable Interrupts


'---------------------------------------------------------
Do

If Pinc.5 = 1 Then Enable Timer1

If Pinc.5 = 0 Then Disable Timer1


Loop
'---------------------------------------------------------



Ontimer1:
  Timer1 = 64393
  Ftoggle0 = Not Ftoggle0
  Portc.4 = Ftoggle0


Return

Autor: leo9 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ stefan:
mit 64... meinte ich deinen Preset-Wert.
Die konstante Reaktion ergibt sich dadurch dass der Timer nach dem Int
vorerst weiterläuft, du setzt ihn auf einen fixen Wert und verlierst
damit die bereits vergangenen Takte. Wenn du aber 64393 dazuaddierst
ist es egal ob die Routine bei Zählerstand 50, 150 oder sonstwas
aufgerufen wird.

ich hoff das ist jetz verständlich.

grüsse leo9

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.