AVR probleme ICP interrupt

#1131123
Lesenswert?

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?
#1132038
Lesenswert?

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...)
#1132297
Lesenswert?

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:
#1132317
Lesenswert?

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.
#1132461
Lesenswert?

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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren