Interrupts konkurrieren

OP #3764234
Lesenswert?
• ▲
▼
Hallo.

Ich habe hier ein kleines Problem mit meinem ATxmega128A1.

Es soll mit einer Frequenz von 250kHz Werte vom ADc eingelesen werden.
Der ADC ist momentan im Freerun modus konfiguriert und der 
Interrupt-mode ist auf "complete" gestelt.

Die ISR des ADCs sieht so aus:
1
ISR(ADCA_CH0_vect) {
2
    PORTF.OUTTGL = PIN1_bm;
3
    if (protectFlag == 0) {
4
        adcAvgVal += val;
5
        adcSamples++;
6
    }
7
}

So weit so gut. Bis hierher funktioniert alles ohne Probleme. Die 250kHz 
wurden mittels Oszi kontrolliert.

Jetzt habe ich einen Timer, welcher mit 40kHz getaktet ist. Dieser Timer 
soll in jeden Taktzyklus das arithmetische Mittel des ADC-Wertes 
berechnen und diesen in einer Variable speichern.

Den Timer prüfe ich manuell in der Main-While-Schleife ab (ich dachte so 
kann ich einen interrupt vermeiden, da ich nur auf das Flag prüfe)
1
if ((TCC0.INTFLAGS & TC0_OVFIF_bm) != 0) {
2
    TCC0.INTFLAGS = TC0_OVFIF_bm;
3
    //PORTF.OUTTGL = PIN1_bm;
4
    protectFlag = 1;
5
    currentVal  = adcAvgVal / adcSamples;
6
    adcSamples  = 0;
7
    adcAvgVal   = 0;
8
    protectFlag = 0;
9
}

Jetzt zum eigentlichen Problem:
Sobald der ADC und der Timer die slebe Interrupt-Priorität haben, kommt 
der ADC-Interrupt nicht mehr an die Reihe. Es ist immer ein entweder 
oder.
#3764269
Lesenswert?
• ▲
▼
@Andre S. (xolom)

>Es soll mit einer Frequenz von 250kHz Werte vom ADc eingelesen werden.

Ganz schönn schnell!

>Jetzt habe ich einen Timer, welcher mit 40kHz getaktet ist. Dieser Timer
>soll in jeden Taktzyklus das arithmetische Mittel des ADC-Wertes
>berechnen und diesen in einer Variable speichern.

Das machst du besser in deinem 250kHz Interrupt, da ist das besser 
synchronisiert und die beiden ISRs spucken sich nicht gegenseitig in's 
Timing.

>Sobald der ADC und der Timer die slebe Interrupt-Priorität haben, kommt
>der ADC-Interrupt nicht mehr an die Reihe. Es ist immer ein entweder
>oder.

Da ist wohl was falsch konfiguriert.
Gast #3764271
Lesenswert?
• ▲
▼
Wie stellst Du fest, das der ADC-Interrupt nicht mehr drankommt?

Warum spielt die Interrupt-Priorität aus Deiner Sicht eine Rolle, wenn 
Du doch keine Interrupt-Routine für den Timer verwendest? Nach Deinem 
Codeschnipsel gibt es nur einen Interrupt.

Warum ist die Frequenz mit welcher der Mittelwert berechnet wird, kein 
Teiler der Abtastfrequenz? Warum wird der Mittelwert nicht als 
Konsequenz (im kausalen Sinn) der Abtastung berechnet sondern unabhängig 
davon?
#3764280
Lesenswert?
• ▲
▼
Hi Andre,
normalerweise sollten zwei Interrupts gleicher Priorität sich natürlich 
nicht ausschließen, sondern nacheinander abgearbeitet werden wenn sie 
gleichzeitig auftreten sollen =)

Der Hinweis von Bitflüsterer ist gut mit der Interrupt-Service-Routine. 
Wenn du keine hast kann sich dein Programm aufhängen, da der Controller 
nicht weiss wo er "hinspringen" soll. Ich glaube es gibt zwar eine 
"Default"-ISR aber diese muss auch definiert sein, damit sie greift.

Auf welche Priorität setzt du sie denn? Nutzt du die Defines, wie 
ADC_CH_INTLVL_LO_gc? Mir ist es mal passiert, dass ich für das Setzen 
eines Timer Interrupt eine falsche Define verwendet habe und er somit 
einen ganz anderen Wert im Register gesetzt hat. Deswegen die Frage nach 
der Define.

Ansonsten kann man die einzelnen Interrupt-Prioritäten auch sperren. Um 
alle einzuschalten reicht normalerweise die Funktion pmic_init().

Gruß Olli

Antwort schreiben

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.

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.