Forum: Mikrocontroller und Digitale Elektronik Frequenzen mit ATmega messen


von Guest (Gast)


Lesenswert?

Hallo,

ich habe folgendes Problem:
Mit einem ATmega16 bzw. 32 möchte ich folgende Aufgabe realisieren:
- Frequenzmessung (liegt zwischen 50 und 70Hz) und Bildung eines 
Frequenz-Mittelwertes von z.B. der letzten 100 Perioden
- Die Anzahl der Perioden die wärend der Laufzeit eingegangen sind
- Die Laufzeit von der ersten Periode bis nach der letzten Periode (sind 
max. 45sec)

Ich bin mir jetzt nicht ganz sicher, ob ich hierfür einen ATmega16 bzw. 
32 nehmen kann. Dort habe ich ja nur 2x 8bit Timer und 1x 16bit Timer 
zur Verfügung.
Brauche ich für die Frequenzmessung 2 Timer oder nur einen? Welchen 
Timer nehme ich am besten wofür? Den 16bit-Timer für die Laufzeit, oder?

Habe sowas noch nie gemacht und würde mich hier über eine kleine 
Hilfestellung sehr freuen.

Vielen Dank im Vorraus.

von UBoot-Stocki (Gast)


Lesenswert?

Moin,

Mega8 sollte völlig reichen. Den Mega16 kannst du nehmen und den Mega32 
auch.

Bei 4Mhz Tagktfrequenz recht Dir sogar Timer0. Alles Andere ist "Perlen 
vor die Säue geschmissen"

Gruß

andreas

von Guest (Gast)


Lesenswert?

Vielen Dank für die Antwort Stocki.

Du meinst also, dass mir nur ein Timer ausreichen würde? Brauche ich 
denn nicht schon alleine einen Timer für die Frequenzmessung? Ich dachte 
mir, ich starte einen Timer bei steigender Flank am PinX und stoppe ihn 
auch wieder bei steigender Flanke am PinX (sofern das geht, habs noch 
nie gemacht). Dann den Timerstand rauskopieren (sichern) und daraus die 
Zeit berechnen. Gleichzeitig aber dann den Timer wieder neu starten 
lassen, und das Ganze geht von Vorne los.

Einen weiteren Timer bräuchte ich meiner Meinung nach für die Messung 
der Laufzeit, oder wie würdest du das dann machen?

Du hast Recht, ein ATmega8 würde wohl auch schon reichen.

von Nixweiss (Gast)


Lesenswert?

welchen compiler benutzt du ??

von Johannes M. (johnny-m)


Lesenswert?

Guest wrote:
> Mit einem ATmega16 bzw. 32 möchte ich folgende Aufgabe realisieren:
> - Frequenzmessung (liegt zwischen 50 und 70Hz) und Bildung eines
> Frequenz-Mittelwertes von z.B. der letzten 100 Perioden
Mach das mit Input Capture.

> - Die Anzahl der Perioden die wärend der Laufzeit eingegangen sind
> - Die Laufzeit von der ersten Periode bis nach der letzten Periode (sind
> max. 45sec)
Was verstehst Du unter der "Laufzeit"?

> Ich bin mir jetzt nicht ganz sicher, ob ich hierfür einen ATmega16 bzw.
> 32 nehmen kann. Dort habe ich ja nur 2x 8bit Timer und 1x 16bit Timer
> zur Verfügung.
> Brauche ich für die Frequenzmessung 2 Timer oder nur einen?
Für die Frequenzmessung mit Input Capture genügt ein Timer.

von Guest (Gast)


Lesenswert?

Unter meiner Laufzeit verstehe ich die Zeit von der ersten Periode 
meiner Frequenz bis zur letzten Periode (d.h. meine Frequenz kommt nur 
eine bestimmte Zeit lange, danach und davor nur LOW-Signal). Diese Zeit 
beträgt max. 45sec., soll aber eben genauer bestimmt werden (auf xx,xx 
sec. wenn möglich).

Programmieren will ich das Ganze mit AVRStudio zusammen mit GnuGCC (da 
ich in C programmiere).

