mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interrupt mit Pin als Eingang will nicht


Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jungs, ich stehe mal wieder aufm Schlauch.
Ich möchte das wenn Pin A1 auf GND geht ein Interrupt ausgelöst wird und 
di eLED an Pin A0 leuchtet.
Dazu habe ich folgenden Code getippt:
ISR(INT1_vect)
{
  GICR &= ~(1 << INT1);
  PORTA |= (1 << PA0);

};


int main(void)
{


//Timer initialisieren
 /*  TCCR0 |= (1<<CS00)|(1<<CS02);
   TIMSK =(1<<TOIE0);
*/
   DDRA = (1 << DDA0);
   DDRA &= ~(1 << DDA1);
   PORTA |= (1 << PA1);
   MCUCR = (1 << ISC11);
   GICR = (1 << INT1);
   sei();

Leider geht ier nie in den Interrupt.
Wo liegt mein Fehler?
Muss bestimmt noch in irgendein Register ein Bit setzen aber weis nicht 
wo noch?

Für einen Tip wäre ich dankbar.

Grüße Christian

Autor: Bastian F. (bastian_f)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du schreibst nicht welchen Uc du benutzt.
Bei einem Atmega8(8) (den kenne ich ein bisschen), sind die externen 
Interrupts über PD2 bzw PD3 ansteuerbar.
Dann zB so:
ISR (INT0_vect) {
    dosomething();
}

int main() {
    DDRD  &= ~(1<<PD2);                    // Port als Eingang
    PORTD &= ~(1<<PD2);                    // Pull Up an PD2 = INT0 aktivieren
    GICR |=(1<<INT0);                    // Ext. Interrupt an INT0
    MCUCR |=(0<<ISC01) | (0<<ISC00);            // Interrupt, wenn INT0 = GND
    sei();

    while(1) {
    }
}

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich benutze einen Atmega 162

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian schrieb:
> Ich benutze einen Atmega 162

dann würde dir ein Blick ins Datenblatt verraten, dass INT1 an Pin D3 
liegt...

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Ich benutze einen Atmega 162

Da liegt INT1 aber auf PD3. PA1 ist PCINT1 !

MfG Spess

Autor: Rene K. (draconix)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der PIN A1 liegt beim 162 als PCINT1 vor... Das ist ein Pin Change 
Interrupt, das ist nicht das selber wie der externe Interrupt.

Um ihn zu initialisieren mußt du:

GICR   = (1<<PCIE0)     //Pin Change Interrupt 0 ein
PCMSK0 = (1<<PCINT1)    //Pin Change von PCINT0 - PortA Pin 1

...

ISR (0x008) {           //Interrupt Reg 0x008
    dosomething();
}


Darauf achten das der PCINT JEDEN logischen Wechsel detektiert, quasi 
von low zu high und von high zu low. Dies mußt du in der Software 
auswerten ob PA1 nun high oder low ist.

EDIT: SREG - I muß natürlich auch gesetzt sein!

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian schrieb:
> };

das ist Unsinn und:

hast du eine Endlosschleife im main damit der Interrupt überhaupt eine 
Chance kriegt?

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist keine Endlosschleife, blos der weitere code hat nichts mit dem 
Interrupt zu tun.
Wie heißt denn der Interrupt richtig? ISR(0x00A) funzt nicht, da meckert 
der Compiler rum.

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Desweiteren finde ich das Register SREG nicht in der iom162.h und der 
Compiler kennt es smit nicht. Wo liegt das Problem?

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wollts nochmal hoch schieben, vielleicht weis noch wer Antwort.
Grüße Christian

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Wozu brauchst du bei C das Statusregister?

MfG Spess

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie kann ich denn demInterrupt beibringen nur bei fallender Flanke zu 
reagieren? Muss ja deiesen Pin Change Interrupt nutzen

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Soweit hab ichs jetzt aber die LED geht leider nicht an wenn der 
Pinzustand gewechselt wird.
ISR(PCINT1_vect)
{
  if (PINA & (1 << PINA1))
  {
    GICR &= ~(1 << PCIE0);
      PORTA |= (1 << PA0);
    //wdt_enable (WDTO_2S);
  }



  }

int main(void)
{

   DDRA = (1 << DDA0);
   DDRA &= ~(1 << DDA1);
   PORTA |= (1 << PA1);
   GICR   = (1<<PCIE0);     //Pin Change Interrupt 0 ein
   PCMSK0 = (1<<PCINT1);    //Pin Change von PCINT0 - PortA Pin 1

   MCUCR = (1 << ISC11);
   //SREG = (1 << I);
   initialisierung();
   sei();
.
.
.
}

Autor: Rene K. (draconix)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian schrieb:
> PCMSK0 = (1<<PCINT1);

Muß PCINT0 sein! EDIT: Nee ist richtig... PCINT1 nehmen.

Versuch erstmal in deiner ISR jede Zustandsänderung zu toggeln. Um zu 
sehen ob sie da überhaupt läuft. Welchen Compiler nutzt du eigentlich? 
und...

Christian schrieb:
> MCUCR = (1 << ISC11);

Benötigst du nicht...

Übrigens mit sei() wird das SREG I Bit gesetzt. Bei meinem Compiler muß 
ich das von Hand machen ;)

Christian schrieb:
> GICR &= ~(1 << PCIE0);

Und diesen bitte ebenfalls rauswerfen.

Autor: Siehe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian schrieb:
> Wollts nochmal hoch schieben, vielleicht weis noch wer Antwort.

Dir wurde alle gesagt - teilweise sogar mehrfach.
Das Datenblatt wird dir keiner vorlesen, also setz dich auf deine 4 
Buchstaben und lies es.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.