Atmega32, Taster löst Interrupt zweimal aus

Gast #3534234
Lesenswert?

Hi,

ich habe mir vor etwa einem Jahr einen LED-Cube nach einer Anleitung 
gebastelt, wobei ich damals aber noch keine Ahnung von Mikrocontrollern 
hatte - der Code war bei der Anleitung dabei. Mittlerweile habe ich mich 
etwas in die Welt der Mikrocontroller eingearbeitet und verstehe 
immerhin den bestehenden Code. Jetzt wollte ich ihn so abändern, dass 
ich per Knopfdruck immer einen Effekt weiterschalten kann. Also einen 
Taster an den INT1 gehängt mit folgendem Code:
1
volatile unsigned char current_effect = 0;
2
volatile unsigned char effects_mode = 2;
3

4
ISR(INT1_vect)
5
{
6
  if (effects_mode == 2) {
7
    delay_ms(1000);
8
    ++current_effect;
9
    if (current_effect >= EFFECTS_TOTAL) current_effect = 0;
10
  }
11
}

Vorher kommt natürlich noch beim Initialisieren:
1
GICR |= (1 << INT1);
2
MCUCR |= (1 << ISC11);

delay_ms() hat zwar ms im Namen, sind aber keine Millisekunden. Wurde 
aber vom Autor des Codes aus mir unbekannten Gründen so genannt. 1000 
entspricht eher 200 ms. Die Funktion rufe ich natürlich auf, weil der 
Taster wie blöd prellt. Habe auch noch ein kleines RC-Glied (1kR, 10nF) 
zwischen Taster und Atmega gesetzt.

Das Problem ist jetzt, dass current_effect immer um 2 erhöht wird, statt 
um 1. Ich denke nicht, dass es an Schwingvorgängen am Taster liegt, da 
ich auch schon delay_ms(5000) ausprobiert habe mit demselben Ergebnis.

Ich hoffe ihr könnt mir da irgendwie weiterhelfen. Falls das zu wenig 
Code ist, einfach sagen - es ist genug für alle da. ;-)


Grüße,
Marc
Gast #3534250
Lesenswert?

Delay Funktionen sind an sich schon blöd, die bewirken nur, dass der µC 
für die Wartezeit maximal Strom aufnimmt und überhaupt nicht mehr 
reagiert.

In Interrupts haben Delays garnichts zu suchen!

Taster fragt man einfach in der Hauptschleife zyklisch ab, gegen das 
Prellen lässt man einen Zähler mitlaufen.
Taster betätigt -> Zähler plus 1
Taster nicht betätigt -> wenn Zähler grösser Null, Zähler Minus 1
Zähler grösser Schwellwert -> Taster gilt als betätigt
#3534281
Lesenswert?

Das wait bringt in dem Fall halt reichlich wenig, da das Flag im ISR 
trotzdem gesetzt wird wenn der Interrupt getriggert wird.

Hier passiert jetzt Folgendes:
Der erste Interrupt vom prellende Taster kommt, die Interrupt-Routine 
wird aufgerufen und das Flag im ISR wieder 0 gesetzt.
Während die Interrupt-Routine jetzt abgearbeitet wird, kommt das nächste 
Impuls vom prellenden Taster und das Flag im ISR wird wieder auf 1 
gesetzt.
Wenn der µC jetzt mit der Abarbeitung fertig ist, "bemerkt" er, dass da 
ja schon wieder eine 1 im ISR stellt und ruft die Interrupt-Routine 
erneut auf...
Gast #3534304
Lesenswert?

Danke, für die schnellen Antworten. Ich habe mal versucht Rudolphs 
Prinzip zu verfolgen, also weg vom externen Interrupt. Mein Hauptproblem 
ist, dass die Hauptschleife ziemlich langsam ist. Sie ruft nur eine 
Funktion auf, die einen neuen Effekt erzeugt, wartet bis dieser vorbei 
ist (mehrere Sekunden) und startet dann wieder einen neuen. Allerdings 
läuft nebenbei noch ein Timer-Interrupt, der die Daten an den Cube 
sendet (ca. 10k interrupts pro Sekunde). Habe mal versucht das Ganze 
dort zu implementieren:
1
char ncount = 0;
2
  
3
if (effects_mode == 2) {
4
  if (!(PIND & RS232_BTN)) ++ncount;
5
  else {
6
    if (ncount > 0) --ncount;
7
    }
8

9
  if (ncount > 100) {
10
    ++current_effect;
11
    ncount = 0;
12
    }
13
  if (current_effect >= EFFECTS_TOTAL) current_effect = 0;
14
}

Leider schaltet er jetzt nicht mehr auf andere Effekte um. Woran könnte 
das liegen?


Grüße,
Marc

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