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

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)