www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timer1 im Capture Mode am Tiny2313


Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich versuche mit dem Timer1 vom Tiny2313 im Capture-Mode die Puls- und
Pausenlängen eines Signals zu messen, aber leider funktioniert das
nicht ganz so, wie ich mir das vorstelle...

Initialisierung wie folgt:
  TCCR1A = 0;
  TCCR1B=_BV(ICNC1) |  _BV(CS11) ; // Noise Canceler, CLK/8;
  TIMSK = _BV(TOIE0) | _BV(ICIE1) | _BV(TOIE1);
lässt also bei 8MHz Takt den Counter mit 1MHz hochzählen.

ISR für Timer0 Overflow macht was anderes, funktioniert.
ISR für Timer1 Overflow zählt eine 16bit variable hoch, zusammen mit
dem Timer hab ich dann einen 32Bit timestamp, funktioniert auch.

ISR für Timer1 Capture funktioniert so:
ISR(TIMER1_CAPT_vect) {
  uint16_t tval;
  tval=ICR1;
}
(Ich probier schon länger dran rum, die ISR enthält nur noch was nötig
ist um das Problem zu reproduzieren)

Damit ich jetzt abwechselnd auch an steigenden Flanken triggern kann,
muss ich im ISR das ICES1 Bit toggeln, also:
ISR(TIMER1_CAPT_vect) {
  uint16_t tval;
  tval=ICR1;
  TIMSK ^= _BV(ICES1); // Toggle flank to listen for
//  TIFR = _BV(ICF1);
}
Also im Prinzip so wie im Datenblatt vorgeschlagen, zuerst Wert
auslesen, dann ICES1 ändern, und dann das ICF1 Flag im TIFR
zurücksetzen (Der Schritt ist auskommentiert, macht keinen
Unterschied).

Problem ist nun, mit dieser ISR funktioniert es nur "meistens", etwa
jede 10.-20. Flanke am Eingangssignal führt der Tiny einen Reset aus.

Ich vermute, das ich dabei dann ungewollt irgendeinen nicht definierten
Interrupt auslöse, und die default "bad_interrupt" Routine vom GCC
dann resettet.

Irgendjemand eine Idee, was das sein könnte?

Danke,
/Ernst

Autor: TravelRec. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Am besten alle nicht benötigten Interrupts sperren oder gar nicht erst
einschalten. Oder den Watchdog mal ausmachen oder dessen Time-Out
verlängern. Vielleicht hängt ja das Programm und der Watchdog kommt...

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Watchdog hab ich schon rumprobiert, der ist es nicht (mit 2 Sekunden und
ohne getestet)

Ansonsten scheinen die anderen IRQs, die ich eingeschaltet habe auch in
Ordnung zu sein, zwei UART-Irqs, Timer0 Overflow alle 10ms, und eben den
Timer1 Overflow (der auch funktioniert) und den Timer1 Capture
Interrupt.

Wenn ich das "Flankenauswahl" Bit in der Capture-ISR nicht anfasse,
funktioniert ja auch alles, nur sobald ich die "TIMSK ^= _BV(ICES1);"
Zeile hinzufüge, resettet der AVR regelmässig.

Als Referenz mal der Abschnitt aus dem Datenblatt, vielleicht hab ich
das was falsch verstanden:

---------------
Measurement of an external signal’s duty cycle requires that the
trigger edge is changed after each capture. Changing the edge sensing
must be done as early as possible after the ICR1 Register has been
read. After a change of the edge, the Input Capture Flag (ICF1) must be
cleared by software (writing a logical one to the I/O bit location). For
measuring frequency only, the clearing of the ICF1 flag is not required
(if an interrupt handler is used).
----------------

/Ernst

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Keiner eine Idee?

Mir würd auch ein "Ich hab das schon benutzt, muss also gehen"
reichen, dann wüsste ich das ich weitersuchen muss...


Danke,
/Ernst

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lass die Zeile "TIFR = _BV(ICF1);" in der ISR drinne (nicht
auskommentieren)! Wenn Du das Flag nicht löschst wird nach dem
Verlassen der ISR nur der nächste Befehl von main() ausgeführt, und
danach landest Du automatisch (wegen des gesetzten 'ICF1') wieder in
der ISR.

Gruß
Magnetus

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hatts auch mit dem TIFR clear getestet, kein Unterschied, der Tiny hat
immer noch ständig resettet. (Hat vermutlich nur Blödsinn gemessen ohne
die TIFR=_BV(ICF1) Zeile, aber die Ausgabefunktionen waren das erste,
das ich zum Debuggen aus der ISR entfernt hatte).

... 5 minuten später ...

Hab den (blöden) Fehler aber glaubich grad selbst gefunden...
das ICES1 Flag ist nicht im TIMSK-Register, sondern im TCCR1B....

Manchmal ist man echt blind... hab das X-Mal im Datenblatt
nachgeschaut. grr..

Hab also "Aus Versehen" immer einen Compare-Match IRQ eingeschaltet,
und wenn der zufällig genau dann gekommen ist, ist der AVR in den Reset
gesprungen.

Danke an alle, die sich da mal drübergesehen haben,
/Ernst

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Hab den (blöden) Fehler aber glaubich grad selbst gefunden...
>> das ICES1 Flag ist nicht im TIMSK-Register, sondern im TCCR1B....

So eine ähnliche Vermutung schwirrte mir auch schon im Kopf herum ;)

Auf jeden Fall: Wenn Du mal den Gegencheck machen willst... einfach mal
die Zeile "TIFR = _BV(ICF1);" auskommentieren -> dann wird Dein Code
wieder nicht funktionieren (nur mal zum Verinnerlichen ggg).

In diesem Sinne: Viel Spass beim Entwickeln (und Debuggen) cheese

Magnetus

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.