Forum: Mikrocontroller und Digitale Elektronik Binärzähler mit Case-Anweisung


von Jakob (Gast)


Lesenswert?

Guten Morgen Experten,

ich versuche mir einen Binärzähler mit Case-Anweisung zu programmieren 
aber irgendwas mache ich falsch.

Hier mein Code:
1
#define    F_CPU 3686400
2
#include  <avr\io.h>
3
#include  <avr\delay.h>
4
5
int main (void)
6
{
7
  DDRD = 0xFF;
8
  DDRB = 0xFF;
9
  
10
  while(1)
11
  {
12
  
13
  for (int a=1 ; a<8 ; a++)
14
  
15
    {  
16
        switch(a){
17
              case 1: (PORTD = 0x10) & (PORTB = 0x00);
18
              case 2: (PORTB = 0x00) & (PORTD = 0x08);
19
              case 3: (PORTB = 0x00) & (PORTD = 0x18);
20
              case 4: (PORTB = 0x02) & (PORTD = 0x00);
21
              case 5: (PORTB = 0x02) & (PORTD = 0x08);
22
              case 6: (PORTB = 0x02) & (PORTD = 0x10);
23
              case 7: (PORTB = 0x02) & (PORTD = 0x18);
24
              default:(PORTB = 0x02) & (PORTD = 0x18);
25
              break;
26
            }
27
    _delay_ms(500);
28
    }
29
  }
30
31
return 0;
32
}

Was mache ich hier falsch?

PS: bin noch Anfänger... unnötige Kommentare können gleich erspart 
werden!

von Peter D. (peda)


Lesenswert?

break; vergessen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Jakob schrieb:
> Was mache ich hier falsch?

Vom fehlenden break abgehsehen:

Was soll da das &?


> (PORTD = 0x10) & (PORTB = 0x00);

Du meinst vermutlich
1
  case 1: 
2
    PORTD = 0x10;
3
    PORTB = 0x00;
4
    break;
5
6
  case 2: 
7
    PORTB = 0x00;
8
    PORTD = 0x08;
9
    break;

etc.

von Peter D. (peda)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Was soll da das &?

Das ist Unsinn, stört aber nicht die Funktion, da das Ergebnis verworfen 
wird (keiner lvalue zugewiesen wird).
Vermutlich wird der Compiler dafür nichtmal Code erzeugen.
Eventuell läßt er sich auch zu ner Warnung hinreißen:
warning “statement has no effect”

: Bearbeitet durch User
von Jakob (Gast)


Lesenswert?

Es lag an dem break;

Vielen Dank!

Gibt´s elegantere Lösung um so ein Zähler mit C zu programmieren?

von Peter D. (peda)


Lesenswert?

Jakob schrieb:
> Gibt´s elegantere Lösung um so ein Zähler mit C zu programmieren?

Man könnte die Bits direkt zuweisen, aber case 1 paßt dann nicht.
Sicher, daß case 1 stimmt?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Peter Dannegger schrieb:
> Das ist Unsinn

Ich weiß das, ich vermute, daß der Threadersteller so hoffte, 
mehrere Anweisungen irgendwie magisch zu einer zusammenzufassen, damit 
sie in einer Zeile behandelt werden können.

Das dürfte irgendwie vom "concatenation operator" von Basic inspiriert 
sein.

von LM317 (Gast)


Lesenswert?

Jakob schrieb:
> Was mache ich hier falsch?
Unvollständige Problembeschreibung, siehe Netiquette

von Jakob (Gast)


Lesenswert?

LM317 schrieb im Beitrag #4031330:
> Unvollständige Problembeschreibung, siehe Netiquette

Was soll hier unvollständig sein? Die anderen haben es auch bloß 
verstanden!

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


Lesenswert?

Jakob schrieb:
> LM317 schrieb:
>> Unvollständige Problembeschreibung, siehe Netiquette
> Was soll hier unvollständig sein?
Du schreibst nur, DASS du ein Problem hast. Aber nicht, WELCHES Problem 
du hast.

