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:
1 | TCCR1A = 0;
|
2 | TCCR1B=_BV(ICNC1) | _BV(CS11) ; // Noise Canceler, CLK/8;
|
3 | 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:
1 | ISR(TIMER1_CAPT_vect) {
|
2 | uint16_t tval;
|
3 | tval=ICR1;
|
4 | }
|
(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:
1 | ISR(TIMER1_CAPT_vect) {
|
2 | uint16_t tval;
|
3 | tval=ICR1;
|
4 | TIMSK ^= _BV(ICES1); // Toggle flank to listen for
|
5 | // TIFR = _BV(ICF1);
|
6 | }
|
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