mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit Timer und Input Capture


Autor: Kai H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin!

Habe ein Problem mit dem Input Capture und den Timern beim ATMega8
(Takt 4 Mhz).

Folgendes soll ablaufen:

In einem Highsignal treten in mehr oder weniger regelmäßigen Abständen
Clockimpulse auf, und zwar als Lowpegel für ca 50 us. Diese versuche
ich per Input Capture auf falling edge zeitmäßig zu erfassen und dann
diesen Zeitwert an den Timer 2 zu übergeben, damit dieser seinerseits
einen Output Compare Match erzeugen kann. Der Vorteiler ist so gewählt,
daß es bei der Übergabe von 16 auf 8 bit keine Probleme geben sollte.
Leider funktioniert diese Auswertung überhaupt nicht. Mal geht es für
einige Takte, dann gerät der Timerwert wieder völlig außer Kontrolle.
Habe mittlerweile so ziemlich alles versucht, Auswertung direkt,
Auswertung über zwei Captures und Übergabe der Differenz, Einsatz des
Noisecancel....immer mit unbrauchbaren Ergebnissen.

Mache ich hier irgendwo einen Denkfehler, oder ist der Impuls zu kurz,
als das er vom Mega8 vernünftig erkannt wird?

Vielleicht kann mir jemand einen Denkanstoß geben?

Vielen Dank!

Kai

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zeile 24.

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

am besten postet du mal dein Prg damit man ein Moeglichen Fehler
entdecken kann.

50µs ist extrem lang daran sollte es nicht liegen.


mfg

Dirk

Autor: Kai H. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier nochmal die ISRs und Timer Einstellungen!

Autor: Kai H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, und die Var wechsel hieß vorher zaehler, daran liegt es also nicht,
war in der Version nur noch nicht geändert! ;o)

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ein paar Sachen fallen mir auf:
ein direkter Fehler:
TCNT1L=0;
TCNT1H=0;

das geht nicht, nur andersherum, erst H, dann L schreiben, beliebter
Anfängerfehler.
Beim Lesen hast du es richtig gemacht, erst L, dann H.

Am besten benutzt du direkt den 16bit-Zugriff, damit ersparst du dir
diese Probleme und auch das Addieren mit shift.
statt:
templ=ICR1L;
temph=ICR1H;
capture1=templ+(temph<<8);

schreibst du einfach:
capture1=ICR1;

ebenso
TCNT1=0;

Ansonsten: du ermittelst ein 16bit-Ergebnis, überträgst aber nur den
low-Teil davon an OCR2? Ist das so gewollt?
Was willst du letztendlich mit demProgramm bezwecken?

Autor: Kai H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@crazy horse:

zunächst mal danke für Deine Antwort, das mit dem 16 bit access habe
ich eingebaut, mußte bloß erstmal die header-Datei umändern, weil
standardmäßig bei Codevision das nicht mit drin ist. Dort steht nur
ICR1H und L. Hat aber leider auch nicht zum Erfolg geführt.

Was das Programm am Ende bewirken soll ist Folgendes: Ich benötige
zwischen den Clocksignalen, die einen ext. Interrupt auslösen, mittig
einen weiteren Interrupt. Dafür will ich ständig die Zeit überwachen,
die zwischen den Clocks vergeht, und in der Hälfte der Zeit per compare
match den Interrupt auslösen. Manchmal funktioniert diese Zeitnahme auch
ein paar Takte lang, dann aber sieht man auf dem Oszilloskop wieder
völligen Wirrwarr, wo die Abstände wieder überhaupt nicht mehr stimmen.
Als würde ein Timer überlaufen o.ä., aber das kann ja eigentlich nicht
sein, denn dafür setze ich ja den Timer extra wieder auf Null zurück.
Daß ich einen 16 bit Wert an einen 8 Bit-Timer übergebe ist mir klar,
aber auch das dürfte eigentlich unkritisch sein, denn bei
Clockabständen von etwa 2ms hat der Zähler eh nur bis ca. 130 gezählt,
wenn ich nicht irre.
Ich drehe mich hier seit einer Woche echt im Kreis und komme nicht
weiter...

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, und warum benutzt du dafür nicht den OCR1x des Timer1? Ich würde den
Timer komplett durchlaufen lassen.

interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
static unsigned int capture_bak;  //letzter ICP-Wert
OCR1A=(ICR1-capture_bak)>>1;        //halbe Zeit zwischen letzter und
dieser Messung
capture_bak=ICR1;   //speichern für nächste Differenz
}

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hm, Fehler drin:
OCR1A=ICR1+(ICR1-capture_bak)>>1;

hoffentlich stimmts jetzt :-)

Autor: Kai H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meinst Du mit Timer komplett durchlaufen lassen den Mode Top=0xFFFF?
Müßte man nicht den Timer CTC laufen lassen, also bei OCR1 zurück auf
Null? Denn sonst haut das doch mit der Zeit zwischen den Clocks nicht
hin, oder?

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, meine ich, komplett durchlaufen lassen, kein CTC, kein stoppen, kein
reset.

Bsp:
1.Messung :0x2000
2.Messung :0x3000

Differenz=0x1000, davon die Hälfte 0x800, also setzt du OCR auf 0x3800,
da kommt dann der OCR-Int zwischen diesem und dem nächsten ICP-Ereignis
(falls die Impulse halbwegs konstanten Abstand haben).
Auch ein zwischenzeitlicher Überlauf ist kein Problem:

1.Messung: 0xf000
2.Messung: 0x1000
Differenz (mit unsigned int!) =0x2000

und auch dann klappts:
1.Messung: 0xf000
2.Messung: 0xfff0

Differenz 0xff0, davon die Hälfte 0x7F8, addiert zu 0xfff0=0x07e8 als
neuer OCR-Wert.

Autor: Kai H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vom Ansatz her gebe ich Dir völlig recht, stimmt, so müßte es
theoretisch laufen. Leider meint aber der Mega8, daß er sich deshalb
noch lange nicht so verhalten muß! :-(
Ich habe in der Zeit eines Interrupts vom Timer bereits 5 neue
Clockimpulse.
Habe sogar schon den Controller gewechselt, um auszuschließen, daß der
eine Macke hat!

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.