Forum: Mikrocontroller und Digitale Elektronik genaue Frequenz mit AVR


von Erwin (Gast)


Angehängte Dateien:

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

von inoffizieller WM-Rahul (Gast)


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

von Erwin (Gast)


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

von Erwin (Gast)


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

von Hubert.G (Gast)


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,

von Erwin (Gast)


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

von inoffizieller WM-Rahul (Gast)


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

von Johannes (Gast)


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

von johnny.m (Gast)


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?

von Johannes (Gast)


Lesenswert?

Ähm, ich meinte natürlich:

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

Verflixtes Copy-n-paste :-)

von Johannes (Gast)


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

von johnny.m (Gast)


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.

von johnny.m (Gast)


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...;-)

von Johannes (Gast)


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

von johnny.m (Gast)


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

von Peter D. (peda)


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

von Erwin (Gast)


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

von johnny.m (Gast)


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?

von Erwin (Gast)


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

von Erwin (Gast)


Lesenswert?

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

Erwin

von Johannes (Gast)


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

von Erwin (Gast)


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

von Peter D. (peda)


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

von Johannes (Gast)


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

von johnny.m (Gast)


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.

von Johannes (Gast)


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

von Erwin (Gast)


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

von Oliver (Gast)


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

von Erwin (Gast)


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

von inoffizieller WM-Rahul (Gast)


Lesenswert?

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

von Johannes (Gast)


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

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
Noch kein Account? Hier anmelden.