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)