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


von Christian (Gast)


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:
1
ISR(INT1_vect)
2
{
3
  GICR &= ~(1 << INT1);
4
  PORTA |= (1 << PA0);
5
6
};
7
8
9
int main(void)
10
{
11
12
13
//Timer initialisieren
14
 /*  TCCR0 |= (1<<CS00)|(1<<CS02);
15
   TIMSK =(1<<TOIE0);
16
*/
17
   DDRA = (1 << DDA0);
18
   DDRA &= ~(1 << DDA1);
19
   PORTA |= (1 << PA1);
20
   MCUCR = (1 << ISC11);
21
   GICR = (1 << INT1);
22
   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

von Bastian F. (bastian_f)


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:
1
ISR (INT0_vect) {
2
    dosomething();
3
}
4
5
int main() {
6
    DDRD  &= ~(1<<PD2);                    // Port als Eingang
7
    PORTD &= ~(1<<PD2);                    // Pull Up an PD2 = INT0 aktivieren
8
    GICR |=(1<<INT0);                    // Ext. Interrupt an INT0
9
    MCUCR |=(0<<ISC01) | (0<<ISC00);            // Interrupt, wenn INT0 = GND
10
    sei();
11
12
    while(1) {
13
    }
14
}

von Christian (Gast)


Lesenswert?

Ich benutze einen Atmega 162

von Justus S. (jussa)


Lesenswert?

Christian schrieb:
> Ich benutze einen Atmega 162

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

von spess53 (Gast)


Lesenswert?

Hi

>Ich benutze einen Atmega 162

Da liegt INT1 aber auf PD3. PA1 ist PCINT1 !

MfG Spess

von Rene K. (draconix)


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:
1
GICR   = (1<<PCIE0)     //Pin Change Interrupt 0 ein
2
PCMSK0 = (1<<PCINT1)    //Pin Change von PCINT0 - PortA Pin 1
3
4
...
5
6
ISR (0x008) {           //Interrupt Reg 0x008
7
    dosomething();
8
}

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!

von Walter (Gast)


Lesenswert?

Christian schrieb:
> };

das ist Unsinn und:

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

von Christian (Gast)


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.

von Christian (Gast)


Lesenswert?

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

von Christian (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

Hi

Wozu brauchst du bei C das Statusregister?

MfG Spess

von Christian (Gast)


Lesenswert?

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

von Christian (Gast)


Lesenswert?

Soweit hab ichs jetzt aber die LED geht leider nicht an wenn der 
Pinzustand gewechselt wird.
1
ISR(PCINT1_vect)
2
{
3
  if (PINA & (1 << PINA1))
4
  {
5
    GICR &= ~(1 << PCIE0);
6
      PORTA |= (1 << PA0);
7
    //wdt_enable (WDTO_2S);
8
  }
9
10
11
12
  }
13
14
int main(void)
15
{
16
17
   DDRA = (1 << DDA0);
18
   DDRA &= ~(1 << DDA1);
19
   PORTA |= (1 << PA1);
20
   GICR   = (1<<PCIE0);     //Pin Change Interrupt 0 ein
21
   PCMSK0 = (1<<PCINT1);    //Pin Change von PCINT0 - PortA Pin 1
22
23
   MCUCR = (1 << ISC11);
24
   //SREG = (1 << I);
25
   initialisierung();
26
   sei();
27
.
28
.
29
.
30
}

von Rene K. (draconix)


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.

von Siehe (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.