mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Nach If-Anweisung zurück an bestimmte Stelle


Autor: Matthias Bock (Firma: DLR ___ www.dlr.de) (silverhawk84)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich möchte dass einer If anweisung ( langsamer Vorlauf ) die LEDs 
wieder den alten Zustand annehmen. Also beim langsamen Vorlauf wird LED 
1 angeschaltet und geht auch aus,wenn ich die taste loslasse. nun möchte 
ich,dass wieder die Geschwindigkeit angezeigt wird (1,2 oder 3).
Dachte ich könnte einfach eine Goto anweisung nutzen, aber das geht iwie 
nicht.
 // GESCHWINDIGKEIT  
    if( get_key_press( 1<<KEY0 ))
  { speed=speed+1;
    led_speed=led_speed+1;
    if(led_speed==1) {LED_PORT = 0xFF;
                KEY_PORT = 0x1F;
              LED_PORT ^= 1<<LED0; speed=1;
              //  ANZEIGE  1 //
              ANZEIGE_PORT = 0x00;
              ANZEIGE_PORT ^= 1<<b;
              ANZEIGE_PORT ^= 1<<c;              
              }
  
    if(led_speed==2) {LED_PORT = 0xFF;  
                KEY_PORT = 0x1F;
              LED_PORT ^= 1<<LED0; 
              LED_PORT ^= 1<<LED1; 
              //  ANZEIGE  2 //
              ANZEIGE_PORT = 0x00;
              ANZEIGE_PORT ^= 1<<a;
              ANZEIGE_PORT ^= 1<<b;  
              KEY_PORT ^= 1<<g;
              ANZEIGE_PORT ^= 1<<e;               
              ANZEIGE_PORT ^= 1<<d;  
             } 
    if(led_speed==3) {LED_PORT = 0xFF;  
                KEY_PORT = 0x1F;
              LED_PORT ^= 1<<LED0; 
              LED_PORT ^= 1<<LED1; 
              LED_PORT ^= 1<<LED2; 
              //  ANZEIGE  3 //
              ANZEIGE_PORT = 0x00;
              ANZEIGE_PORT ^= 1<<a;
              ANZEIGE_PORT ^= 1<<b;  
              KEY_PORT ^= 1<<g;
              ANZEIGE_PORT ^= 1<<c;               
              ANZEIGE_PORT ^= 1<<d;  led_speed=0;              
             }
    }

//LANGSAMER VORLAUF
if (bit_is_clear (PIND, PD1))
{     OCR1A = 1800; 
      LED_PORT ^= 1<<LED1; 
     _delay_ms(10);
    OCR1A = 1600; 
    LED_PORT = 0xFF;
}