> Die anderen haben es auch bloß verstanden!
Ja, das sind aber auch erklärte Cracks. Und es würde Anderen durchaus 
helfen, wenn du das Fehlverhalten beschreibst. Denn dann könnte man 
diesen Thread mitsamt der Antwort irgendwann wieder mal finden...

Jakob schrieb:
> PS: bin noch Anfänger... unnötige Kommentare können gleich erspart
> werden!
Du solltest nicht allzu jungforsch auftreten und mit Ausrufezeichen im 
Befehlston um dich werfen. Das kommt manchmal nicht gut an und bewirkt 
das Gegenteil.

von LM317 (Gast)


Lesenswert?

Jakob schrieb:
> Was soll hier unvollständig sein?
Ich habe den verlinkten Artikel gelesen (zutreffendes ankreuzen):
[ ] Ja
[ ] Nein
Deine Beschreibung:
>> aber irgendwas mache ich falsch.
Vollständig wäre:
Was will ich mit dem Code erreichen?
Was macht der µC das er nicht machen sollte?

Jakob schrieb:
> Die anderen haben es auch bloß verstanden!
Wenn bei einem Switch Case das break fehlt wird man schnell misstrauisch 
und wenn das der Fehler war hat man das Problem schon gelöst ohne zu 
verstehen was du mit deinem Code überhaupt erreichen willst.

von Walter (Gast)


Lesenswert?

Jakob schrieb:
> Es lag an dem break;
>
> Vielen Dank!

kann gar nicht sein,
wie andere schon erwähnt haben ist definitiv nicht nur das break falsch

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


Lesenswert?

Walter schrieb:
> ist definitiv nicht nur das break falsch
Klar sind die verUNDeten Zuweisungen falsch, sie haben aber ausser einer 
Warnung eben auch keine negative Auswirkung. Der Optimierer schmeißt so 
unnötiges Zeug einfach weg...

BTW: auch die Schleife, die so menschenfreundlich und 
grundschulmäßig von 1 bis 8 läuft, deutet auf Verbesserungspotential 
hin.

von Jakob (Gast)


Lesenswert?

Lothar Miller schrieb:
> BTW: auch die Schleife, die so menschenfreundlich und
> grundschulmäßig von 1 bis 8 läuft, deutet auf Verbesserungspotential
> hin.

Und das wäre?

von LM317 (Gast)


Lesenswert?

Lothar Miller schrieb:
> von 1 bis 8 läuft
Nicht bis 7?

Jakob schrieb:
> Und das wäre?
Dazu müsste man erstmal wissen was du erreichen willst.

von Jakob (Gast)


Lesenswert?

LM317 schrieb im Beitrag #4031722:
> Lothar Miller schrieb:
>> von 1 bis 8 läuft
> Nicht bis 7?

a<8 ist für mich nicht 8 (<=8 wäre bis 8)

LM317 schrieb im Beitrag #4031722:
>> Und das wäre?
> Dazu müsste man erstmal wissen was du erreichen willst.

Einfach 3 LED´s im 500ms-Takt binär blinken lassen.

von Karl H. (kbuchegg)


Lesenswert?

Jakob schrieb:
> Lothar Miller schrieb:
>> BTW: auch die Schleife, die so menschenfreundlich und
>> grundschulmäßig von 1 bis 8 läuft, deutet auf Verbesserungspotential
>> hin.
>
> Und das wäre?

C Programmierer fangen bei 0 an zu zählen.

