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 Friedhelm Michel - 20.01.2010 19:31)
Als Antwort auf Re: ISR Hardware Interrupt 0 von PeterS - 20.01.2010 18:07
Ich nutze:
C-Control Pro Mega128, CC-Pro 128 Application Board
> > 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: