www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik genaue Frequenz mit AVR


Autor: Erwin (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
Ich habe ein Problem, exakt 2 Khz mit dem Timer 0 zu erzeugen.
Das Programm erzeugt mir 1,6 Khz schöne symmetrische Rechtecke.
(Mit Oszi und Zählfrequenzmesser festgestellt).

Aber warum?

Ratlos
Erwin

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du benutzt den Überlauf-Interrupt mit Nachladewert, um die Zeitbasis zu
erzeugen.
Bist du dir beim NachladeWert=6 sicher, dass BASCOM das in der Zeit
schafft?
Ich würde den Timer im CTC-Mode laufen lassen. Dann braucht man sich um
nichts mehr zu kümmern. Sogar der dazugehörende Ausgang wird ganz ohne
extra Programm-Code umgeschaltet.
Das erfodert allerdings einen Blick ins Datenblatt und dem verstehen
der dort aufgeführten Informationen...

Autor: Erwin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Rahul

Eben, das ist es. ...dem Verstehen der Informationen im Datenblatt.
(Englisch).

Wenn ich wüßte, wie man den Timer in den CTC-Modus bekommt, würde
ich es mal probieren.
Ich kenne nur die Modi Timer oder Counter. :-((

Immer noch ratlos
Erwin

Autor: Erwin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt habe ich mal mit größeren Prescaler-Werten getestet; da stimmen
die Frequenzen, die ich berechnet habe. Scheinbar ist die Zeit zu
gering, um die Schleife vernünftig auszuführen, wenn der Prescaler
auf 1 steht.

In dem CTC-Modus könnte ich doch wahrscheinlich doch auch keine 2 KHz
aus 4 Mhz erzeugen, bei nur 256 Schritten, die Timer 0 kann?!

Ich baue gleich einen 4060 und einen Schwung Teiler dahinter. GRMPF

Erwin

Autor: Hubert.G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum nimmst du nicht den Prescaler 8, dann ersparst du dir das teilen
danach, obwohl 48 Takte sind auch ziemlich knapp für Interrupt und
Timer laden.
Timer 0 kann übrigends kein CTC, das kann nur Timer 1 und der ist
16bit. Da müsstest du dann 2000 als Wert eintragen, das sollte dann
schon,

Autor: Erwin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Hubert
Ich kann den Timer1 nicht dafür verwenden, weil das Ganze ein
Frequenzzähler werden soll und der Timer1 als Impulszähler agieren
soll. Der Timer0 sollte mir eigentlich die Meßzeit zur Verfügung
stellen. Wenn der 1ms Meßzeit herstellen soll, muß er ja mit 1000Hz
"schwingen".
...wenn es Atmel´s mit 2 großen Timern gäbe....?! Tja dann...

Ich würde mich trotzdem über ein Stückchen Assembler freuen, was
mir mal den CTC-Modus veranschaulicht.

Gruß Erwin

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Assembler?
Guck doch mal bei www.hanneslux.de vorbei.
In den Datenblättern neuerer AVR sind meist auch Codebeispiele
vorhanden.
Sehe ich es richtig, dass du den AT90S2313 verwendest?
Der kann CTC beim Timer0 noch nicht...
Du kannst aber auch "irgendeine" MEsszeit wählen und den Controller
dann etwas rechnen lassen - das machen die gerne...

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich schätze, das grundsätzliche Problem ist, dass die Interrupt-Routine
nie in Nullzeit übernehmen kann. Sprich: ab dem Zeitpunkt, wo der
Interrupt kommt, bis zum Neuladen hat der Timer immer schon ein Stück
über die 0 hinaus weitergezählt, was in der Zeitrechnung berücksichtig
werden muss - oder zu einer Verlängerung der Interrupt-Periode führt.

Dazu kommt, dass ein AVR-Timer nach dem Neuladen im laufenden Betrieb
stets einen Takt "aussetzt", bevor er weiterzählt.

Ein probates Verfahren für einen Nicht-CTC-Timer mit Prescaler 1 ist
daher, in der Interrupt-Routine
"Timer0 = Timer0+(startwert+1)"
statt
"Timer0 = (startwert)"
zu schreiben.

Ansonsten, wenn der Timer0 wirklich nur den Ausgangspin toggeln soll
und es auf möglichst hohe Genauigkeit ankommt, würde ich die
Umlauf-Geschichte mit in die Interrupt-Routine zu integrieren und
schreiben:

"Ontimer0:
Timer0 = 6+1
Decr Umlauf
If Umlauf <=0 Then
 Umlauf = 8
 If Umlauf >=4 Then
  Portd.1 = 1
 Else
  Portd.1 = 0
 End If
End If
Return"

Vorausgesetzt, es wird kein höher priorisierter Interrupt benutzt
(INT0/1 oder Timer1-Interrupts), jittert das Ausgangssignal dann nur
noch um maximal 3 Taktzyklen.

HIH
Johannes

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ...wenn es Atmel´s mit 2 großen Timern gäbe....?!

Gibt es doch... ATMega64 z.B. hat zwei 8- und zwei 16-Bit-Timer... Oder
ist Dir das dann schon zu viel des Guten?

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ähm, ich meinte natürlich:

"Ontimer0:
Timer0 = Timer0+6+1
..."

Verflixtes Copy-n-paste :-)

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch eins:

Was spricht gegen eine Tiny2313 statt AT90S2313?

Der hat auch schon CTC auf Timer0. Und ist sowieso zukunftsträchtiger
als der eh auslaufende AT90S2313...

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Einsprung in den Interrupt-Vektor dauert bei AVRs mit bis zu 128KB
Flash 4 Taktzyklen. Hinzu kommt noch die Zeit, die benötigt wird, um
den zum Zeitpunkt des Auftretens des Interrupt-Ereignisses gerade
ausgeführten Befehl zu Ende zu bearbeiten (bis zu 3 Zyklen). Dann
kommen 3 Zyklen für den Sprungbefehl in die ISR (bei µCs mit bis zu 8
KB Flash). Dann werden Register gesichert, was auch noch mal 10-15
Zyklen dauern dürfte (Schätzwert, hängt davon ab, welche Register vom
Compiler gesichert werden). Dann erst kommt die eigentliche
Interrupt-Routine. Am Ende werden die Register wieder geladen (noch mal
10-15 Zyklen) und der Rücksprung dauert noch mal 4 Zyklen. Dann noch
mindestens ein Befehl im Hauptprogramm (mindestens ein Zyklus) und erst
dann kann der nächste Interrupt bearbeitet werden! Macht insgesamt 30-50
Zyklen...

Das nur als Idee, wie lange die Ausführung einer Interrupt-Bearbeitung
wirklich dauert und dass das mit Timern ohne Prescaler und mit
niedrigen Werten für den Überlauf nicht funktionieren kann.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> als der eh auslaufende AT90S2313...

Wohl eher 'ausgelaufen' als 'auslaufend'. Und der Tiny2313 ist so
preisgünstig, da sollte es keine Frage sein, ob man seine verstaubten
Altlasten noch benutzt...;-)

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@johnny.m u.a.

Bitte nichts durcheinanderbringen, denn der Timmer zählt, außer in
bestimmten PWM-Modi, immer hoch und nicht runter. Von daher bedeuten
kleine Startwerte durchaus hohe Taktzahlen bis zum Überlauf.

Die Formel für einen 8bit-Timer lautet:

Takte bis Überlauf = (256 - Startwert) * Prescaler

Nichts für ungut
Johannes

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Johannes:
Hast natürlich recht! Hatte nicht richtig gesehen, dass er die 6 dirket
ins TCNT schreibt. War davon ausgegangen, dass er nur 6 Zyklen warten
will. Dass der Timer raufzählt ist mir schon klar...

Auch in diesem Fall kann aber die Ausführungszeit der ISR eine Rolle
spielen, v.a. dann, wenn innerhalb der ISR mehr Code steht. Ich weiß
halt nicht, was BASCOM noch alles an automatischen Aktionen in ISRs
durchführt, aber so was sollte man schon bedenken. Und auch 250
Taktzyklen sind u.U. schnell erreicht, wenn man nicht aufpasst....

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Erwin,

"Ich kann den Timer1 nicht dafür verwenden, weil das Ganze ein
Frequenzzähler werden soll und der Timer1 als Impulszähler agieren
soll. Der Timer0 sollte mir eigentlich die Meßzeit zur Verfügung
stellen. Wenn der 1ms Meßzeit herstellen soll, muß er ja mit 1000Hz
"schwingen"."


Wenn das ein Frequenzmesser werden soll, dann ists genau umgekehrt
besser, weil Du dann die Capture-Funktion für kleine Frequenzen nutzen
kannst (Periodendauermessung über n Perioden).


Außerdem keine Angst vor Mathematik, d.h. obs nun genau 1ms sind oder
genau was anderes, ist völlig egal.


Peter

Autor: Erwin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
UFF!!
Das Programm ist nur als Test gedacht, später werde ich nur
intern eine Variable setzen und damit den anderen Timer starten
und stoppen. Ich wollte eben "draußen" etwas messen können. (Oszi)
Ihr habt mich jetzt erst mal mit genug Lesestoff versorgt. :-)
Ich habe auch noch Attiny2313. Danke für den Rat mit den "großen"
Avr´s. (2 16 bit Timer). Bascom unterstützt den CTC-Betrieb nicht :-(
Scha....ade!
@Peter
Ich könnte natürlich die Timer tauschen, aber ich möchte möglichst
viele Werte pro Zeiteinheit einlesen, (genauigkeit) und in den kleinen
Timer kann ich nur 256 Bit "reintun".

Danke erst mal
Erwin

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Bascom unterstützt den CTC-Betrieb nicht...

Das kann ich mir so aber nicht vorstellen. Außerdem kannst Du sicher
auch in BASCOM die I/O-Register von Hand konfigurieren, oder etwa
nicht?

Autor: Erwin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann die Register "von Hand" beeinflussen. Das nützt mir aber
wenig, wenn ich den CTC-Modus nicht durchschaue. Ich kann kein Englisch
und Übersetzungen der Datenblätter mit Babelfish liefern nur wirres
Zeug.

Ein Stück kommentierter Assemblercode zu diesem Modus würde mir sehr
helfen, zumal man Assembler auch in Bascom "einbauen" kann.

Gruß Erwin

Autor: Erwin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P.S.
"Config Timer" kann nur Timer als Timer, als Counter oder als PWM
einstellen. Das ist ja mein Ärger.

Erwin

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Erwin

Wenn es um eine Frequenz- bzw. Periodenmessung geht, ist, wie Peter
schon angedeutet hat, die Capture-Funktion in Kombination mit dem
Overflow des Timer1 in der Lage, ganz ohne Interrupt zwischen ein paar
zig und fast 2mal 65536 Taktzyklen auf +/- 1 Taktzyklus genau zu
vermessen. Dazu muss das zu messende Signal nur auf den ICP-Pin des AVR
geschaltet sein. Die Umrechnung auf die exakte Frequenz erfolgt dann
anhand der (immer bekannten) Taktfrequenz und ist normal ziemlich
einfach. Und Assembler brauchst Du dafür ebenso normal nicht
unbedingt.

Bleibt allerdings die Frage, welchen Frequenzbereich Du tatsächlich
erfassen willst...

Johannes

Autor: Erwin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich will bis 100Mhz messen. Dazu muß ich noch einen 10:1 Teiler
davorsetzen. Die Prozessoren, die ich habe sind für 20Mhz Takt gedacht.
Damit müßte ich bis 10 Mhz messen können. Und dann eben den
Wert * 10. Gut, den Capture Interrupt gibt es bei Bascom. Damit habe
ich noch nichts gemacht, aber da finde ich mich schon zurecht.
Ich gucke jetzt erst mal, wie das mit Capture geht.

Vor Jahrzehnten habe ich einen TTL-Zähler mit 26 Schaltkreisen gebaut.
Ich glaube, damals bin ich schneller zum Ziel gekommen als heute mit
Kontrollern. ;-)

