was ist eigentlich der entscheidende Unterschied zwischen dem ICP und
z.b. dem INT0 eines ATmega16/32.
Ich kann ja beide so einstellen, dass sie auf eine negative bzw. eine
positive Flanke reagieren und beide sollten mir einen Interrupt
auslösen.
ist meine Init richtig?
Int0:
1
...
2
GIMSK=(1<<INT0);// Interrupt von INT0 aktivieren
3
MCUCR=(1<<ISC01)|(1<<ISC00);// Interrupt0 bei steigender Flanke
ok, danke schon mal, aber ist die Init zum ICP denn richtig (Int0
funktioniert wunderbar, i wird hochgezählt)
beim ICP passiert eher nicht das erwartete
es ist eher wie ein berührungssensor, wenn ich die leitung von PD6
anfasse zählt er lustig munter hoch, lege ich aber Referenzspannung
(also 1 Signal) an, passiert meist gar nichts, wobei er gerade da
hochzählen sollte (so wie der Int0 es ja auch macht)
mal der ganze code:
1
uint16_ti=0;
2
3
voidwait(uint16_tzeit)//zeit: wartezeit in ms (0 bis 65536)
>lege ich aber Referenzspannung (also 1 Signal) an, passiert meist gar>nichts, wobei er gerade da hochzählen sollte (so wie der Int0 es ja auch>macht)
ICP reagiert auf Flanken (die kann man einstellen, und so wie ich dein
Programm verstehe sollte es auch funktionieren).
Du scheinst aber ein Verständinsproblem zu haben:
Du willst scheinbar die Dauer eines konstanten Signals messen. Das geht
nicht mit dem ICP, wenn man die Flankenrichtung nicht während des
Ereignisses ändert.
Mit ICP kann man hervorragend Periodendauern messen: Die
Detektions-Flanke auf fallend oder steigend stellen und die Differenz
zwischen zwei Zeitmarken, die man aus dem ICP-Register auslesen kann
(die "ältere" muß man in einer 16-Bit-Variablen zwischenspeichern...).
Dann hat man die Periodendauer eines Signals.
Um nur den Puls einer Periode zu messen (z.B. PWM-Auswertung durch den
Controller), muß man die Flankenrichtung nach der ersten Detektion
umschalten , den Zeitstempel sicher und bei der nächsten Flanke beides
wieder machen, und die Differenz bilden. Ein gutes Beispiel dafür ist
die Auswertung von Modellbauservo-Signalen, die einen Puls zwischen ca.
1ms und 2ms haben. Diese Pulsdauer ist proportional zur Servoposition.
Ein sinnvoller Einsatz für einen externen Interrupt fällt mir gerade
nicht ein, ausser dass darüber mehrere Controller darüber eine
Kommunikation aufbauen könnten...
Kann aber auch sein, dass ich daneben liege.
Hallo,
ich weiß zwar jetzt nicht, was bei Dir Referenzspannung ist, aber auch
INT0 hat da kein Zählen zu bewirken, wenn er auf steigende Flanke
programmiert ist. H-Pegl ist nur einmal eine stegende Flanke, dann, wenn
man ihn anlegt.
Anfassen ist auch mit SIcherheit keine sinnvolle Fuinktionsprobe dafür,
die Eingänge des AVR sind hochohmig genug, um jede Störung und z.B. 50Hz
Netzbrummen vom Finger einzufangen...
Selbst ein Taster ist ungeeignet, wenn die Software nicht entprellt,
weil der auch bei einem Tastendruck etlich Impulse produziert, bis er
geschlossen oder geöffnet bleibt.
Gruß aus Berlin
Michael
Ich will nicht die Dauer von "Gleichspannung" messen, ich hab nur zum
testen ( da ich später Frequenzen messen will) probiert ob i hochgezählt
wird, wenn ich Vcc anlege und wieder entferne und wieder anlege und...
Halt genau was du gesagt hast --> eine Flanke erzeugen
Bei INT0 klappt das wunderbar, nur halt bei ICP nicht so.
Ich werd mal probieren ein richtiges Signal anzulegen, evtl. klappts ja
dann.
Komisch ist halt nur, dass es bei INT0 klappt, also dort die "Flanke"
erkannt wird.
Abgesehen davon, dass die Verwendung des Capture Interrupt nicht gerade
seinem Sinn entspricht, wundert es mich, dass es mit dem INT0 angeblich
funktioniert, mit dem Capture aber nicht. Ich hätte erwartet, dass
keiner von beiden wirklich sinnvolle Werte liefert, da die Zählvariable
i nicht volatile deklariert ist. Ansonsten sollte auch der
zweckentfremdete Capture-Interrupt seinen Dienst tun...
Ok, mal andere Sache, wenn ich dann die Frequenzmessung machen will und
mir das erste ICR1 (A) zwischenspeichere und dann beim nächsten
interrupt auch das zweite (B), wie rechne ich dann die zeit zwischen den
beiden interrupts aus
rechne ich einfach B-A und hab dann schon die Zeit?
oder lass ich nen timer nebenbei mitlaufen und stoppe qusi die zeit mit?
Holger wrote:
> Ok, mal andere Sache, wenn ich dann die Frequenzmessung machen will und> mir das erste ICR1 (A) zwischenspeichere und dann beim nächsten> interrupt auch das zweite (B), wie rechne ich dann die zeit zwischen den> beiden interrupts aus> rechne ich einfach B-A und hab dann schon die Zeit?
Im Prinzip ja, Du musst nur eventuell in der Zwischenzeit aufgetretene
Timer-Überläufe mitzählen und dazurechnen.
> oder lass ich nen timer nebenbei mitlaufen und stoppe qusi die zeit mit?
Siehe oben. Wichtig ist nur, dass der Timer auch laufen muss, sonst
gibts bei jedem Capture das selbe Ergebnis.
Holger wrote:
> rechne ich einfach B-A und hab dann schon die Zeit?
Direkt nicht.
Du hast erst mal die Anzahl der Timer Ticks, die der Timer
vom Auftreten einer Flanke bis zum Auftreten der nächsten
Flanke geschafft hat.
Aber: Du weist ja wie schnell der Timer zählt (*)
Wenn er zb. in 1 Sekunde 1000 Ticks macht, dann braucht er
logischerweise für 1 Tick 1 Millisekunde. Und wenn du jetzt
eine Differnz von 534 hast, dann hat er dafür 534 Millisekunden
oder 0.534 Sekunden gebraucht.
(*) Das weist du, weil du ja den Systemtakt kennst und auch
welchen Vorteiler du eingestellt hast.
Ok, das heisst ja dann , wenn ich zb den 16bit Timer nehm mit extern
16Mhz und nem Prescaler von z.B 256, dann hat mein Timer ne max
Auflösung von 16µs, also kann ich auch nur max 62,5kHz messen
heist, wenn ich den Prescaler verkleinere, kann ich bei Prescaler 1 max
16Mhz messen da der Timer mit 62,5ns läuft
Wie sieht das nun aber bei der minimalen Frequenz aus, da zählt der sich
ja bei einer sehr niedrigen Frequenz dumm und dusselig mit den
Überläufen.
seh ich das dann richtig, dass ich minimal 65536*62,5µs=4,095ms-->244Hz
messen kann (die 65536 kommt jetzt wegen z.b einer 16 bit integer
variablen)
Mit nem Prescaler von 1024 kriegste bei 16 MHz einen Überlauf alle 4,19
s mit einer Zählauflösung von 64 µs... Und wenn Du dann noch ne
16-Bit-Variable für das Zählen der Überläufe spendierst, kannste drei
Tage lang auf die nächste Flanke warten!
Holger wrote:
> Wie sieht das nun aber bei der minimalen Frequenz aus, da zählt der sich> ja bei einer sehr niedrigen Frequenz dumm und dusselig mit den> Überläufen.
Und?
Wenn ein µC etwas gut kann, dann ist das sich dumm und dusselig
zu zählen.
Ausserdem: Dem µC ist doch ansonsten sowieso fad.
Bei einem Überlauf alle ~4 ms kann man noch nicht von
dumm und dusselig reden. Siehs mal so: 65500 Takte
gibts nichts zu tun und dann muss in 3 oder 4 Takten mal
was gearbeitet werden. Das wäre sogar einem Beamten zu fad :-)
> seh ich das dann richtig, dass ich minimal 65536*62,5µs=4,095ms-->244Hz> messen kann (die 65536 kommt jetzt wegen z.b einer 16 bit integer> variablen)
* Du hast ja auch noch den Vorteiler
* Wie macht das dann eine Uhr: Die misst auch nur Sekunden und
trotzdem kannst du mit einer Stoppuhr stundenlang, tagelang,
wochenlang stoppen.
Wenn du wirklich hohe Frequenzen messen willst, (Oben stand was von
16MHz...), dann leg die Frequenz nicht an den ICP oder INT pin, sondern
als Externes Taktsignal an den Zählereingang.
Im Einfachsten Fall: Zähler einschalten, exakt eine Sekunde warten,
Zähler wieder ausschalten, Zählerstand == Frequenz.
/Ernst
Hallo ich hätte dazu noch ein Frage.
Wie sieht es aus wenn ich mit dem µC zwei Frequenzen gleichzeitig messen
will? Ich glaube es gibt keinen AVR mit zwei ICP's, oder?
Oder kann man in so einem Fall auch einen INT-Eingang verwenden?
>Oder kann man in so einem Fall auch einen INT-Eingang verwenden?
Das ist verboten...
Aus dem Thread sollte hervorgegangen sein, wie man kleine und große
Frequenzen misst.
Die Messmethode hängt halt von der Frequenz ab...
Wie groß sind deine Frequenzen?
Du solltest einen Timer so programmieren, dass er in regelmäßigen
Abständen einen Überlauf produziert und guckst dann in der Timer-ISR
nach, ob sich der Zustand des jeweiligen Eingangspin verändert hast.
In der ISR muss dann noch jeder Timer-Interrupt mitgezählt werden, um
auf die vergangene Zeit zurück schliessen zu können.