PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frequenz am Mega168 auswerten - welcher Eingang?



squelver
12.11.2007, 12:04
Hallo O:)

Ich habe eine variierende momentan noch unbekannte Frequenz im Hz- bis Khz-Bereich, welche ich mit einem Controller Mega 168 auswerten möchte.

Kann ich dieses über einen digitalen Port machen oder ist ein ADC Eingang zwingend?

Ich möchte lediglich den Bereich zwischen zwei Grenzen verwenden und damit einen Motor nachführen können :-k

Hubert.G
12.11.2007, 13:25
Du könntest es über den T0 Eingang machen, die Eingangsimpulse über eine bestimmte Zeit zählen und schon weisst du die Frequenz.

squelver
12.11.2007, 13:31
Du könntest es über den T0 Eingang machen, die Eingangsimpulse über eine bestimmte Zeit zählen und schon weisst du die Frequenz.

Hi :)

Das wäre n Ansatz, dankeschön O:)
Benötige ich dazu noch ein Schaltung davor oder könnte ich das Signal direkt anschliessen?

Andreas

Hubert.G
12.11.2007, 13:57
Wenn das Signal nicht höher als VCC ist brauchst du nichts, ein Serienwiderstand als Schutz ist aber ratsam.

squelver
12.11.2007, 13:59
Wenn das Signal nicht höher als VCC ist brauchst du nichts, ein Serienwiderstand als Schutz ist aber ratsam.

Ok, den werde ich sicherheitshalber nehmen :)
Um weiteres fragen zu können, werd ich micht erstmal mit dem T0-Eingang beschäftigen \:D/

robocat
12.11.2007, 14:52
bin mir jetzt auch nicht ganz sicher, aber müsste man nicht vorkehrungen gegen negative halbwellen treffen? wenn sich alles zwischen 0V und Ub abspielt, ist das nicht relevant.

gruesse

ogni42
12.11.2007, 14:58
Int0 und Int1 sind ebenfalls sehr einfach dafür benutzbar

squelver
12.11.2007, 16:14
Werd ich mir dann mal anschauen :)

Wie kann ich dieses Zählen den verstehen?
Wird in einer gewissen Zeit gezählt?

Hubert.G
12.11.2007, 20:15
Du startest einen Timer für z.B. 100msec und zählst die Impulse am T0 .

squelver
12.11.2007, 20:34
Du startest einen Timer für z.B. 100msec und zählst die Impulse am T0 .

Ok, das kann ich verstehen. Dann müsste ich dem gezählten Wert ein Anfang und ein Ende geben und vergleichen oder?

Hubert.G
12.11.2007, 20:46
Du startest den Timer, startest den Zähler, wenn der Timer abgelaufen ist dann den Zähler stoppen und auslesen. Sollte der Zähler überlaufen dann ein Hilfsregister hochzählen lassen.

squelver
12.11.2007, 20:57
Du startest den Timer, startest den Zähler, wenn der Timer abgelaufen ist dann den Zähler stoppen und auslesen. Sollte der Zähler überlaufen dann ein Hilfsregister hochzählen lassen.

Verstanden O:)
Dankeschöön ;)

Besserwessi
12.11.2007, 21:07
Die genaueste Zeit/Frequenzmessung geht mit dem ICP pin. Damit kann man die Zeiten auf einen Zyklus genau messen.
Bei mir geht das bei 20 MHz Takt bis etwa 300 kHz gut, hängt aber vom Programm ab. Der ICP Eingang hat auch noch gleich die Möglichkeiten sehr hochfrequente Störungen rauszufiltern. Je nach Signalqualität/Amplitude kann auch der analoge Komperator benutzt werden und das ICP event auslösen.

squelver
13.11.2007, 17:10
Ich kann jetzt garnicht mehr mitreden, klingt kompliziert :-&

Besserwessi
13.11.2007, 18:42
Ich wollte keinen Einschüchtern, so kompliziert ist das gar nicht.
Ob man einen Digitalen Eingang oder einen AD bzw. analogen Komperator nehmen muss hängt von der Spannung des Signals ab. Bei großer Amplitude geht der Digitaleingang, sonst muß ein Verstärker oder ähnliches davor oder man nimmt den analogen Komperator-eingang oder notfalls auch einen AD (aber da wird es dann etwas aufwendiger).

