Forum: Compiler & IDEs externer Interrupt


von udo (Gast)


Lesenswert?

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
}

von (prx) A. K. (prx)


Lesenswert?

udo wrote:

> weil der Befehl sei(); das "I" Flag
> nicht setzt. In AVR Studio kann ich das verfolgen.

Vermutung oder Gewissheit? Das wär ja mal was Neues. Nicht mehr 
"Compilerfehler" sondern "Prozessorfehler".

von Johannes M. (johnny-m)


Lesenswert?

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...

von Johannes M. (johnny-m)


Lesenswert?

>  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)

von udo (Gast)


Lesenswert?

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

von Johannes M. (johnny-m)


Lesenswert?

udo wrote:
>
1
> 
2
> PORTD=_BV(INT0) | _BV(INT1); //Pullups aktibier
3
>                                        ^^^^^^^^
4
>
Aktibier? Ist das Actimel für Leute mit Lactose-Unverträglichkeit?

Oder meinst Du vielleicht aktivieren ?

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.