ISR Hardware Interrupt 0 Kategorie: Programmierung C (von Friedhelm Michel - 20.01.2010 16:20) | ||
| ||
Hallo, folgendes Problem tritt bei der Verwendung eines externen Interupts auf: Ein Signalgeber, der abwechselnd â??lowâ?? und â??highâ?? erzeugt, ist an Port D, Pin 0 angeschlossen. Es handelt sich um einen Inkrementaldrehgeber. Die erzeugten Pegel wurden an Port D, Pin 0 mit einem Voltmeter gemessen. Nach jedem Drehstep erscheinen abwechselnd 0.002 V oder 4.98 V, je nach Drehstellung. Da die Auswertelogik die ansteigende und die abfallende Flanke des Signals erkennen muss, wurde der Interupt 0 mit dem Wert 1 freigegeben. Nachdem der Drehgeber einmal auf die nächste Stufe gestellt wurde (Signalwechsel) wird der geforderte Interrupt ausglöst. Allerdings lässt sich der Interrup kein zweites mal auslösen. An den LED Ausgaben kann ich ablesen, dass der Pegel am IRQ Pin nicht mehr wechselt obwohl die Voltmessung einen Pegelwechsel anzeigt. Um die Verwirrung zu komplettieren, habe ich das Ganze im Debugger versucht. Dort zeigt sich ein ganz anderer Effekt. Wenn ein Break Point in die ISR gesetzt wird dann wird die ISR nach dem ersten IRQ immer wieder aufgerufen obwohl kein weiterer IRQ stattgefunden hat. Da es sich hier um eine Funktionalität handelt die wohl schon hunderte mal von verschiedenen Usern angewandt wurde bleiben eigentlich nur zwei Lösungen über: Entweder ich habe etwas total übersehen oder ich habe etwas totgemessen. Andere Steueraufgaben über Port D funktionieren alldings. z.B. Ansteuerung von Schrittmotoren. Hier mein Testprogramm: byte ISRval; byte ISRpulse; void DoOneStep_ISR(void) { ISRpulse = Port_ReadBit(PortD.0); // lese den aktuellen Pegel am Interrupt Pin Port_WriteBit(PORT_LED2,ISRpulse ^ 1); // Den ausgelesenen Pegel an LED 2 anzeigen ISRval++; // Zum Zeichen für den IRQ Eintritt wird // die Variable jedesmal inkrementiert Port_WriteBit(PORT_LED1,ISRval & 1); // das unterste Bit wird zur sichtbaren // Kontrolle auf LED 1 geleitet } // LED 1 müsste bei jedem ISR Eintritt umschalten (Drehgeber Step) // LED 2 soll dazu den aktuellen Pegel am IRQ pin darstellen. void main(void) { byte pulse; ISRval = 0; // Variable auf definierte Ausgangswerte setzen Port_DataDirBit(PORT_LED1,PORT_OUT); // Vorbereitung LED 1 für Ausgabe Port_DataDirBit(PORT_LED2,PORT_OUT); // Vorbereitung LED 2 für Ausgabe Port_DataDirBit(PortD.0,PORT_IN); // Vorbereitung Port D, Pin 0 als IRQ signal Port_WriteBit(PortD.0,0); // pull up Widerstand explizit abschalten Irq_SetVect(INT_0,DoOneStep_ISR); // Die ISR an externen interup 0 binden Ext_IntEnable(0,1); // Interrup 0 für 'rising and falling edge' freigeben while(true) { pulse = Port_ReadBit(PortD.0); // lese parallel den aktuellen Pegel am // Interrupt Pin aus falls die ISR nicht // mehr aufgerufen wird AbsDelay(10); // 'Angst essen Seele' delay Port_WriteBit(PORT_LED2,pulse ^ 1); // den aktuellen Pegel mit LED2 anzeigen } } Hat jemand eine Idee? MfG Friedhelm Michel | ||
Antwort schreiben Antworten: Re: ISR Hardware Interrupt 0 (von PeterS - 20.01.2010 18:07) Re: ISR Hardware Interrupt 0 (von Friedhelm Michel - 20.01.2010 19:31) |
Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum