Forum: Mikrocontroller und Digitale Elektronik Lauflicht uController


von Raini_Breite (Gast)


Lesenswert?

Hallo zusammen
Ich habe eine Frage bezüglich eines Lauflichts mit der Schiebefunktion.
Kann mir jemand die Bedingung in der if-Abfrage ganz genau erläutern.
------------------------------------------------------------------------ 
-----
int main()
{
  int i=1;
  DDRB=255;
  while(1)
  {
    PORTB=i;
    _delay_ms(250);
    if(!(i&(1<<7)))
    {
      i=i<<1;
    }
    else i=1;
  }
}
------------------------------------------------------------------------ 
-----
Danke im Voraus
mfg Raini_Breite

von Joachim (Gast)


Lesenswert?

Guck mal hier:
http://www.mikrocontroller.net/articles/Bitmanipulation

Wenn du es dann noch nicht verstehst frag nochmal :)

Gruß

von Raini_Breite (Gast)


Lesenswert?

Hallo
erst mal danke für die schnelle antwort.
Ich habe es leider noch nicht ganz verstanden. Ich will damit 8 LED's 
ansteuern aber ich verstehe es nicht wieso da die 7 steht und wieso 
alles negiert wird.
Die &-Verknüpfung ist einfach das mit der Maske oder?
mfg Raini_Breite

von egon (Gast)


Lesenswert?

1<<7 -> = 128...

d.h. auf i wird ein and 128 gemacht und das negiert...das heisst wenn 
das hoechste bit nicht gesetzt ist shiftet er sonst setzt er i wieder 
auf 1...

bit 7 ist ja das letzte bit danach muss ja wieder das bit 0 (also 1 ) 
gesetzt werden sonst laeuft es ja nicht ;) sprich ist nur dafuer da um 
den sprung von der letzten led zur ersten zu machen...

von Raini_Breite (Gast)


Lesenswert?

Danke erstmal...und noch eine kleine frage^^
Ist das ausrufezeichen dafür da, dass es solange shiftet bis das letzte 
bit gesetzt ist?

von tim (Gast)


Lesenswert?

das ausrufezeigen negiert nur... z.b.

bei einem lauflicht hast du ja 8 positionen

bit 7 entspricht ja 128

7      0

00000001 i&(128) = 0 !i&(128) -> 1
00000010 i&(128) = 0 !i&(128) -> 1
00000100 i&(128) = 0 !i&(128) -> 1
00001000 i&(128) = 0 !i&(128) -> 1
00010000 i&(128) = 0 !i&(128) -> 1
00100000 i&(128) = 0 !i&(128) -> 1
01000000 i&(128) = 0 !i&(128) -> 1
10000000 i&(128) = 1 !i&(128) -> 0

wenn eine if anweisung 1 oder true hat geht sie ja in den ersten zweig 
sonst in den else zweig...
sprich bei den ersten 7 shifted er bei dem letzten macht er den sprung 
von bit 7 zu 1...

von tim (Gast)


Lesenswert?

von bit 7 zu bit 0 mein ich ;)

von Raini_Breite (Gast)


Lesenswert?

Danke ich glaube nun verstehe ich es einigermassen.

von dunno.. (Gast)


Lesenswert?

der schönheit halber würd ich aber mal das int i auf char, bzw unsigned 
char ändern..

oder hast du keinen 8bit controller?

mfg

von tim (Gast)


Lesenswert?

bisschen einfacher zu lesen waere z.b. das:

int main()
{
  char i=1;
  DDRB=255;
  while(1)
  {
    PORTB=i;
    _delay_ms(250);
    if(i>0)
    {
      i=i<<1;
    }
    else i=1;
  }
}

wenn bit 7 gesetzt ist wird die zahl bei einem char negativ... sprich so 
lange es groesser 0 ist wird geshiftet sonst der sprung gemacht...

von Raini_Breite (Gast)


Lesenswert?

Oke danke dier viel mal ich probiere es gleich mal aus...!! Doch mein 
Controller ist 8 Bit also sollte es gehen ;)
Gruss Raini_Breite

von tim (Gast)


Lesenswert?

noch einfacher waere das:

int main()
{
  char i=1;
  DDRB=255;
  while(1)
  {
    PORTB=1<(i++&7);
    _delay_ms(250);
  }
}

ok ich hoer auf ;) aber wie man sieht gibts div moeglichkeiten wie mans 
macht...

von Raini_Breite (Gast)


Lesenswert?

Daanke viel mal :)
Jedoch ist es meine aufgabenstellung dies mit dem schiebebefehl << zu 
lösen.
@tim: es funktioniert =)

von LuXXuS 9. (aichn)


Lesenswert?

Raini_Breite schrieb:
> Jedoch ist es meine aufgabenstellung dies mit dem schiebebefehl << zu
> lösen.

Jetzt gibt's wieder auf den Deckel :-)

von Martin (Gast)


Lesenswert?

Raini_Breite schrieb:
> Jedoch ist es meine aufgabenstellung dies mit dem schiebebefehl << zu
> lösen.

Ist es auch, da dort ein Tippfehler drin ist:

PORTB=1<<(i++&7);

von tim (Gast)


Lesenswert?

oh stimmt ... sorry ;)

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


Lesenswert?

tim schrieb:
> noch einfacher waere das:
     PORTB=1<<(i++&7);
Das ist allerdings ganz was anderes als der ursprüngliche Ansatz, denn 
hier wird die 1 unterschiedlich weit geschoben. Im Original wird mit dem 
Schiebebefehl nur die Maske berechnet:
     if(!(i&(1<<7)))

tim schrieb:
> bisschen einfacher zu lesen waere z.b. das:
>     if(i>0)
Unter der impliziten Annahme, dass i vorzeichenbehaftet ist....

Raini_Breite schrieb:
> Kann mir jemand die Bedingung in der if-Abfrage ganz genau erläutern.
Das hier:
    if(!(i&(1<<7)))   i=i<<1;
    else              i=1;
heißt im Klartext: wenn das MSB nicht gesetzt ist, dann schiebe i um 
eins nach links.
Das könnte auch so aussehen:
    if( i&(1<<7) )  i=1;
    else            i=i<<1;
Oder so:
    if(i&0b10000000) i=1;
    else             i=i<<1;

von Random .. (thorstendb) Benutzerseite


Lesenswert?

meine bevorzugte Variante:
1
led_out(1<<(ledCnt=++ledCnt<8?ledCnt:0));  //feed the running light
:-)

von Karl H. (kbuchegg)


Lesenswert?

Man kann fast alles beliebig komplex und kryptisch schreiben.

Für einen Anfänger ist aber wohl das hier
1
  while( 1 ) {
2
3
    PORTB = 0x01;
4
    delay_ms( 250 );
5
6
    for( i = 0; i < 6; ++i ) {
7
      PORTB = PORTB << 1;
8
      delay_ms( 250 );
9
    }
10
  }

die wohl am einfachsten zu verstehende Variante.

Und Reini. Auf sowas solltest du schon auch alleine kommen.

von Thomas (kosmos)


Lesenswert?

00000001 du kannst jetzt 7 mal nach links schieben dann steht die 1 ganz 
links wenn du weiter schiebst verschwindet sie vielleicht im Nirvana. 
Aber das ganz man verhintern, z.B. durch den passenden Befehl oder einen 
Begrenzung damit man nicht über 255 und unter 1 schieben kann.

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.