www.mikrocontroller.net

Forum: Compiler & IDEs 4x8 Bit Variable


Autor: TobyTetzi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: TobyTetzi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
lauflicht1=1;

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

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;
}

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht 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;

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!)

Autor: Tobias Tetzlaff (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Einfach von hinten angfangen:
lauflicht3 += lauflicht3 + (lauflicht2 >> 7);
lauflicht2 += lauflicht2 + (lauflicht1 >> 7);
lauflicht1 += lauflicht1 + (lauflicht0 >> 7);
lauflicht0 += lauflicht0;


Peter

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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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


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.