mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR probleme ICP interrupt


Autor: Luky S. (luky)
Datum:

Bewertung
0 lesenswert
nicht 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.
...
TCCR1B = (1<< ICNC1) | (1<< CS10); //falling Edge, Noise Canceler, CLk/1
TIMSK1 = (1<< ICIE1); //Input Capture Enable
...

SIGNAL(SIG_INPUT_CAPTURE1) {

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

  syncstat = 128;
}

PORTD |= (1<< PD7);
}

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

PORTD &= ~(1<< PD5);
//UART_print("SIG_OVERFLOW");
PORTD |= (1<< PD5);

}

Der Overflow-Interrupt wird aber merkwürdigerweise 60µs nach dem 
ICP-Interrupt aufgerufen.
Hat jemand eine Erklärung?

Autor: Luky S. (luky)
Datum:

Bewertung
0 lesenswert
nicht 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...)

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Luky S. (luky)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Luky S. (luky)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier mal das Oszibild des Vorganges...

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Luky S. (luky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe den Code jetzt geändert

ISR(TIMER1_CAPT_vect) {
...
  if (syncstat == 10) { //erste fallende Flanke
    
    fl1 = ICR1;
    owfl1 = 0;

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


ISR(TIMER1_OVF_vect) { //Timer1 Overflow
  owfl1++;

}

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?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Luky S. (luky)
Datum:

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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Yep, das sollte ausreichen.

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.