Gruß Erwin

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"...und in den kleinen Timer kann ich nur 256 Bit "reintun"."

Nö !

Im Overflowinterrupt kannst Du beliebig weiter zählen.
Genau, wie Du mit nur 10 Ziffern 0..9 auch beliebig hohe Zahlen
darstellen kannst.


Mit 20MHz kannst Du nur etwa bis 8MHz zuverlässig zählen. Aber kein
Problem, nimm einfach nen Vorteiler 1/16.


Peter

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oha, ich fürchte, da musst Du schon mindestens 100:1 vorteilen, um mit
einem 20MHz AVR noch hinterher zu kommen. Selbst wenn der gar nichts
weiter tut, als in "pure Asm" nur auf das ICP-Signal zu warten...

Johannes

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ... wenn ich den CTC-Modus nicht durchschaue...

Der CTC-Modus (Clear Timer on Compare match) macht nix anderes als den
Timer bei Auftreten eines Compare-Ereignisses (also genau dann, wenn
das Timer-Counter-Register TCNTx den im entsprechenden Compare-Register
befindlichen Wert erreicht) zurückzusetzen. Das ganze geschieht
hardwaremäßig, d.h. verzögerungsfrei. Es muss nichts nachgeladen
werden, da der Wert im Compare-Register gleich bleibt, wodurch sich
keine Ungenauigkeiten ergeben. Im CTC-Modus kann man (ähnlich wie bei
einer PWM) auch einen bestimmten I/O-Pin bei einem Compare-Ereignis
hardwaremäßig umschalten lassen und so sehr präzise Taktsignale
erzeugen.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Um johnny's post zu ergänzen, kann der CTC-Modus den betreffenden
Output, sofern er vorher per DDR auf Ausgang gestellt ist, nur toggeln,
d.h. er wird bei Ablauf der Timer-Periode auf den jeweils anderen Pegel
gestellt, was wiederum heißt, dass für ein symmetrisches Ausgangssignal
das Compare-Register (OCR) mit dem halben Periodenwert geladen werden
muss.

