Problem Interrupt

Gast #4472378
Lesenswert?

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 #4472387
Lesenswert?

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 #4472391
Lesenswert?

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 #4472394
Lesenswert?

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 #4472407
Lesenswert?

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 #4472410
Lesenswert?

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
#4472424
Lesenswert?

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
#4472502
Lesenswert?

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
#4472700
Lesenswert?

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

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