www.mikrocontroller.net

Forum: Compiler & IDEs Unterschied zw. ICP und INT0


Autor: Holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
...
  GIMSK = (1 << INT0);                 // Interrupt von INT0 aktivieren
  MCUCR = (1 << ISC01) | (1 << ISC00); // Interrupt0 bei steigender Flanke
  sei();
....
ISR(INT0_vect)
{
i++;
}

bzw für ICP:
...
   TIMSK |= (1<<TICIE1);  // Input Capture Interrupt aktivieren
   TCCR1B |= (1<<ICES1);  // steigende Flanke für ICP Interrupt
   sei();
...
ISR(TIMER1_CAPT_vect)   //Interrupt bei Overflow Timer1
{
   i++;
}

Autor: isr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ganz einfach der INT0 löst einfach nur einen IRQ aus, während die ICP 
auch noch einen Timestamp erzeugt.
Näheres im Datenblatt :-P

Autor: Holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
uint16_t i=0;

void wait (uint16_t zeit) //zeit: wartezeit in ms (0 bis 65536)
{
   uint16_t i;
   for(i=0;i<zeit;i++) _delay_ms(1);
} 

int main (void)
{
   char s[10];

   DDRD &= ~( 1 << PD6 );  // PD6 als Eingang
   TIMSK |= (1<<TICIE1);  // Input Capture Interrupt aktivieren
   TCCR1B |= (1<<ICES1);  // steigende Flanke für ICP Interrupt

   lcd_init(LCD_DISP_ON);
   lcd_clrscr();
   lcd_puts("ICP\n");
   sei();      //Interrupts aktivieren 


while(1)
{ wait(500);
  lcd_clrscr();
  lcd_puts(itoa(i,s,10));  
}   
           
}


ISR(TIMER1_CAPT_vect)
{
   i++;
}

Autor: Rahul Der trollige (rahul)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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.

Autor: Michael U. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das mit dem "anfassen" war nur eine Nebenerscheinung welche ich 
festgestellt habe, war nicht zum testen

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.


Autor: Holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Alfred Q. (higedigdag)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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?

Autor: Alfred Q. (higedigdag)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die eine ist max 5kHz die andere geht bis 300Hz.

Ich denk mal für die 5kHz sollte man den ICP verwenden, oder?

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Alfred Q. (higedigdag)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok danke ich werd das mal versuchen... mir gings nur erstmal um die 
gestaltung der hardware

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.