Also müsste ich ICES1 (Input Capture Edge Select Timer/Counter 1) auf 
"1" setzen um die steigende Flanke an Pin PD5 (als T1 bezeichnet an 
Atmega8) zu erkennen, ja?
Anschließend die Interrupts sperren und den Stand des Counters aus 
TCNT1H holen, oder?

Versuche mich aufs Tutorial zu beziehen, hoffe meine Ansätze passen so.

Vielen Dank euch schonmal.

von Johannes M. (johnny-m)


Lesenswert?

Guest wrote:
> Unter meiner Laufzeit verstehe ich die Zeit von der ersten Periode
> meiner Frequenz bis zur letzten Periode (d.h. meine Frequenz kommt nur
> eine bestimmte Zeit lange, danach und davor nur LOW-Signal). Diese Zeit
> beträgt max. 45sec., soll aber eben genauer bestimmt werden (auf xx,xx
> sec. wenn möglich).
Ah so.

> Also müsste ich ICES1 (Input Capture Edge Select Timer/Counter 1) auf
> "1" setzen um die steigende Flanke an Pin PD5 (als T1 bezeichnet an
> Atmega8) zu erkennen, ja?
> Anschließend die Interrupts sperren und den Stand des Counters aus
> TCNT1H holen, oder?
Nö. Das ist doch grad der Sinn der Input-Capture, dass nichts aus dem 
TCNT geholt werden muss. Beim Auftreten des Capture-Ereignisses wird der 
Inhalt von TCNT verzögerungsfrei ins ICR übernommen. Und da bleibt der 
stehen, bis das nächste Ereignis eintritt. Der Timer kann währenddessen 
ruhig im Hintergrund weiterlaufen. Und bei den von Dir angegebenen 
Frequenzen hat das Programm dann alle Zeit der Welt, den Wert im ICR zu 
verarbeiten.

Nur dran denken: Wenn zwischen zwei Captures Timer-Überläufe auftreten, 
müssen die bei der Berechnung der Frequenz mit berücksichtigt werden.

> Versuche mich aufs Tutorial zu beziehen, hoffe meine Ansätze passen so.
Tutorial ist ne verdammt gute Idee...

von Johannes M. (johnny-m)


Lesenswert?

BTW:
Gib mal "Frequenzmessung" in die Forensuche ein. Das ist hier schon 
zigmal durchgekaut worden...

von Guest (Gast)


Lesenswert?

Natürlich habe ich die Forensuche bereits benutzt, bevor ich gepostet 
habe. Trotzdem ist für mich manches noch fachchinesisch, wo ich noch 
nicht mithalten kann. Ich habe zwar schon mit AVRs gearbeitet, jedoch 
die Timer/Counter bisher noch nie verwendet.

Das mit dem Überlauf gibt mir noch zu denken... da muss ich nochmal 
dran.

Wie ist das mit dem Rücksetzen des Counters? Kann ich da einfach den 
Stand vom TCNT1 mit Nullen überschreiben?

von Johannes M. (johnny-m)


Lesenswert?

Guest wrote:
> Wie ist das mit dem Rücksetzen des Counters? Kann ich da einfach den
> Stand vom TCNT1 mit Nullen überschreiben?
Klar,
1
TCNT1 = 0;

von Guest (Gast)


Lesenswert?

Okay, danke.

Nochmal zum Überlauf:

Eigentlich kann ich ja hier eine variable nehmen, welche bei jedem 
Überlauf um 1 erhöht wird. Danach diesen Wert mit 255 (höchster Wert des 
Zählers) multiplizieren, und noch den aktuellen Stand des Zählers 
addieren, oder?

Wie berechne ich diesen Wert dann in eine Zeit? Multiplizieren mit dem 
Zeitfaktor, den der µC braucht, um seinen Counter 1x zu erhöhen?

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

Fü Frequenzen um 50-70 Hz bietet sich eher die Periodendauermessung an, 
die Mittelwertbildung geht dann durch Aufsummieren der letzten 100 
Messungen. Das kostet natürlich nach jeder Messung eine 
Fixkomma-Division.

von Guest (Gast)


Lesenswert?