Hoffentlich ist das nicht schon wieder zu kompliziert :-)

Johannes

Autor: Erwin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Alle Helfer :-)
Jetzt habe ich 2 Möglichkeiten, das Programm zu realisieren:Peters
Methode (Du hast Recht, das habe ich eben mal probiert, geht gut)

und Johnnies Erklärung, da setze ich mich heute Abend mal dran. (Jetzt
habe ich den Mechanismus verstanden, danke).

So, ich muß mich erst mal neu initialisieren, ich habe in der falschen
Schleife gehangen! :-))

Gruß Erwin

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin Erwin, wenn es etwas extra Hardware sein darf, schau Dir mal den
LTC1799 an, der ist programmierbar von 2kHz bis 20 Mhz, kostet bei
Fr. Reichelt 3,- . 2Rs und ein C und fertig.

mfg
Oliver

Autor: Erwin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Oliver
Moin!
Danke für den Tip, aber ich will das Problem mit AVR lösen, woll´n
mal sehen, wer den stärkeren Willen hat, der MC oder ich. :-))

Gruß Erwin

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der MC wird starrer in seinem Verhalten sein...Der kann einfach nicht
anders!

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erwin,

lass Dich nicht bangemachen. Mag ein MC noch so starr in seinem
Verhalten sein, dem menschlichen Willen ist er doch niemals gewachsen.

Ohne angeben zu wollen - ich spreche da aus Erfahrung.

Viel Erfolg
Johannes

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.