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) |
Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum