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


von Matthias B. (Firma: DLR ___ www.dlr.de) (silverhawk84)


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.
1
 // GESCHWINDIGKEIT  
2
    if( get_key_press( 1<<KEY0 ))
3
  { speed=speed+1;
4
    led_speed=led_speed+1;
5
    if(led_speed==1) {LED_PORT = 0xFF;
6
                KEY_PORT = 0x1F;
7
              LED_PORT ^= 1<<LED0; speed=1;
8
              //  ANZEIGE  1 //
9
              ANZEIGE_PORT = 0x00;
10
              ANZEIGE_PORT ^= 1<<b;
11
              ANZEIGE_PORT ^= 1<<c;              
12
              }
13
  
14
    if(led_speed==2) {LED_PORT = 0xFF;  
15
                KEY_PORT = 0x1F;
16
              LED_PORT ^= 1<<LED0; 
17
              LED_PORT ^= 1<<LED1; 
18
              //  ANZEIGE  2 //
19
              ANZEIGE_PORT = 0x00;
20
              ANZEIGE_PORT ^= 1<<a;
21
              ANZEIGE_PORT ^= 1<<b;  
22
              KEY_PORT ^= 1<<g;
23
              ANZEIGE_PORT ^= 1<<e;               
24
              ANZEIGE_PORT ^= 1<<d;  
25
             } 
26
    if(led_speed==3) {LED_PORT = 0xFF;  
27
                KEY_PORT = 0x1F;
28
              LED_PORT ^= 1<<LED0; 
29
              LED_PORT ^= 1<<LED1; 
30
              LED_PORT ^= 1<<LED2; 
31
              //  ANZEIGE  3 //
32
              ANZEIGE_PORT = 0x00;
33
              ANZEIGE_PORT ^= 1<<a;
34
              ANZEIGE_PORT ^= 1<<b;  
35
              KEY_PORT ^= 1<<g;
36
              ANZEIGE_PORT ^= 1<<c;               
37
              ANZEIGE_PORT ^= 1<<d;  led_speed=0;              
38
             }
39
    }
40
41
//LANGSAMER VORLAUF
42
if (bit_is_clear (PIND, PD1))
43
{     OCR1A = 1800; 
44
      LED_PORT ^= 1<<LED1; 
45
     _delay_ms(10);
46
    OCR1A = 1600; 
47
    LED_PORT = 0xFF;
48
}

von PeggySue (Gast)


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?

von Matthias B. (Firma: DLR ___ www.dlr.de) (silverhawk84)


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

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


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 ;-)
1
:
2
unsigned char leds;
3
:
4
while(1) {  // Meine Vermutung
5
:
6
:
7
 // GESCHWINDIGKEIT  
8
  if( get_key_press( 1<<KEY0 ))  { 
9
    speed=speed+1;
10
    led_speed=led_speed+1;
11
    if(led_speed==4) led_speed=0;  // Überlauf --> zurücksetzen
12
    if(led_speed==1) {
13
              KEY_PORT = 0x1F;
14
              speed=1;
15
              //  ANZEIGE  1 //
16
              ANZEIGE_PORT = 0x00;
17
              ANZEIGE_PORT ^= 1<<b;
18
              ANZEIGE_PORT ^= 1<<c;              
19
    }
20
    if(led_speed==2) {
21
              KEY_PORT = 0x1F;
22
              //  ANZEIGE  2 //
23
              ANZEIGE_PORT = 0x00;
24
              ANZEIGE_PORT ^= 1<<a;
25
              ANZEIGE_PORT ^= 1<<b;  
26
              KEY_PORT ^= 1<<g;
27
              ANZEIGE_PORT ^= 1<<e;               
28
              ANZEIGE_PORT ^= 1<<d;  
29
    } 
30
    if(led_speed==3) {
31
              KEY_PORT = 0x1F;
32
              //  ANZEIGE  3 //
33
              ANZEIGE_PORT = 0x00;
34
              ANZEIGE_PORT ^= 1<<a;
35
              ANZEIGE_PORT ^= 1<<b;  
36
              KEY_PORT ^= 1<<g;
37
              ANZEIGE_PORT ^= 1<<c;               
38
              ANZEIGE_PORT ^= 1<<d;                
39
    }
40
  }
41
42
  //LANGSAMER VORLAUF
43
  if (bit_is_clear (PIND, PD1))  {  // vermutlich die Vorlauf-Taste
44
     OCR1A = 1800; 
45
     _delay_ms(10);                 // AUA, nicht in der Haupt-Schleife
46
     OCR1A = 1600; 
47
  }
48
49
  // LEDs ansteuern
50
  leds = 0;                 // Variable manipulieren
51
  if                             (led_speed==1) leds |= 1<<LED0; 
52
  if (bit_is_clear (PIND, PD1) || led_speed==2) leds |= 1<<LED1; 
53
  if                             (led_speed==3) leds |= 1<<LED2;  
54
  LED_PORT =  ~leds;        // nach Berechnung auf Port schreiben
55
:
56
:
57
} // ende while(1)
58
:

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.

von PeggySue (Gast)


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 ;-)

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


Lesenswert?

Kleine Überschneidung....
Gut, nochmal mit Pseudocode:
1
while(1) {
2
  :
3
  :
4
  // Geschwindigkeit einstellen
5
  if(Geschwindigkeitseinstellungstaste_gedrückt) { // 1 mal pro Betätigung
6
    speed++;
7
    if (speed>4) // Überlauf
8
       speed = 0;
9
  }
10
11
  if (Taster_Langsam_gedrückt) {                   // dauernd
12
     langsamfahrt = 1;
13
     :
14
     :
15
  }
16
  else {  // Taster_Langsam_losgelassen
17
     langsamfahrt = 0;
18
     :
19
  }
20
21
22
  // LEDs ansteuern
23
  leds = 0;                 // Variable manipulieren
24
  if (!langsamfahrt && speed==1) leds |= 1<<LED0; 
25
  if (langsamfahrt  || speed==2) leds |= 1<<LED1; 
26
  if (!langsamfahrt && speed==3) leds |= 1<<LED2;  
27
  LED_PORT =  ~leds;        // nach Berechnung auf Port schreiben
28
29
  // Anzeige ansteuern
30
  ANZEIGE_PORT = ... s.o.
31
}
32
:
33
:

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

von Matthias B. (Firma: DLR ___ www.dlr.de) (silverhawk84)


Lesenswert?

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

von Skeptiker (Gast)


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 ?

von Michael Wilhelm (Gast)


Lesenswert?

In Assembler erlaubt und in C verboten? Warum?

MW

von Moi (Gast)


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.

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


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

von Michael Wilhelm (Gast)


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

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.