Interrupt wird nur einmal ausgeführt

Gast #4003796
Lesenswert?
• ▲
▼
Hallo,

ich beschäftige mich aktuell mit Interrupts und habe ein Problem.

Ich verwende einen ATMEGA8 mit internen 8MHz.

Ich habe an Pin PD3 einen Taster gehängt (natürlich mit 10k gegen VCC) 
mit dem ich den Pin PD3 auf GND ziehe. Dieser Pin ist der 
Interrupteingang INT1 und dieser soll in der ISR eine Variable 
verändern. Es soll bei jedem Tastendruck die Variable s2 zwischen 1 und 
2 wechseln. Diese Variable wird in meinem Hauptprogramm ausgwertet und 
eine LED an- bzw. ausgeschaltet. Damit das Prellen des Tasters keinen 
Einfluß hat, habe ich in der ISR- Schleife eine Wartezeit definiert (ich 
weiß man sollte in ISRs keine "dummen" Wartezeiten programmieren aber 
für meine Anwendung reicht es aus).

Als Initialwert definiere ich in dem Hauptprogramm s2=2 und somit wird 
die LED eingeschaltet. Das funktioniert auch. Danach betätige ich den 
Taster und somit soll die Variable in der ISR von 2 auf 1 geändert 
werden und die LED soll ausgehen. Auch das funktioniert. ABER: Wenn ich 
jetzt den Taster wieder betätige passiert nichts mehr....

Anbei mein Code:
1
#include <avr/io.h>
2
#include <avr/pgmspace.h>
3

4
#define F_CPU 8000000L
5
#include <util/delay.h>
6
#include <avr/interrupt.h>
7

8

9
volatile int s2;
10

11
ISR(INT1_vect)
12
{
13
  if(s2==1)
14
  {
15
    s2=2;
16
  }
17
  
18
  if(s2==2)
19
  {
20
    s2=1;
21
  }
22
  _delay_ms(300);
23
}
24

25

26
int main(void)
27
{
28
  DDRB |= (1<<DDB3); 
29
  DDRD &= ~(1<<DDD3); 
30
  
31
  //Interrupts anschalten
32
  MCUCR |=(1<<ISC11);
33
  GICR |= (1<<INT1);
34
  
35
  s2=2;
36
  
37
  
38
    while(1)
39
  {
40
    //GICR |= (1<<INT1)|(1<<INT0);
41
    sei();
42
    
43
    if(s2==1)
44
    {
45
      PORTB &= ~(1<<PB3);
46
    }
47
  
48
    if(s2==2)
49
    {
50
      PORTB |= (1<<PB3);
51
    }
52
  }
53
}

Danke schon mal und Gruß Uwe
Gast #4003809
Lesenswert?
• ▲
▼
Naja, schau dir die Interrupt-Routine mal genauer an:
1
  if(s2==1)
2
  {
3
    s2=2;
4
  }
5
  
6
  if(s2==2)
7
  {
8
    s2=1;
9
  }


Im ersten Durchlauf greift das zeite if und die LED geht an.

Beim zweiten Durchlauf (s2==1) greift erst das erste if (s2 =2) und 
danach dann direkt das zweite if, dass s2 wieder auf 1 setzt.

Benutze
1
else if
antelle des zweiten if
Gast #4003815
Lesenswert?
• ▲
▼
Hallo Uwe,

zum ersten kommt sei(); vor den Mainloop.
Dann musst du dem MC noch sagen welche Richtung der Pin machen soll:
1
DDRB &= ~((1 << DDB3)); //Taster 
2
PORTB |= (1<<PB3); //Pullup ein

und zum dritten, du benutzt den INT1 als Ausgang wenn das ein Taster 
sein soll dann muss da ein Taster dran. Also am besten deinen Ausgang wo 
anders hin legen

Gruß Steffen

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.