Forum: Mikrocontroller und Digitale Elektronik Zwei Programme/Funktionen umschalten mit einem Taster


von Lars M. (larsmie)


Lesenswert?

Hallo leute, ich bräuchte mal eure Hilfe zu folgendem Problem, ich komme 
da gedanklich gerade nicht weiter:

Ich habe in meinem uC ein Programm mit zwei Funktionen, zwischen diesen 
möchte ich gerne mit einem Taster umschalten.

Das Umschallten an sich stellt kein Problem dar, eine kleine 
debounce-routine für den Taster habe ich in einem Timer-Interrupt 
realisiert, der alle 13,6ms aufgerufen wird:

ISR(TIM0_OVF_vect)
{
   // Wenn Taster nach 13ms weiterhin gedrückt, dann Flag für gedrückten
   // Taster setzen ("Taster ist gedrückt

        if(!(PINB & (1<<PINB2)) && (taster_flag == 1))
  {
    taster_gedr = 1;
  }
  else
  {
    taster_gedr = 0;
    taster_flag = 0;
  }

  // Wenn Taster gedrückt, dann flag setzen

  if(!(PINB & (1<<PINB2)))
  {
    taster_flag = 1;
  }
}


In der Main-Schleife möchte ich nun mit dem Flag "taster_gedr" zwischen 
den Programmen umschalten.
Das Problem stellt sich insofern dar, die beiden Programme während der 
gedrückten Taste gegeneinander abzuriegeln, d.h. bei meiner Lösung 
schalten sich die Programme ständig um solange die Taste gedrückt ist. 
Es ist also ein Glücksspiel, wie bei einer nicht Entprellten Taste, das 
andere Programm zu erwischen.

Hier mal der Teil zum Umschalten im Hauptprogramm:

if((taster_gedr == 1) && (prognr == 1))
  {
    prognr = 2;
    taster_gedr = 0;
  }
else if((taster_gedr ==1) && (prognr == 2))
  {
    prognr = 1;
    taster_gedr = 0;
  }


Die Lösung ist ziemlich trivial, das weiss ich selber, nur komme ich 
grad nicht auf eine solche. Es würde eigentlich reichen, eine Flag im 
Hauptprogramm zu setzen, die es ausschließen würde, dass in der ISR die 
taster_gedr Flag wieder auf 1 gesetzt wird, solange der Taster gedrückt 
ist.

Wäre über Hilfe sehr dankbar!

Falls der komplette Code nötig ist, bitte bescheid geben!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Lars M. schrieb:
> d.h. bei meiner Lösung schalten sich die Programme ständig um solange
> die Taste gedrückt ist.
Du brauchst eine Flankenerkennung: merke dir in der Hauptschleife den 
Zustand des Tasters. Wenn der eingelesene Zustand (so einen Taster musst 
du übrigens nicht in einem Interrupt einlesen, das ist sogar eine ganz 
schlecht Idee) ungleich dem "alten" Zustand ist, dann hattest du eine 
Betätigungsflanke. Un dauf die hin schaltest du deine "Programmvariable" 
um:
1
int altetaste = 0;
2
int programm = 0;
3
4
{
5
// hauptschleife ...
6
   if (taste!=altetaste) { // Flanke erkannt?
7
      if (taste) {         // steigende Flanke?
8
        programm++;        // unterstes Bit toggeln
9
      }
10
      altetaste=taste;     // für nächsten Zyklus merken
11
   }
12
13
14
   if (programm&0x01) { // Programmnummer ungerade?
15
     // "Programm 1"
16
   }
17
   else {               // Programmnummer gerade
18
     // "Programm 2"
19
   }
20
}

: Bearbeitet durch Moderator
von Lars M. (larsmie)


Lesenswert?

Danke für deinenn Tipp, ich habe es jetzt so gelöst (5min. vor der 
Kaffemaschine haben geholfen ;-))
1
if(!(PINB & (1<<PINB2)) && (taster_gedr == 1) && (sperr == 0))
2
     {
3
       PORTB ^= (1<<PB3);
4
       taster_gedr = 0;
5
       tast_timeout++;
6
       sperr = 1;
7
    }
8
    else if((PINB & (1<<PINB2)) && (sperr == 1))
9
    {
10
      sperr = 0;
11
    }

Das ist jetzt testweise um eine LED ein und auszuschalten, aber sollte 
auch für andere Programme funktionieren.

Eine frage zum Entprellen:

Warum nicht in einem Timer-Interrupt? Bei der Methode vom Peter 
Dannegger ist die Entprellung doch auch in eine ISR ausgelagert, die 
Pin-Status Abfrage an sich ist in den Funktionen im Hauptprogramm. (Habe 
das prozedere mit dem Register-Auslesen ct0,ct1,i jetzt auch zu 90% 
verstanden).

Leigt es an den Registerzugriffen? Diese kann man ja zuerst in temporäre 
Variablen innerhalb der ISR kopieren und dann wieder zurückschreiben. 
Habe gelesen, das soll weniger Zeitintensiv sein.
Oder liegt es an etwas anderem?


Noch eine Frage:

Wie hast du den Quellcode farblich so hinbekommen? welche Klammern und 
befehle muss ich dafür setzen?

Edit: Ok habs gefunden :)

: Bearbeitet durch User
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.