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.
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
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.
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.
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.
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...
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?
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?
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.
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...
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.
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 :-)
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.
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 :-)
@ 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
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.
>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.
>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.
>> 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.
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
> 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).