Wenn ein Motor nachgeregelt werden soll, hilft es wenn die Frequenz sehr schnell gemessen werden kann. Das geht am besten indem man die Länge einer Periode stopt. Die Frequenz ist dann gerade der Kehrwert der Zeit.
Um Zeiten zu Stoppen ist gerade der ICP Pin da. Wenn die gewünschte Flanke am ICP Pin auftriff, wird der Timerstand in 2 spezielle Register kopiert. Die Periodendauer ergibt sich dann indem man die Zeiten von 2 aufeinanderfolgenden ICP Ereignissen abzieht. Um es Anfangs einfach zu haben, kann man den Timer langsam genug laufen lassen, das man sich nicht um Überläufe des Timer kümmern muss. Aber auch das mit den Überläufen ist nicht besonders kompiziert.

oberallgeier
07.12.2007, 11:04
.. so kompliziert ist das gar nicht. ...Anfangs klang es für mich auch kompliziert. Aber jetzt - ich hab mir grad das ATMEL-doc vom tiny2313 angesehen. Weil ich den Pin GARNICHT kannte :(. Jetzt hört sich das ja sehr gut an. Danke für den Hinweis. Da ich erst ein drei-Monats-Wickelkind im Bezug auf die µC bin, hab ich jetzt gleich ein paar Fragen dazu.

Sehe ich das richtig, dass ich jetzt ziemlich einfach ne Motordrehzahl messen kann? Einfach von einem Aufnehmer das Signal (ok, der Pegel muss stimmen) auf den Pin legen, ICP einschalten, Input Capture Flag löschen, DIESEN Interrupt erlauben (aber das ist doch ein Interrupt, den andere auch benutzen? Kann ich den schalten ähnlich sei/cli?), ersten Interrupt abwarten, ist das (beim tiny2313) der

.org 0x0003 reti ; TIM1_CAPT ;Timer1 Capture Handler ??

oder welcher Interrupt ist das? Timer starten, zweiten Interrupt abwarten (kann ich den auf die gleiche Flanke setzen?), Timer auslesen - und ich kenn die Periodendauer des Drehzahl-Sensors. Ohne glitch und wenn und aber. Machen das alle so? Oder denke ich da falsch?

Und warum schreiben die im doc 2543, S 94 mitte: "An Input Capture can be triggered by software by controlling the port of the ICP1 pin." - MUSS ich das alles per Software machen? Dann hätte die Interrupt-Geschichte doch keinen solchen Sinn?

Fragen:
a) Wird (Kann) vom ICP ein Interrupt ausgelöst (werden)?
b) Welcher Interrupt wird vom ICP ausgelöst?
c) Welche Interruptquellen benutzen den gleichen Interrupt?
d) Ist Flankenerkennung möglich beim ICP?
e) Kann der "ICP Interrupt" explizit erlaubt/verboten werden? Unabhängig von anderen Interrupts?
f) Was bedeutet der Software-Hinweis im doc?
g) Was gibts da noch zu bedenken? Ich hab ja sowieso ein gewissens Problem, weil ich bisher in Assembler dachte - und nun in C die allergrösste Mühe besonders mit Interrupts habe :(.


... Um es Anfangs einfach zu haben, kann man den Timer langsam genug laufen lassen, das man sich nicht um Überläufe des Timer kümmern muss. ....Na ja, ich weiss nicht, wenn ich die Drehzahl zwischen 800 Hz und 1 Hz messen will - dann ist das Spektrum doch etwas weit . . . . oder?

Sorry für die vielen Fragen. Ich könnt ja auch das doc durchlesen :)

Besserwessi
07.12.2007, 22:18
Den ICP per software auszulösen ist nicht nötig und macht auch nicht allzuviel Sinn.

Antworten:
a) Wenn die ICP Funktion aktiviert wird, kann auch ein Interrupt ausgelöst werden.
b) Das ist der Input Capture interrupt.
c) der Interrrupt wird nicht anders benutzt
d) Die Flanke, die das ICP event und damit den Interrupt auslöst kann eingestellt werden (Rgister TCCR1C beim Tiny2313)
e) ja, im Register TIMSK, oder durch Abstellen von ICP in TCCR1C
f) ?
g) Wenn die Zeiten länger werden, sodass der Zähler überläuft, muss man das getrennt behandeln, aber darum sollte man sich später kümmern.

