Forum: Compiler & IDEs 4x8 Bit Variable


von TobyTetzi (Gast)


Lesenswert?

Hallo,

ich habe mal wieder ein Brett vorm Kopf!

Mein Code:

unsigned char Lauflicht1 = 1;
unsigned char Lauflicht2 = 0;
unsigned char Lauflicht3 = 0;
unsigned char Lauflicht4 = 0;

...

Lauflicht1 = lauflicht1 << 1;
   If ( Lauflicht1 == 0x00 )
   {
   Lauftlicht2 = 1;
   }

Jetzt soll Lauflicht2 diese Funktion ausführen:
Lauflicht2 = Lauflicht2 <<1;
   If ( Lauflicht2 == 0x00 )
   {
   Lauftlicht3 = 1;
   }

usw.

Habe mit If Schleifen schon alles Mögliche versucht, aber entweder
blieb Lauflicht2 bei 0b00000001 stehen,
oder bei 0b00000010 stehen.

Kann mir jemand weiter helfen?

Danke im vorraus!

Gruß Toby

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>If Schleifen

Wo kann man die kaufen?

for(Lauflicht1=1;Lauflicht1<=128;Lauflicht1*=2);
for(Lauflicht2=1;Lauflicht2<=128;Lauflicht3*=2);
for(Lauflicht3=1;Lauflicht3<=128;Lauflicht3*=2);

und wo ist das Problem?
Genau: If ist eine Abfrage, und was du brauchst sind Schleifen.

von TobyTetzi (Gast)


Lesenswert?

Hallo und Danke!

Ich sagte ja, ich habe ein Brett vorm Kopf.

Allerdings habe ich vergessen zu sagen,
das ich das Schieben in einem Timer Int mache.
Also pro Timer Overflow ein mal schieben.

Da hilft mir die Schleife nicht wirklich weiter, oder?

Gruß Toby

von Karl heinz B. (kbucheg)


Lesenswert?

denn merke:
Nicht jedes Konstrukt in dem { und } vorkommen sind Schleifen!

Des Wesen, ja das Charakteristikum, einer Schleife ist es,
dass Anweisungen immer wieder wiederholt werden. Dieses
Wiederholen kann man an eine Bedingung knüpfen.

Bei einem if wird nichts wiederholt.
Ein if prüft einfach nur eine Bedingung und führt eine von
2 Möglichkeiten aus, je nachdem was die Bedingung ergeben hat.

von inoffizieller WM-Rahul (Gast)


Lesenswert?

lauflicht1=1;

ISR(Timerblabla)
{
  if (!lauflicht1)
     lauflicht1*=2;
  else if (!lauflicht2)
         lauflicht2*=2;
  else if(!lauflicht3)
         lauflicht3*=2;
  else lauflicht1=1;
}

von Karl heinz B. (kbucheg)


Lesenswert?

> Da hilft mir die Schleife nicht wirklich weiter, oder?

Nein. In dem Fall hilft dir ein Schleifenkonstukt nichts.

Ich empfehle dir mal, deinen Code im Simulator vom AVR-Studio
zu simulieren. Da sieht man nämlich sehr shön was abgeht:

Zuerst wird die 1 in Lauflicht1 schön durchgeschoben. Irgendwann
fällt das Bit dann links aus Lauflicht1 heraus. Als Konsequenz
davon wird dann Lauflicht2 auf 1 gesetzt.
Aber was passiert beim nächsten Interrupt?
Nun, Lauflicht1 ist immer noch 0, daher wird Lauflicht2 schon
wieder auf 1 gesetzt.
Und beim nächsten Interrupt?
Lauflicht 1 hat seinen Wert von 0 immer noch nicht verändert,
daher wird Lauflicht2 schon wieder auf 1 gesetzt.

Wie gesagt: Benutze den AVR-Studio Simulator, da sieht man das
wunderbar.

von Karl heinz B. (kbucheg)


Lesenswert?

> lauflicht1=1;
>
> ISR(Timerblabla)
> {
>   if (!lauflicht1)
>     lauflicht1*=2;
>  else if (!lauflicht2)
>         lauflicht2*=2;
>  else if(!lauflicht3)
>         lauflicht3*=2;
>  else lauflicht1=1;
> }

Nicht wirklich.
lauflicht1 startet mit 1. D.h. !lauflicht1 ergibt schon mal
FALSE

von inoffizieller WM-Rahul (Gast)


