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

Interrupt-Problem? Kategorie: Programmierung C (von Wolfgang - 30.03.2009 23:21)
Ich nutze:
C-Control Pro Mega128
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.

besten GruĂ?,
Wolfgang



    Antwort schreiben


Antworten:

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