Autor: PeggySue (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weiß nicht, ob ich dich jetzt wirklich richtig verstanden habe, aber wie 
wäre es mit einem Zustandsautomat in der Form:

switch(State)
{
   case LED_SPEED_1:
      ...
      break;
   case LED_SPEED_2:
      ...
      break;
   case LED_SPEED_3:
      ...
      break;
   case LED_LANGSAM:
      ...
      if (blabla)
      {
         State = LED_SPEED_X;
      }
      break;
}

Wenn du dies zyklisch aufrufst, dann solltest du doch das von dir 
gewünschte Verhalten erreichen. Oder?

Autor: Matthias Bock (Firma: DLR ___ www.dlr.de) (silverhawk84)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also eigentlich möchte ich, dass wenn ich die taste für langsamen 
vorlauf loslasse, wieder die LEDs leuchten, je nachdem welchen speed ich 
gerad hab.
bsp:
geschwindigkeit 3 gewählt --> 3leds leuchten
taster für langsamen vorlauf gedrückt: --> nur eine leuchtet
taster loslassen
und nun sollen wieder die 3 leds leuchten.

hoffe das ging jetzt von der erklärung her ^^

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du solltest die Eingabe, die Anzeige und die Geschwindigkeitseinstellung 
entkoppeln. Alles in einer (1) if-Abfrage zu machen bringt dich früher 
oder später an den Rande eines GOTOs...

Ich vermute mal, das Ganze läuft in der Hauptschleife zyklisch ab.
(wenn nicht, solltest du den Programmierstil ändern ;-)
:
unsigned char leds;
:
while(1) {  // Meine Vermutung
:
:
 // GESCHWINDIGKEIT  
  if( get_key_press( 1<<KEY0 ))  { 
    speed=speed+1;
    led_speed=led_speed+1;
    if(led_speed==4) led_speed=0;  // Überlauf --> zurücksetzen
    if(led_speed==1) {
              KEY_PORT = 0x1F;
              speed=1;
              //  ANZEIGE  1 //
              ANZEIGE_PORT = 0x00;
              ANZEIGE_PORT ^= 1<<b;
              ANZEIGE_PORT ^= 1<<c;              
    }
    if(led_speed==2) {
              KEY_PORT = 0x1F;
              //  ANZEIGE  2 //
              ANZEIGE_PORT = 0x00;
              ANZEIGE_PORT ^= 1<<a;
              ANZEIGE_PORT ^= 1<<b;  
              KEY_PORT ^= 1<<g;
              ANZEIGE_PORT ^= 1<<e;               
              ANZEIGE_PORT ^= 1<<d;  
    } 
    if(led_speed==3) {
              KEY_PORT = 0x1F;
              //  ANZEIGE  3 //
              ANZEIGE_PORT = 0x00;
              ANZEIGE_PORT ^= 1<<a;
              ANZEIGE_PORT ^= 1<<b;  
              KEY_PORT ^= 1<<g;
              ANZEIGE_PORT ^= 1<<c;               
              ANZEIGE_PORT ^= 1<<d;                
    }
  }

  //LANGSAMER VORLAUF
  if (bit_is_clear (PIND, PD1))  {  // vermutlich die Vorlauf-Taste
     OCR1A = 1800; 
     _delay_ms(10);                 // AUA, nicht in der Haupt-Schleife
     OCR1A = 1600; 
  }

  // LEDs ansteuern
  leds = 0;                 // Variable manipulieren
  if                             (led_speed==1) leds |= 1<<LED0; 
  if (bit_is_clear (PIND, PD1) || led_speed==2) leds |= 1<<LED1; 
  if                             (led_speed==3) leds |= 1<<LED2;  
  LED_PORT =  ~leds;        // nach Berechnung auf Port schreiben
:
:
} // ende while(1)
:

Warum schreibst du eigentlich überall xxx_PORT, da bricht mir ja das 
Augenlicht...

BTW:
speed  und  led_speed  scheinen mir irgendwie ähnlich...

Fazit: eigentlich willst ud die Geschwindigkeit einstellen. Punkt.
Und später irgendwie irgendwo anzeigen. Dann schreib das Programm so, 
dass die Geschwindigkeiteinstellung klappt (vermutlich speed) und leite 
die Anzeige daraus ab.

Autor: PeggySue (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahja... nungut... neuer Versuch:

switch(State)
{
   case SPEED_1:
      LED1 = ON;
      if (Taster_Langsam_gedrückt)
      {
         LEDsOff();
         Merker = State;
         State = SPEED_LANGSAM;
      }
      break;
   case SPEED_2:
      LED1 = ON;
      LED2 = ON;
      if (Taster_Langsam_gedrückt)
      {
         LEDsOff();
         Merker = State;
         State = SPEED_LANGSAM;
      }
      break;
   case SPEED_3:
      LED1 = ON;
      LED2 = ON;
      LED3 = ON;
      if (Taster_Langsam_gedrückt)
      {
         LEDsOff();
         Merker = State;
         State = SPEED_LANGSAM;
      }
      break;
   case SPEED_LANGSAM:
      ...
      if (Taster_Langsam_losgelassen)
      {
         State = Merker;
      }
      break;
}

Ist jetzt nur Pseudocode, aber ich hoffe du verstehst, was ich damit 
meine. So sollte es eigentlich funktionieren. Ist vermutlich nicht die 
schönste Lösung und es läßt sich sicherlich noch was daran optimieren, 
aber vom Prinzip her sollte es so wie beschrieben gehn.

Und nun hoffe ich, dass ich dich diesmal richtig verstanden habe und 
keinen Denkfehler drin habe ;-)

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kleine Überschneidung....
Gut, nochmal mit Pseudocode:
while(1) {
  :
  :
  // Geschwindigkeit einstellen
  if(Geschwindigkeitseinstellungstaste_gedrückt) { // 1 mal pro Betätigung
    speed++;
    if (speed>4) // Überlauf
       speed = 0;
  }

  if (Taster_Langsam_gedrückt) {                   // dauernd
     langsamfahrt = 1;
     :
     :
  }
  else {  // Taster_Langsam_losgelassen
     langsamfahrt = 0;
     :
  }


  // LEDs ansteuern
  leds = 0;                 // Variable manipulieren
  if (!langsamfahrt && speed==1) leds |= 1<<LED0; 
  if (langsamfahrt  || speed==2) leds |= 1<<LED1; 
  if (!langsamfahrt && speed==3) leds |= 1<<LED2;  
  LED_PORT =  ~leds;        // nach Berechnung auf Port schreiben

  // Anzeige ansteuern
  ANZEIGE_PORT = ... s.o.
}
:
:

Ein variabler Shift wie
>  ANZEIGE_PORT ^= 1<<d;
ist übrigens extrem rechenaufwendig. Das geht sicher einfacher.

Autor: Matthias Bock (Firma: DLR ___ www.dlr.de) (silverhawk84)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oki, vielen dank für die ganzen hilfen!
daraus kann ich sicherlich was bauen ;)

Autor: Skeptiker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Matthias Bock

Der Namenszusatz "Firma DLR _ www.dlr.de" läßt mich vermuten, daß 
demnächst mal wieder ein Spacelab oder so vom Himmel fällt, weil 
IF-Abfragen mit GOTO verhuddelt werden

IF außenschott_geschlossen
   THEN IF solarsegel_angeklappt
      THEN IF noch_irgendwas
THEN GOTO open_außenschott

ich dachte, daß mit dem GOTO ist seit Erfindung der strukturierten 
Programmierung (so ca. 1965) überflüssig ?

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In Assembler erlaubt und in C verboten? Warum?

MW

Autor: Moi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weil C eine Hochsprache ist und dementsprechend die eigentliche Tatsache 
abstraktieren soll.
Es ist halt übersichtlicher ohne Goto.

In c kann man quasi 2 Dimensional programmieren. In asm nur 1 
Dimensional.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>In Assembler erlaubt und in C verboten?
Klar ist ein GOTO in C erlaubt.

Es ist auch erlaubt, ausserhalb geschlossener Ortschaften zu Hupen,
um seine Überholabsicht anzuzeigen, aber MAN TUT SOWAS NICHT,
weil/wenn es nicht unbedingt nötig ist.

@ Skeptiker
Wenigstens traut Matthias sich, seinen Namen anzugeben... ;-)

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>In Assembler erlaubt und in C verboten?
>Klar ist ein GOTO in C erlaubt.

Hab mich falsch ausgedrückt. Sollte heißen verpönt.

MW

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.