Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum

Re: Interrupt-Problem? Kategorie: Programmierung C (von PeterS - 31.03.2009 13:29)
Als Antwort auf Interrupt-Problem? von Wolfgang - 30.03.2009 23:21

> Hallo Peter,
>
> in meinem eigenen Board wird von externer Logik alle 20ms ein Interrupt an IRQ1 erzeugt, bei dem
> meine Schaltung darauf angewiesen ist, dass er innerhalb 10ms zwei ADC-Werte ausliest, die später
> nicht mehr korrekt anstehen. Das klappt auch fast immer, aber etwa alle 700s (!) geht es mehrmals
> hintereinander (für länger als 1s) schief.
>
> Zur �berprüfung ziehe ich einen Pin high, sobald ich in der ISR-Routine bin, und setze den Pin
> wieder runter, nachdem ich die AD-Wandler gelesen habe. Dann kann ich auf einem Oszilloskop
> ansehen, wie lange es vom Ziehen des IRQ-Pins bis zum Eintritt in die ISR-Routine dauert. Meine
> Beobachtung: während es normalerweise ca. 50..55µs sind, sind es bei den Ausreissern ziemlich
> genau 10ms, also stolze 200-mal so lange! Mir scheint, das kann nicht mit der Bearbeitungsdauer
> des gerade bearbeiteten Befehles zu erklären sein, oder?
>
> In meinem kompletten Programm habe ich einen weiteren externen IRQ zu bearbeiten (auf IRQ5) sowie
> beide serielle Schnittstellen im Interrupt-Modus laufen, aber das habe ich zur Fehlersuche alles
> abgeschaltet/weggelassen, ohne dass sich am Fehlerbild irgendetwas geändert hätte.
>
> Meine Einrichtung des IRQ1 lautet folgendermassen:
>
> #define IRQ1     25
> #define In  0
> #define negEdge   2                                         // IRQ bei fallender Flanke
>  ...
>   Port_DataDirBit(IRQ1, In);
>   Irq_SetVect(INT_1,Waage_IRQ);                     // Interrupt-Routine zum Auslesen der ADCs
>   Ext_IntEnable(1, negEdge);                            // Enable IRQ_1 mit Mode=2: 'falling Edge'
>
>
> Die ISR-Routine sieht so aus:
>
> #define EXP_PA6   6                                       // Marker für regelnden 10ms-IRQ
> #define Low    0
> #define High   1
> ...
> void Waage_IRQ(void)
> { Port_WriteBit(EXP_PA6, High);                      // Marker setzen
>
>   ADC_Set(ADC_VREF_VCC, ADC_An_B); An_B = ADC_Read();
>   ADC_Set(ADC_VREF_VCC, ADC_A_Bn); A_Bn = ADC_Read();
>
>   Port_WriteBit(EXP_PA6, Low);                       // Marker löschen
>   ...
>   Irq_GetCount(INT_1);
> }
>
> (An_B und A_Bn sind globale Integer-Variablen)
>
>
> Mir schleicht der Verdacht im Hinterkopf herum, dass das vielleicht etwas mit dem eingebauten Timer-
> Interrupt zu tun haben könnte, der ja 10ms-Ticks liefern soll - kann der gelegentlich vielleicht so lange
> brauchen? Oder kann ich den irgendwie komplett abschalten?
>
> Fällt Dir sonst irgendetwas ein, was ich prüfen oder ändern sollte? Erledigt Dein System gelegentlich
> irgendeine nach aussen nicht sichtbare Sonderaufgabe (zumindest früher war mal 'Garbage Collect'
> so ein Kandidat)? Bin für jeden Tip dankbar, nachdem ich schon ziemlich lange gesucht habe, bis ich
> wenigstens das Phänomen soweit beschreiben konnte.

Alle 700s sind schon ein merkwürdiger Wert. Kann meines Wissens nichts mit dem 10ms Interrupt
zu tun haben. Langwierige Flie�komma Operationen können so lang innerhalb eines Bytecodes dauern.
Man kann zu Testzwecken mit den Direct Access Befehlen den Timer 2 Interrupt ausschalten.
Siehe Mega128 Refernzhandbuch.

Gruss Peter

>
> besten GruÃ?,
> Wolfgang
>
>


    Antwort schreiben


Antworten:

Re: Interrupt-Problem? (von Wolfgang - 31.03.2009 21:08)
    Re: Interrupt-Problem? - Nachtrag (von Wolfgang - 31.03.2009 21:57)