Forum: Mikrocontroller und Digitale Elektronik AVR probleme ICP interrupt


von Luky S. (luky)


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?

von Luky S. (luky)


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...)

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Setze mal das Timerinteruptflag zurück am ende der ISR indem du eine 1 
reinschreibst.
ggf tritt der Timerinterupt WÄHREND des ICP Interupt auf, dann würde das 
Flag gesezt und beim verlassen der Overflow Interupt ausgelöst.
ggf könnte auch das volstndige Programm (als Anhang) helfen.

von Luky S. (luky)


Angehängte Dateien:

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.

von Luky S. (luky)


Angehängte Dateien:

Lesenswert?

Hier mal das Oszibild des Vorganges...

von (prx) A. K. (prx)


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.

von Luky S. (luky)


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?

von (prx) A. K. (prx)


Lesenswert?

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.

von Luky S. (luky)


Lesenswert?

Eine Plausibilitätskontrolle
1
if ( (dt > 5994) && (dt < 7326) ) { //Max. Abweichung +-10%
2
...
3
}
habe ich eingebaut. Hoffe, das reicht...

von (prx) A. K. (prx)


Lesenswert?

Yep, das sollte ausreichen.

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
Noch kein Account? Hier anmelden.