Forum: Mikrocontroller und Digitale Elektronik Problem Interrupt


von Ernst (Gast)


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 ?

von Karl M. (Gast)


Lesenswert?

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.

von Ernst (Gast)


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

von Peter II (Gast)


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?

von Ernst (Gast)


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

von Ernst (Gast)


Lesenswert?

Geht ledglich um eine Möglichkeit den Interrupt mit dem selben Taster 
wieder auszuschalten

von Dietrich L. (dietrichl)


Lesenswert?

Wie ist "menuMark" deklariert?
Hinweis: Du brachst "volatile".

von Karl M. (Gast)


Lesenswert?

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 ?

von Oliver S. (oliverso)


Lesenswert?

Ü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

von Dietrich L. (dietrichl)


Lesenswert?

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

von Ernst (Gast)


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.

von Ernst (Gast)


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

von Peter II (Gast)


Lesenswert?

Ernst schrieb:
> die 0 aus dem case wird ignoriert.

welchem case? Ich code steht kein case.

von Ernst (Gast)


Lesenswert?

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...

von Dietrich L. (dietrichl)


Lesenswert?

Dietrich L. schrieb:
> Wie ist "menuMark" deklariert?

Dazu fehlt noch Deine Antwort.

> Hinweis: Du brachst "volatile".

Gruß Dietrich

von Ernst (Gast)


Lesenswert?

Dietrich L. schrieb:
> Dietrich L. schrieb:
>> Wie ist "menuMark" deklariert?
>
> Dazu fehlt noch Deine Antwort.
>
>> Hinweis: Du brachst "volatile".
>
> Gruß Dietrich

Zum zweiten Mal
int menuMark = 0;

Wofür genau volatile?

von Dietrich L. (dietrichl)


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

von Dietrich L. (dietrichl)


Lesenswert?


von Ernst (Gast)


Lesenswert?

Hier der komplette Code in der C Datei

http://www.file-upload.net/download-11315566/Clock.c.html

von Dietrich L. (dietrichl)


Lesenswert?

Ernst schrieb:
> Hier der komplette Code in der C Datei
>
> http://www.file-upload.net/download-11315566/Clock.c.html

Man das lieber als Dateianhang hier im Forum. Das ist für die Leser 
einfacher und sicherer.

von Ernst (Gast)


Lesenswert?

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

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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.

von Karl M. (Gast)


Lesenswert?

Hallo Betreuer,

bitte erklärt Ernst
wie er mit ISR(PCINT1_vect) - level interrupt umgehen muss.
Ich will mich nun nicht weiter einmischen.

von Stefan K. (stefan64)


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

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Stefan K. schrieb:
> case keyEnterMenuPressed:
>     case keyEnterMenuReleased:

 Hmmm...

von Stefan K. (stefan64)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.