Okay, aber kann mir einer noch sagen, wie ich den Zählerstand 
anschließend in eine Zeit umrechnen kann? Irgendwie dämmerts mir da noch 
nicht so richtig...

von Karl H. (kbuchegg)


Lesenswert?

Du bist schon am richtigen Weg.

Du kennst die Taktfrequenz deines µC.
Davon leitet isch ja, zusammen mit dem Vorteiler ab,
mit welcher Frequenz der Timer erhöht wird.

Der Rest ist dann simple Grundschulmathematik um,
ja nach Messverfahren, einen Zählerstand in eine
Zeit und damit auch in eine Frequenz umzurechnen.

von Guest (Gast)


Lesenswert?

Okay, angenommen mein Controller läuft mit 16MHz Quarztakt. Das 
entspricht einer Zeit von 62,5ns pro Takt, richtig? Ggf. kann ich ja den 
Takt, welchen der Counter verwendet, über den Prescaler noch 
herunterteilen, oder?

Wenn ich es mir recht überlege: Der Counter läuft ja unabhängig von 
meinem Programm, d.h. selbst mit einer Blockade (z.B. Schleife) im 
Programm könnte ich den Counter nicht verlangsamen, stimmts?

Jetzt muss ich nur noch wissen, wieviele Takte der µC braucht, um den 
Counter um 1 zu erhöhen, ja? Habe hierzu im Datenblatt leider gerade 
nichts gefunden. Kann ich davon ausgehen, dass bei jedem Takt der µC den 
Counterstand um 1 erhöht?
Möchte nur, dass sich keine Ungenauigkeitsfehler durch von mir 
verursachte Denkfehler einschleichen.

Vielen Dank euch schonmal, habt mir sehr geholfen :-)

von Johannes M. (johnny-m)


Lesenswert?

Guest wrote:
> Jetzt muss ich nur noch wissen, wieviele Takte der µC braucht, um den
> Counter um 1 zu erhöhen, ja?
Genau das stellst Du doch mit dem Prescaler ein... Ein Prescaler von 
1024 heißt, dass das Zählregister mit jedem 1024. CPU-Takt um eins 
erhöht wird.

von Guest (Gast)


Lesenswert?

Achso ist das... sehe wohl vor lauter Bäume den Wald nicht mehr :-D

Stimmt dann meine Beispielrechnung so?

Wenn aktueller Zählerstand: 200
Erkannte Überläufe des Zählers: 2
Da der Zähler von 0...255 geht: Entspricht einem Zählerstand von 
(2x255)+200
-> 710

- Prescaler ist auf 1024 eingestellt
- Controller-Quarztakt 16MHz
16MHz entsprechen 62,5ns
Da bei jedem 1024 Takt der Zähler um 1 erhöht wird: 62,5ns x 1024 = 64µs 
(braucht der Zähler für eine Erhöhung um den Wert "1")

Jetzt den Zählerstand mit diesen 64µs erhöhen:
710 x 64µs = 45,44ms

Ist das so korrekt?

Wäre nett wenn da mal einer drüber schauen könnte. Danke im Vorraus :-)

von Guest (Gast)


Lesenswert?

[zitat]Jetzt den Zählerstand mit diesen 64µs erhöhen:
710 x 64µs = 45,44ms[/zitat]

"multiplizieren" meine ich natürlich, nicht "erhöhen", sorry.

von Falk (Gast)


Lesenswert?

@ Christoph Kessler (Firma db1uq) (christoph_kessler)

>die Mittelwertbildung geht dann durch Aufsummieren der letzten 100
>Messungen. Das kostet natürlich nach jeder Messung eine
>Fixkomma-Division.

Na dann miss doch 128 Perioden ;-)

MfG
Falk

von Karl H. (kbuchegg)


Lesenswert?

Guest wrote:
> Jetzt den Zählerstand mit diesen 64µs erhöhen:
> 710 x 64µs = 45,44ms

Der Rechengang ist prinzipiell korrekt.
Die Zahlen hab ich jetzt nicht nachgerechnet.

von Guest (Gast)


Lesenswert?

Okay vielen Dank! Habt mir sehr geholfen.

von STK500-Besitzer (Gast)


Lesenswert?

