Atmega32U4 und der externe Interrupt

Gast #2513330
Lesenswert?
• ▲
▼
Hi,

bisher hatte ich keine Probleme mit Interrupts (Atmega8), aber jetzt mit 
dem  Atmega32u4 ist alles anders :) Die Register heissen hier scheinbar 
alle anders. Folgendes habe ich mithilfe des Datenblatts soweit 
zusammenbekommen, kompiliert ohne Fehler aber tut nichts.
Ich habe einen Drehgeber an PD0, der definitiv funktioniert, das habe 
ich durch blockierendes Auslesen schon nachgeprüft. Ich komme einfach 
nicht drauf, was ich vergessen bzw. überlesen haben könnte.
Hier die betreffenden Auszüge:
1
uint16_t lcount = 0;
2

3
ISR( INT0_vect ){
4
    lcount++;
5
}
6

7
main(){
8
   DDRD &= ~(1 << 0); // eingang
9
   DDRD &= ~(1 << 1); // eingang
10

11
   ...
12

13
   // sowohl steigende als auch fallende Flanken sollen auslösen
14
   EICRA &= ~(1 << ISC01);
15
   EICRA |= (1 << ISC00);
16

17
   // External interrupt mask, Interrupt 0 "einschalten"
18
   EIMSK |= (1 << INT0);
19

20
   /* Datenblatt, S. 87:
21
   * When an INT[6;3:0] bit is written to one and the I-bit in the Status 
22
   * Register (SREG) is set (one),
23
   * the corresponding external pin interrupt is enabled.
24
   * SREG: I-Bit ist 7, S. 11
25
   */
26
   SREG |= (1 << 7);
27
   sei();
28

29
   ...
30

31
   while(1){
32
      if(lcount > 1000){
33
         led_an(); // funktion existiert, schaltet LED an, geprüft
34
      }
35
   }   
36
}
Gast #2513399
Lesenswert?
• ▲
▼
Ok, hat sich erledigt.Ich dachte eigentlich, dass das auslesen von 
lcount nicht mit den interrupts kollidieren kann.
Nachdem ich jetzt aber ein cli() vor dem auslesen des Wertes mache, 
funktioniert es.
Etwas aufgeräumt nochmal der funktionierende Code:
1
int16_t lcount = 0;
2

3
ISR( INT0_vect){
4
   lcount++;
5
}
6

7
int main(){
8
   PORTD |= (1 << 0); // pullup ein
9
   PORTD |= (1 << 1); // pullup ein
10

11
   EIMSK |= (1 << INT0) | (1 << INT1); 
12
   EICRA |= (1 << ISC10) | (1 << ISC00);
13

14
   sei();
15

16
   while(1){
17
      cli(); // stoppe interrupts
18
      int16_t llcount = lcount; // speichere Wert in lokalem lcount
19
      sei(); // starte interrupts wieder
20
      if(llcount > 1000){
21
           // lcount sollte könnte noch auf 0 gesetzt werden,
22
           // um überläufe zu vermeiden!
23
           do_something();
24
      }
25
         
26
   }
27
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren