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
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
Oh, und die Var wechsel hieß vorher zaehler, daran liegt es also nicht, war in der Version nur noch nicht geändert! ;o)
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 }
hm, Fehler drin: OCR1A=ICR1+(ICR1-capture_bak)>>1; hoffentlich stimmts jetzt :-)
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!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.