Atmega32, Taster löst Interrupt zweimal aus

Gast #3534234
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
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
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
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

Eine eigene Frage? Dieser Thread ist über 12 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.