Re: ISR Hardware Interrupt 0 Kategorie: Programmierung C (von PeterS - 20.01.2010 18:07) | |
Als Antwort auf ISR Hardware Interrupt 0 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 > Bitte am Ende der Interruptoutine Irq_GetCount() aufrufen, das führt einen IRQ Acknowledge aus. Ist in jeder Demo die Interrupts benutzt drin, einfach mal einen Blick auf die Demoprogramme werfen! Gruss Peter | |
Antwort schreiben Antworten: 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