AVR probleme ICP interrupt

OP #1131123
Ich habe einen ATmega168 mit 1MHz und möchte eine Pulslänge messen. Dazu 
verwende ich das  ICP-Modul von Timer 1 und zusätzlich den Timer 
Overflow Interrupt, um ein ungültiges Signal festzustellen. Die 
Signallänge darf 6-7 ms betragen, ich habe keinen Timer prescaler. Also 
dürfte der Overflow Interrupt nie aufgerufen werden.
1
...
2
TCCR1B = (1<< ICNC1) | (1<< CS10); //falling Edge, Noise Canceler, CLk/1
3
TIMSK1 = (1<< ICIE1); //Input Capture Enable
4
...
5

6
SIGNAL(SIG_INPUT_CAPTURE1) {
7

8
PORTD &= ~(1<< PD7);
9
  
10
if (syncstat == 10) { //erste fallende Flanke
11
  TCNT1 = 0; //Timer auf 0 setzen
12
  TIMSK1 = (1<< ICIE1) | (1<< TOIE1); //Input Capture + Overflow Interrupt Enable
13
  syncstat = 11; //warte auf zweite fallende Flanke
14
} else if (syncstat == 11) { //zweite fallende Flanke
15
  dt = ICR1; //Sollwert 6660 @ 1MHz
16
    
17
  TCCR1B = 0x00; //deaktivieren
18
  TIMSK1 = 0x00 ; //deaktivieren
19

20
  syncstat = 128;
21
}
22

23
PORTD |= (1<< PD7);
24
}
25

26
SIGNAL(SIG_OVERFLOW1) { //Darf nie aufgerufen werden -> Fehler!
27

28
PORTD &= ~(1<< PD5);
29
//UART_print("SIG_OVERFLOW");
30
PORTD |= (1<< PD5);
31

32
}

Der Overflow-Interrupt wird aber merkwürdigerweise 60µs nach dem 
ICP-Interrupt aufgerufen.
Hat jemand eine Erklärung?
OP
Ich habe jetzt mal die Namen der Interruptroutinen an den modernen 
Standart (ISR(TIMER1_CAPT_vect) usw.) angepasst, hat aber nichts 
geändert.
Das merkwürdige ist, das es keinen Unterschied zu machen scheint, mit 
welcher Geschwindigkeit der Timer läuft.
Der Overflow Interrupt wird immer im Anschluss an die ICP Routine 
ausgeführt (Wo ich den Timerwert ja auf 0 setze...)
OP
Hat leider nichts gebracht
Im Anhang mein Testrogramm.
Es macht momentan noch nicht viel. Später soll es mal die Pulslängen 
eines mit 300Bd gesendeten RS232 Signals mit Even Parity (0x55 = 
0b1010101) messen und sich auf dieses Synchronisieren.
Der Overflow Interrupt dient dazu, ungültige Signale abzufangen.
Erlaubt sind 6,66ms +-10%, also bei 1MHz Timertakt 6660 Takte. Der 16Bit 
Timer darf also sicher nicht überlaufen, falls wirklich ein gültiges 
Synchronisationssignal empfangen wurde.
Angehängte Dateien:
Präzise Messung geht so nicht, da in diesem Code die Reaktionszeit der 
ISR mit eingeht.

Besser: Timer frei laufen lassen und die Differenz aufeinander folgender 
Capture-Werte bilden. Ist dann taktgenau ohne Einfluss der ISR.

Test auf "ungültig" sieht dann anders aus, da der Overflow regelmässig 
auftritt. Aber vielleicht reicht es dir dafür die Erkenntnis aus, das 
ganz ohne Signal zwischen 2 Overflows kein Capture erfolgt.
OP
Ich habe den Code jetzt geändert
1
ISR(TIMER1_CAPT_vect) {
2
...
3
  if (syncstat == 10) { //erste fallende Flanke
4
    
5
    fl1 = ICR1;
6
    owfl1 = 0;
7

8
    TIMSK1 = (1<< ICIE1) | (1<< TOIE1); //Input Capture + Overflow Interrupt Enable
9
    syncstat = 11; //warte auf zweite fallende Flanke
10
  } else if (syncstat == 11) { //zweite fallende Flanke -> 1. Zyklus fertig
11
    dt = (ICR1 + owfl1 * 65536) - fl1;
12
  }  
13
    
14
...
15

16

17
ISR(TIMER1_OVF_vect) { //Timer1 Overflow
18
  owfl1++;
19

20
}

Funktioniert soweit ganz gut.
Danke für die Hilfe. Warum der Overflow Interrupt aber fälschlicherweise 
aufgerufen wurde weis ich immer noch nicht.

Die Werte schwanken jetzt aber recht stark im Bereich von 6687 bis 6733. 
Als Sender dient ein FT232RL.
Liegt das im normalen Bereich?
Würde ich als normal einschätzen.

Bin mir aber grad nicht sicher, ob die Overflow-Rechnung nicht ganz 
selten mal Unfug produzieren kann. Sowas wie ICR1=0 und owf11=0 oder 
ICR1=0xFFFF und ovf11=1. Lässt sich mit Ergebniskontrolle abfangen.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.