Die Zeitmessung geht am genauesten, wenn man für start und stop die ICP funktion nutzt. Im ICP Interrrupt, von der zuletzt gemessenen Zeit die vorherige abziehen um die Periodendauer zu bekommen. Die Gemessene Zeit merken für das Nächste mal. Man bekommt dan bei jeder passenden Flanke einen neuen Wert für die Periodendauer.
Wenn schon unbedingt der überlauf behandelt werden soll, dann nimmt man dazu den overflow interrrupt, und zählt darin eine integervariable hoch. Diese Integervariable bildet dann die oberen 2 Bytes der Zeit. So weit eigentlich noch ganz einfach, etwas komplizierter wird es dann den Fall zu berücksichtigen, das der overflow und ICP interrrupt fast gleichzeitig auftreten: Es dann möglich, das der ICP Interrrupts schon ausgeführt wird, bevor der overflow Interrupt dran war. Das Merkt man daran, das der ICP Wert sehr klein ( < 1000) ist, und das Signalbit für den overflow Interrrupt an ist. In diesen Fall ist dann der Zähler aus den overflow interrrupt noch um eins zu klein.

So kompliziert sind interrrupts in C eigentlich nicht, man muss nur die richtige Form einmal raus haben (ISR(...) ). Das einzige worauf man achten muss, ist dem Compiler zu sagen, welche variablen von der ISR routine verändert werden, und diese als "volatile" kennzeichnen. Lokale Variablen die zwischen den ISR aufrufen erhalten bleiben sollen sind mit dem Zusatz "static" zu deklarieren.

Das einzige wo ich selber noch ein Problem hätte ist es in C, die 2 unsigned integer Werte (ICP Zeit und Overflow Zäher) einfach zu einer unsigned longint Zahl zusammenzufassen. Wie das auf die langsame Art (mit <<16) geht weiss ich.

wkrug
07.12.2007, 22:50
Wie das auf die langsame Art (mit <<16) geht weiss ich.
Und wenn Du gleich eine Assembler Routine schreibst die 2 int Werte aufnimmt und einen long Wert zurückgibt ?

Bei Codevision wären das genau 4 MOV Befehle.


Es dann möglich, das der ICP Interrrupts schon ausgeführt wird, bevor der overflow Interrupt dran war.
Das dürfte aber nichts ausmachen, wenn man für die Zeitberechnung das ICR Register, anstatt des TCNT ausliest und verarbeitet.
Darin befindet sich ja der Zählerstand als der Input Capture Interrupt auftrat. Folglich sollten auch die Überlaufzähler noch nicht hochgezählt werden.

Auch wenn beide Interrupts 100% zeitgleich eintreffen wird der ICP Interrupt zuerst ausgeführt, weil er höher priorisiert ist.

Auch wenn jetzt einTimer Overflow Interrupt auftritt, ist es sogar besser, wenn er nicht ausgeführt werden kann, weil dadurch die Überlaufzähler ja auch auf dem alten Stand bleiben.
Wenn im Input Capture Interrupt alle Zeiten ausgewertet sind, kann ja der Overflow Interrupt immer noch korrekt ausgeführt werden.

Die Zeit, die vergeht bis das ICR ausgelesen wird ist ebenfalls unkritisch, weil sie ja bei jedem Zyklus gleich lang dauert ( Es sei denn man hat das im Programm extra anders gemacht ) .

Ich finde mit dem ICP lassen sich viele Probleme lösen, die man mit normalen Interrupts und Timer abfragen immer hätte ( Überholeffekte usw. ) .

Besserwessi
08.12.2007, 00:05
Das Problem entstehtm wenn das ICP event ganz kurz nach dem Overflow auftritt, der overflow Interrrupt aber noch nicht starten kann weil gerade ein längerer Befehl (z.B. RET, BREQ, ..) ausgeführt wird oder weil gerade ein CLI...SEI Block ausgeführt wird. In diesem Fall wird erst der ICP-Interrrupt aufgerufen (wegen höherer Priorität) obwohl der overflow Interrupt eigentlich früher dran wäre. Wenn man diesen Sonderfall nicht berücksichtigt, kriegt man ganz selten mal eine falsche Zeit.

oberallgeier
08.12.2007, 00:46
Hei, danke schön! Ich habe zwar mächtige Probleme die Zeilen zu lesen (nach der Sauna verschwimmt mir immer alles) aber morgen ist auch noch ein Tag (mit schlechtem Wetter :) )