Problem Interrupt

Gast #4472378
Hey Guys,

ich hab ein Problem mit der ISR

while(marker)
{
   CODE
   PINX ((PINX & (Taster))==0)
   marker = 0; Goto(1);
}

ISR
{marker = 1;}

Nun möchte ich das ich mit dem selben Taster mit dem ich den Interrupt 
betätige wieder raus kommen aus der while Schleife.
Wie ist dies möglich ?
Gast
Ist das so etwas wie virtueller Code?

Welcher Comtroller - Compiler etc. wird verwendet ?

Besser ist es ein richtiges um komplettes Programm mit der Fragestellung 
zu posten.
Gast
AVR 328
Atmel Studio

1
      while(menuMark)
2
      {
3
            lcd_clear();
4
            WeckerMenu();
5
            if (WeckerH == 24) WeckerH = 0;
6
            if (WeckerM == 60) WeckerM = 0;
7
            zeit(150);
8
            if ((PINC & (1<<ChooseVariable))==0) vari++;
9
            zeit(150);
10
            if (vari==0)
11
            {
12
              if ((PINC & (1<<ZeitverstellenPLUS))==0) WeckerH++;
13
              if ((PINC & (1<<ZeitverstellenMINUS))==0) WeckerH--;
14
            }
15
            else
16
            zeit(150);
17
            {
18
              if ((PINC & (1<<ZeitverstellenPLUS))==0) WeckerM++;
19
              if ((PINC & (1<<ZeitverstellenMINUS))==0) WeckerM--;
20
            }
21
            zeit(150);
22
            if (vari==2) vari=0;
23
            zeit(150);
24
            if ((PINC & (1<<Menu_Taster))==0) {menuMarker = 0; goto(1);}
25
      }
26

27
ISR(PCINT1_vect) // Interrupt Service Routine
28
{
29
  menuMark = 1;
30
}

Rest funktioniert des Progamms
Gast
ich denke es wird zeit das Programm komplett zu sehen, in einer ISR zu 
warten ist eine ganz schlechte Idee. Auch das
1
goto(1);

finde ich sehr bedenktlich, hast du eine Funktion mit dem namen goto?
Gast
was heißt goto eigentlich gotocase(1)...

Warte routinen sind zum einlesen der Taster das nicht mit einem 
Tastendruck 30 mal nach oben gezählt wird.


Rest des Programmes ist relativ irrelevant weil dies nichts mit dem 
Problem zu tun hat
Gast
Hallo,

Bei mir meckert der gcc an den Stellen, wo wir die Funktiondeklaraion 
und Variablen nicht kennen.

Was soll da genau passieren, in deinen Augen ?
Üblicherweise merkst du dir dazu in einem Flag, ob du gerade drin oder 
draußen bist. Bei dem gezeigten Code ist allerdings "üblicherweise" 
eventuell nicht der passende Ansatz.

Die Meinung deines Compilers zu goto(1) würd mich allerdings schon 
interessieren.

Oliver
Gast
int Phase_;
int vari = 0;
int menuMark = 0;
int clockMark = 0;

#define Menu_Taster PC0
#define ZeitverstellenPLUS PC1
#define ZeitverstellenMINUS PC2
#define ChooseVariable PC3
#define TurnClockoff PC4
#define Menu_Uhr PB5

Er sollte eigentlich aus dem Menü raus gehen, aber anstatt geht er nur 
raus wenn der Taster gedrückt wird, sprich die ISR setzt die variable 
dauerhaft 1 per Tastendruck und die 0 aus dem case wird ignoriert.
Gast
Dietrich L. schrieb:
> Ernst schrieb:
>
>> while(menuMark)
>                 ^^
>
>> if ((PINC & (1<<Menu_Taster))==0) {menuMarker = 0; goto(1);}
>                                              ^^
> Ist das auch so programmiert oder ist das hier nur ein Schreibfehler?
>
> Gruß Dietrich