Lesenswert?

stimmt... man spare sich also die "!"...
lauflicht1=1;

ISR(Timerblabla)
{
  if (lauflicht1)
     lauflicht1*=2;
  else if (lauflicht2)
         lauflicht2*=2;
  else if(lauflicht3)
         lauflicht3*=2;
  else lauflicht1=1;
}

und dann gibt es noch das Problem, dass lauflicht2 und lauflicht3 zu
anfang 0 sind.
Man braucht also noch eine Variable mehr, die sich darum kümmert,
welches Byte weitergeschoben werden muß.
Oder so:
ISR(Timerblabla)
{
  if (lauflicht1)
  {
     lauflicht1*=2;
     if (!lauflicht1) lauflich2=1;
   }
  else if (lauflicht2)
        {
         lauflicht2*=2;
         if (!lauflicht2) lauflich3=1;
        }
  else if(lauflicht3)
         lauflicht3*=2;
  else lauflicht1=1;
}

von Karl heinz B. (kbucheg)


Lesenswert?

Yep.
So gehts.

Ich würde aber trotzdem eine Hilfsvariable nehmen. Macht
man auch in Assembler so. Dort spielt das Carry-Bit die
Rolle der Hilfsvariablen.

Grund: Das verallgemeinert besser. In der jetzigen Form
kann man nur 1 Bit umlaufen lassen. Wenn ich aber das
Äquivalent vom Carry in C nachbaue, dann kann ich damit
beliebige Muster umlaufen lassen.

von Karl heinz B. (kbucheg)


Lesenswert?

In Code:

  unsigned char Carry1, Carry2;

  Carry1 = ( lauflicht1 > 127 );
  lauflicht1 *= 2;

  Carry2 = ( lauflicht2 > 127 );
  lauflicht2 = ( lauflicht2 * 2 ) | Carry1;

  Carry1 = ( lauflicht3 > 127 );
  lauflicht3 = ( lauflicht3 * 2 ) | Carry2;

  lauflicht1 |= Carry1;

von inoffizieller WM-Rahul (Gast)


Lesenswert?

hübsch!
Man könnte fast sagen: eine Peter-Dannegger-Lösung. Er "rechnet" ja
auch lieber, als einen Vergleich zu machen. (ist auf keinen Fall
negativ gemeint!)

von Tobias Tetzlaff (Gast)


Lesenswert?

Hallo,

ich hatte schon mal nachgefragt, wie ich ein Lauflicht realisieren kann.

Nun hab ich den beitrag wieder gefunden, sorry wegen dem doppelten 
Eintrag!

Ich habe 2(4) 8Bit Schieberegister, auf denen ich eine LED "wandern" 
lassen will.

Mit diesem Code geht es in eine Richtung:

char lauflicht1 = 0x01;
char lauflicht2 = 0x00;

Carry1 = ( lauflicht1 > 127 );
  lauflicht1 *= 2;

  Carry2 = ( lauflicht2 > 127 );
  lauflicht2 = ( lauflicht2 * 2 ) | Carry1;

    lauflicht1 |= Carry2;

...
...
Ausgabe auf Schieberegister.

Nun meine Frage:

Wenn lauflicht2 den wert 0x80 hat, also die letzte LED leuchtet,
wie bekomme ich es hin, das das Lauflicht andersrum läuft, bis 
lauflicht1 den Wert 0x01 hat ???
Von hier aus soll es wieder von vorn beginnen.

Danke im Vorraus...

Gruß Toby

von Peter D. (peda)


Lesenswert?

Einfach von hinten angfangen:
1
lauflicht3 += lauflicht3 + (lauflicht2 >> 7);
2
lauflicht2 += lauflicht2 + (lauflicht1 >> 7);
3
lauflicht1 += lauflicht1 + (lauflicht0 >> 7);
4
lauflicht0 += lauflicht0;


Peter

P.S.:
Du kannst aber auch einfach ne union aus nem long und 4 chars nehmen.

von Peter D. (peda)


Lesenswert?

inoffizieller WM-Rahul wrote:

> Man könnte fast sagen: eine Peter-Dannegger-Lösung. Er "rechnet" ja
> auch lieber, als einen Vergleich zu machen.

Ja, ein Rechen kostet im günstigsten Fall nur einen Zyklus.

Ein IF besteht aber in der Regel mindestens aus Test + conditional Jump 
+ Operation, also >=3 Zyklen.


Peter


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.