Re: ISR Hardware Interrupt 0 Kategorie: Programmierung C (von Friedhelm Michel - 20.01.2010 19:31) | ||
Als Antwort auf Re: ISR Hardware Interrupt 0 von PeterS - 20.01.2010 18:07 | ||
| ||
> > 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 Ich wusste doch, dass ich was vergessen habe! Probier ich gleich aus. Danke! | ||
Antwort schreiben Antworten: |
Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum