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
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?
@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...
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
}
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?
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.
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!