Hab mehrfach rum probiert deshalb war der Code bisschen anderes und 
menuMarker wurde manuell eingefügt aber im Ursprung war es gleich
Gast
Peter II schrieb:
> Ernst schrieb:
>> die 0 aus dem case wird ignoriert.
>
> welchem case? Ich code steht kein case.

Ist alles im switch programmiert.
Im case war damit gemeint in dem oberen Programmteil..

Wie gesagt der rest ist irrelevant...
Ernst schrieb:
> Ist alles im switch programmiert.
> Im case war damit gemeint in dem oberen Programmteil..

So wird das nichts. Du musst den kompletten und aktuellen Code zeigen, 
der den Fehler hat.

> Wie gesagt der rest ist irrelevant...

Bei Fehlersuche darf man nie davon ausgehen, man muss an allem 
zweifeln.

Ernst schrieb:
> Zum zweiten Mal

Das habe ich übersehen :-(

> int menuMark = 0;
>
> Wofür genau volatile?

Damit die Variable innerhalb und außerhalb der ISR gültig ist.

Gruß Dietrich
(Firma: Vescomp)
Ernst schrieb:
> Naja wie auch immer die Frage ist ja, wie ich den Taster für beides
> benutzen beenden und starten des Interrupts während der while Schleife

 Taster löst Interrupt aus.
 Interrupt toggelt einen Flag - nicht mehr und nicht weniger.
 In main() wird der Flag geprüft und das ist auch alles.

 Flag als volatile deklarieren.
So wird das nichts.
Statt den Taster an einen Interrupt-Pin zu hängen, verwendest Du besser 
einen Timer-Interrupt, der alle paar ms ALLE Taster abfragt, das 
Entprellen übernimmt und die Tastendrücke entweder in einer volatile 
Variable oder besser noch in einem Fifo an main() weitergibt.
1
  char myKey = getKey(); // read key from fifo
2

3
  switch(myKey)
4
  {
5
    case keyEnterMenuPressed:
6
      menuMarker = 1;
7
      ...   / do your stuff to enter menu
8
      break;
9

10
    case keyEnterMenuReleased:
11
      menuMarker = 0;
12
      ... // do your stuff to exit menu
13
      break;
14

15
    case keyChooseVariablePressed:
16
      if (menuMarker == 1)
17
      {
18
        ....
19
      }
20
      break;
21

22
    case keyzeitVerstellenPressed:
23
      if (menuMarker == 1)
24
      {
25
        ....
26
      }
27
      break;
28
  }
Mit einer Timer-ISR kannst Du bei Bedarf nicht nur keyPressed sondern 
auch keyReleased Signale auswerten und an main() weiterleiten.

Vorteile:
* Du wertest Deine Tasten an EINER Stelle aus und nicht verstreut im
  Programm. Das erleichtert das Testen (was ist das?).
* Alle Tasten werden entprellt.
* Wenn main() mal ein paar ms beschäftigt ist (Graphik-Ausgabe, etc.),
  kann trotzdem kein tastendruck verlorengehen.
* ...

Wie man Tasten im Timer-ISR entprellt, findest Du hier an mehreren 
Stellen.

Gruß, Stefan
Dann nimm es so:
1
    case keyEnterMenuPressed:
2
      if (menuMarker == 0)
3
      {
4
        menuMarker = 1;
5
        ...   / do your stuff to enter menu
6
      }
7
      else
8
      {
9
        menuMarker = 0;
10
        ... // do your stuff to exit menu
11
      }
12
      break;

Was ich oben zeigen wollte:
* Entprellen ist essentiell.
* Klare Verteilung: ISR konvertiert Pin-Signale zu Tastenkommandos und
  main()steuert mit den Tastenkommandos das Menu, etc.
* Je nach Aufwand in der Timer-ISR lassen sich unterschiedliche
  Tastenkommandos generieren: pressed, released, longPressed... main() 
kann
  diese auswerten, muss das aber nicht.

Antwort schreiben

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