Forum: Mikrocontroller und Digitale Elektronik Atemga8 (Interrupt), Programm springt nicht zurück


von Abi (Gast)


Lesenswert?

Hallo zusammen,

ich hoffe, ihr könnt mir helfen.

Es geht um ein Programm für den Asuro.
es soll die status-LED kurz ausschalten, wenn man den Taster drückt. Das 
Problem ist, dass das Programm wahrscheinlich nicht zur While-schleife 
zurückspringt, um die LED dann wieder auf grün zu schalten.

Ich lasse die LED mit Absicht in der While-schleife auf grün setzen, um 
herauszufinden, ob das Programm nach dem Interrupt zur Schleife 
zurückspringt oder nicht.

#include <avr/io.h>
#include <avr/interrupt.h>

void init (void)
{
  // Datenrichtung der I/O-Ports festlegen.

  DDRB |= (1 << PB0);

       //enable  all interrupts

  GICR |= (1 << INT1);
  SREG |= (1 << 7);

  // Interrupt wird bei fallender Flanke ausgelöst

  MCUCR |=  (1 << ISC11);
  MCUCR &= ~(1 << ISC10);
  sei();
}

SIGNAL (INT1_vect)
{
    PORTB &= ~(1 << PB0); // Grüne LED aus
    reti();
}

int main(void)
{
  init();
  while(1)
  {
    PORTB |= (1 << PB0); // Grüne LED an
  }
  return 0;
}


freundliche Grüße

Abi

von Karl H. (kbuchegg)


Lesenswert?

1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
 
5
void init (void)
6
{
7
  // Datenrichtung der I/O-Ports festlegen. 
8
  DDRB |= (1 << PB0);
9
 
10
  //enable  all interrupts
11
  GICR |= (1 << INT1);
12
13
  // Interrupt wird bei fallender Flanke ausgelöst
14
15
  MCUCR |=  (1 << ISC11);
16
  MCUCR &= ~(1 << ISC10);
17
}
18
19
ISR(INT1_vect)
20
{
21
  PORTB &= ~(1 << PB0); // Grüne LED aus
22
}
23
 
24
int main(void)
25
{
26
  init();
27
28
  sei();
29
30
  while(1)
31
  {
32
    PORTB |= (1 << PB0); // Grüne LED an
33
  }
34
35
  return 0;
36
}

du willst keinen reti() selber aufrufen (das macht sowieso der Compiler 
für dich). Du willst auf das SREG nicht selber zugreifen (das macht der 
sei()). Du willst den sei() dezidiert vor der while Schleife haben, 
damit du ihn siehst (und nicht in irgendwelchen obskuren Funktionen 
verstecken), du willst SIGNAL nicht mehr benutzen (sondern ISR, denn 
dann passt auch der Name der ISR zur Verwendung)

von Abi (Gast)


Angehängte Dateien:

Lesenswert?

Das Problem war wegen reti(). Wenn sie da ist, dann reagiert das 
Programm beim zweiten Tastendrücken nicht.
ob ich auf SREG zugreife oder nicht und ob ISR oder SIGNAL, das is egal.
hier ist das richtige Programm, was funktioniert, es soll die LED-Farbe 
zwischen Grün und Rot schalten, wenn man den Taster drückt.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
void init (void)
5
{
6
  // Datenrichtung der I/O-Ports festlegen. 
7
  DDRB |= (1 << PB0);
8
  DDRD |= (1 << PD2);
9
10
  PORTB |= (1 << PB0); // Grüne LED an
11
  PORTD &= ~(1 << PD2); // Rote LED aus
12
 
13
  //enable  all interrupts
14
  GICR |= (1 << INT1);
15
  SREG |= (1 << 7);
16
17
  // Interrupt wird bei fallender Flanke ausgelöst
18
19
  MCUCR |=  (1 << ISC11);
20
  MCUCR &= ~(1 << ISC10);
21
}
22
23
SIGNAL(INT1_vect)
24
{
25
 if (PINB & (1 << PB0)){  // Grün  an ?
26
  PORTB &= ~(1 << PB0); // Grün aus.
27
  PORTD |= (1 << PD2);  // Rot an.
28
  
29
   }else if (PIND & (1 << PD2)){ // Rot an ?
30
      PORTD &= ~(1 << PD2); // Rot aus.
31
      PORTB |= (1 << PB0); // Grün an.
32
   }
33
}
34
35
int main(void)
36
{
37
  init();
38
39
  sei();
40
41
  while(1)
42
  {    
43
  }
44
  return 0;
45
}

von Timmo H. (masterfx)


Lesenswert?

Dennoch solltest du nicht mehr SIGNAL benutzen. Momentan geht noch 
beides aber irgendwann ist SIGNAL weg. Und wenn du unbedingt SIGNAL 
benutzen musst, dann würde der Vector richtigerweise "SIG_INTERRUPT1" 
heissen

Also entweder
1
SIGNAL(SIG_INTERRUPT1)
2
...
oder
1
ISR(INT1_vect)
2
...
Aber wie gesagt, letzteres ist vorzuziehen weil SIGNAL "deprecated" also 
veraltet ist.

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.