Das ebnet dann gleich auch den Weg zu einem einfacheren Programm, 
welches die auszugebenden Werte aus einem Array holt.
1
#define    F_CPU 3686400
2
#include  <avr\io.h>
3
#include  <avr\delay.h>
4
5
#define ARRAY_SIZE  8
6
7
uint8_t ValuesSmall[ARRAY_SIZE] = { 0x00, 0x08, 0x18, 0x00, 0x08, 0x10, 0x18 };
8
uint8_t ValuesLarge[ARRAY_SIZE] = { 0x10, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02 };
9
10
int main (void)
11
{
12
  uint8_t Index;
13
14
  DDRD = 0xFF;
15
  DDRB = 0xFF;
16
  
17
  while(1)
18
  {
19
    for (Index = 0; Index < ARRAY_SIZE; Index++ )
20
    {  
21
      PORTD = ValuesLarge[Index];
22
      PORTB = ValuesSmall[Index];
23
24
      _delay_ms(500);
25
    }
26
  }
27
}

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


Lesenswert?

Jakob schrieb:
> Lothar Miller schrieb:
>> BTW: auch die Schleife, die so menschenfreundlich und grundschulmäßig
>> von 1 bis 8 läuft, deutet auf Verbesserungspotential hin.
> Und das wäre?
Dass man eine solche Schleife von 0 bis 7 laufen lässt. Das machen die, 
die Erfahrung mit Programierung und Binärzahlen haben...

Jakob schrieb:
> Einfach 3 LED´s im 500ms-Takt binär blinken lassen.
Ich sehe im Programmcode aber 4 Pins, die angesteuert werden...

EDIT: Karl Heinz war schneller und ausführlicher... ;-)

: Bearbeitet durch Moderator
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

1
  for (int a = 1; a < 8; a++)
2
  {
3
      if (a & 0x01)
4
         PORTD |= 0x10;
5
      else
6
         PORTD &= ~0x10;
7
      if (a & 0x02)
8
         PORTD |= 0x08;
9
      else
10
         PORTD &= ~0x08;
11
      if (a & 0x04)
12
         PORTB |= 0x02;
13
      else
14
         PORTD &= ~0x02;
15
      _delay_ms(500);
16
    }

P.S.
Für a reicht auch ein uint8_t.
P.P.S.
Wenn ich es richtig sehe, ist da noch ein Fehler in Deinem Switch:
Für 2, 5, 7 wird D mit 0x.8 besetzt. Richtig wäre aber für 2, 4, 6.

: Bearbeitet durch Moderator
von Jakob (Gast)


Lesenswert?

Karl Heinz... Vielen Dank für die gute und ausführliche Erklärung.

von Dirk B. (dirkb2)


Lesenswert?

@Jakob

Bei dem Beispiel von Karl-Heinz si noch angmerkt, dass die letzten 
Element im Array nicht explizit gesetzt sind.
Diese werden aber automatisch auf 0 gesetzt.²
Und ob es die letzten oder ersten Werte sind, merkt man bei einer 
Endlosschleife auch nicht.

Und die ersten Werte von den Arrays sind vertauscht (weil du die in 
deinem Programm auch so seltsam angeordnet hast)

² Dies gilt aber nur bei einer Initialisierung, bei globalen und static 
Variablen

von Jakob (Gast)


Lesenswert?

Vielen Dank Dirk :)

von Karl H. (kbuchegg)


Lesenswert?

Dirk B. schrieb:
> @Jakob
>
> Bei dem Beispiel von Karl-Heinz si noch angmerkt, dass die letzten
> Element im Array nicht explizit gesetzt sind.

Kannst die Dinge ruhig beim Namen nennen :-)
Mein Array hätte eine Länge von 7 haben sollen. Keine Ahnung, wie mir da 
jetzt die 8 reingerutscht sind.

Ist aber auch kein Beinbruch
1
#define ARRAY_SIZE  7
und alles ist wieder so, wie im Eröffnungsposting

von Dirk B. (dirkb2)


Lesenswert?

Die 0 gehört doch dazu.

von Karl H. (kbuchegg)


Lesenswert?

Dirk B. schrieb:
> Die 0 gehört doch dazu.

Schon. Aber der TO hatte im Eröffnungscode nur 7 unterscheidbare Fälle. 
Das default ignorier mal. Der kommt nicht zum zug.

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.