>Da der Zähler von 0...255 geht: Entspricht einem Zählerstand von
>(2x255)+200 -> 710

Deine Überlaufvariable hat aber den Wert 256...
Man könnte natürlich auch gleich einen 16Bit Timer nehmen, an dem gleich 
auch noch die ICP-Einheit dranhängt.
Du willst 50-70Hz messen. Das bedeutet Periodendauern zwischen 14 und 
20ms zu messen. Ein 16Bit-Timer bei einem (CPU-)Takt von 1MHz hat einen 
Zählumfang von 65,536ms ohne dass man einen Prescaler benutzt.

Auf der atmel.com-Seite gibt es AFAIR eine ApplicationNote zur 
Periodendauer-Messung (oder war es die Auswertung des 
Pulspausenverhältnisses?). Zumindest wird da irgendwo das Messprinzip 
beschrieben.

von Guest (Gast)


Lesenswert?

>Deine Überlaufvariable hat aber den Wert 256...
Richtig, mein Fehler, sorry und danke für den Hinweis.

>Du willst 50-70Hz messen. Das bedeutet Periodendauern zwischen 14 und
>20ms zu messen. Ein 16Bit-Timer bei einem (CPU-)Takt von 1MHz hat einen
>Zählumfang von 65,536ms ohne dass man einen Prescaler benutzt.
Das hieße ja dann, ich könnte das mit 1MHz Quarztakt nicht 
bewerkstelligen, mit mehr als 8MHz Quarztakt sollte es aber sicher keine 
Probleme mehr geben.

Das ApplicationNote werde ich nachher mal suchen und anschauen, danke 
für den Hinweis.

von Karl H. (kbuchegg)


Lesenswert?

>> Du willst 50-70Hz messen. Das bedeutet Periodendauern zwischen 14
>> und 20ms zu messen. Ein 16Bit-Timer bei einem (CPU-)Takt von 1MHz
>> hat einen Zählumfang von 65,536ms ohne dass man einen Prescaler
>> benutzt.

> Das hieße ja dann, ich könnte das mit 1MHz Quarztakt nicht
> bewerkstelligen

Du kannst dann was nicht mit 1Mhz Quarztakt bewerkstelligen?

~60Hz messen kannst du mehr als ausreichend genau mit 1Mhz.
Wenn der Timer ohne Prescaler tickt, läuft er von einer
steigenden Flanke des Signals bis zur nächsten auf einen
Zählerwert von ca. 20000 (bei 50 Hz) bis  ~14000 (bei 70Hz)
hoch.

von Günther (Gast)


Lesenswert?

Hallo an alle,

Steh vor einem ähnlichen Problem: Habe einen ATMEGA8 und möchte damit 
gernen eine Frequenz messen. Dafür steht mir aber nicht der ICP Eingang 
zur Verfügung sondern PC3.

Von der Grundidee ist mir das jetzt schon klar geworden. Bei positiver 
Fnake Timer starten, warten bis negativ und zeit abnehmen.
Oder Schwungungen auf bestimmte Zeit, bzw. Zeit für bestimmte 
Schwingungen.

Um die Zeit auf einen Zyklus genau zu messen würde ich gerne auf die 
"input capture funktion" zurückgreifen.

Ich hab mir auch schon das Datenblatt durchgelsen und -glaube- das mit 
Prscalern und Frequenzen verstanden zu haben, aber spätestens bei den 
verscheidenen Registern hab ich den Überblick veroren.

Da zwar gewisse Grundkenntisse in C habe, aber beim 
Mikrocontrollerprogrammiern noch wenig Erfahrung habe, hoffe ich auch 
eure Hilfe.

Vielleicht kann mir jemand mit einem Codebeispiel weiterhelfen.

Danke,

Günther

von Karl H. (kbuchegg)


Lesenswert?

> Dafür steht mir aber nicht der ICP Eingang
> zur Verfügung sondern PC3.

> würde ich gerne auf die
> "input capture funktion" zurückgreifen.

Das beißt sich. Entweder du hast den ICP Eingang frei (dann
kannst du über Input Capture messen) oder du hast ihn nicht frei
(dann gehts logischerweise nicht über Input Capture).

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.