externer Interrupt

Gast #1134665
Hallo,

der Interrupt wird nicht ausgelöst, weil der Befehl sei(); das "I" Flag 
nicht setzt. In AVR Studio kann ich das verfolgen. Wenn ich aber
1
GICR |= (1<<INT0) | (1<<INT1);

deaktiviere, dann wird der Befehl sei(); ausgeführt. Ich muss doch 
sowohl die Bits INT0 und INT1 und das "I"-Flag setzen. Aber die stören 
sich gegenseitig. Warum?


Es wird der MEGA16 eingesetzt.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3

4

5
#define F_CPU 7372800UL       
6

7
#include <util/delay.h> 
8

9

10
ISR(TIMER0_OVF_vect)
11
    
12
  {
13
  PORTA=0xdd;
14
  }
15

16

17
ISR(TIMER1_OVF_vect)
18

19
  { 
20
  PORTA=0xaa;
21
  }
22

23

24
void init(void)
25

26
{
27
 
28
        TCCR1B = _BV(CS11); 
29

30

31
  GICR |= (1<<INT0) | (1<<INT1);    // Interrupt Enable
32

33
 
34
  DDRD &= ~( ( 1 << PIND2 ) | ( 1<<PIND3) ); //INT0 und INT1 Eingang
35

36
  
37
  PORTD=_BV(INT0) | _BV(INT1); //Pullups aktibieren
38

39
  sei();
40

41
  DDRA = 0xff;
42

43
}   
44

45

46
int main(void)
47
{
48
   
49
  uint8_t i = 0;
50

51
  init();  
52
  
53
    for(;;)
54
    {
55

56
              for(i=0;i<255;i++)
57
      {
58
         PORTA = i;    
59
           _delay_ms(50); 
60
      }
61

62
    for(i=255;i>0;i--)
63
      {
64
         PORTA = i;    
65
           _delay_ms(50); 
66
      }
67
    }
68
    return 0;
69
}
#1134683
Du musst Dich erstmal entscheiden, welche Interrupts Du benutzen willst! 
Du gibst zwei externe Interrupts frei, hast aber für die gar keine 
Interrupt Handler geschrieben. Stattdessen hast Du zwei Interrupt 
Handler für Timer-Interrupts da stehen, die schon aus dem Grunde 
unsinnig sind, weil die Interrupts nirgends freiegegeben werden und auch 
nirgends ein Timer initialisiert wird.

TIMER0_OVF_vect und TIMER1_OVF_vect haben nichts mit externen 
Interrupts zu tun. Und ein freigegebener Interrupt ohne dazu passenden 
Handler führt bei Auftreten zwangsläufig zu einem Programmneustart. Und 
von der Sorte gibt's in Deinem Programm gleich zwei...
#1134697
>  PORTD=_BV(INT0) | _BV(INT1); //Pullups aktibieren
Das ist z.B. auch Unsinn. INT1 und INT0 sind die Nummern der lokalen 
Freigabebits der Interrupts im GICR. Die haben nichts mit der 
Pinbelegung am Port zu tun. Wenn das funktioniert, dann nur zufällig!

(Beim ATMega16 z.B. funktioniert es definitiv nicht, weil INT1 == 7 und 
INT0 == 6, die Pins am Port D aber, wie Du eine Zeile weiter oben ja 
auch richtig geschrieben hast, an Stelle 3 bzw. 2 liegen)
Gast #1134811
Hallo Leute,

Kommando zurück!

Habe beim Kopieren Codeschnipsel durcheinander geschmissen. Ich meinte 
nicht den TIMER Interrupt in der ISR, sondern den externen Interrupt.

Also, ich checke noch mal durch.

Und hier:
1
PORTD=_BV(INT0) | _BV(INT1); //Pullups aktibier

Klar!!!! Anfängerkrimskrams. Learning by doing. Muss man (noch) mit 
leben.



Danke zunächst.

Udo

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.