C Frage zum schieberegister

Ruffyx3

Cadet 2nd Year
Registriert
Okt. 2011
Beiträge
24
Ahoi und einen schönen nachmittag wünsche ich,

ich habe vor kurzem angefangen Arduino Programmierung in der schule zu lernen, nun bin ich gerade etwas am üben und habe eine frage zum Schieberegister.

Erstmal das was ich machen möchte:

Ich habe Über den PORTD 8 LED's angeschlossen und möchte diese nun eine nach der anderen an gehen lassen

das habe ich so vor das ich einfach in einer variablen einen 8 bit Code speichere und hier einfach die 1 immer um einen nach links verschiebe, ich hoffe die Vokabeln passen so halb :D

ich weiß das das Über das Schieberegister funktioniert und das es irgendwie mit den Zeichen >> abgerufen wird

mein Verständnis im Moment ist das: die zahl die vor den beiden größer Zeichen steht, zeigt an um wie viele stellen es verschoben wird, und die dahinter was verschoben werden soll

nun ist die frage ob ich das soweit richtig verstanden habe und wie der richtige Code dafür lautet.

bisher dachte ich das:
z.b.
unsignet char ausgabe=0x00000001;

while(1)
{
PORTD=ausgabe;
ausgabe = 1>>1;
}

das machen sollte doch scheinbar habe ich es wohl nicht richtig verstanden, wenn ich bei Google suche finde ich nur dinge die ich noch nicht verstehe^^
ich hoffe hier kann mir jemand eine schnelle einfache Lösung geben=)

MfG Ruffyx3
 
Ich würde eher sagen.
Code:
unsignet char ausgabe=0b00000001;

while(1)
{
    PORTD=ausgabe;
    ausgabe = ausgabe >> 1;
}
Hinter dem Schiebeoperator gibst du an, um vie viele binäre Stellen du schieben willst.
Da du aber nach rechts schiebst, schiebst du die 1 gleich beim ersten Mal raus.
Würdest du nach links schieben, also so.
Code:
unsignet char ausgabe=0b00000001;

while(1)
{
    PORTD=ausgabe;
    ausgabe = ausgabe << 1;
}
Dann hättest du zumindest einen Druchlauf, also so.
Code:
0b00000001
0b00000010
0b00000100
0b00001000
0b00010000
0b00100000
0b01000000
0b10000000
0b00000000
0b00000000
0b00000000
0b00000000
Aber da irggendwann die 1 raus geschoben wird, kommt irgendwann nur noch 0 (0b00000000).
 
Zuletzt bearbeitet:
ok vielen dank dafür!

so funktioniert es!

was für ein dummer Fehler :D aber daraus lernt man ja =)
 
1>>1 ist 0.

Dir muss klar sein, dass >> kein Schieberegister ist, sondern ein Operator in C. x>>y schiebt die zweikomplementsdarstellung von x um y bit nach rechts, das heißt, x wird kleiner (Pseudocode für positives x: floor(x/pow(2,y)).

Wenn du willst, dass die Lichter der Reihe nach angehen:
Code:
int leds=0;
while(1)
{
PORTD=1<<(leds%8);
leds++;
}

Ich verwende hier den << Operator, der x*2^y macht, dadurch kann ich die 1 um 0 bis 7 Stellen nach links schieben, dadurch gehen die LEDs nacheinander an, weil ich immer nur eine (im binär) 1 habe, die jedes mal eins weiter wandert.

Bei diesem Code werden alle LEDs leuchten, weil das für dein Auge zu schnell geht, also musst du ne Wartefunktion einbauen.

<< schiebt von rechts y Nullen rein.
>> schiebt von links y Nullen (oder Einsen bei einer negativen Zahl, im Zweifel einfach ein unsigned Datentyp verwenden) rein.

Schieben um mehr als 31 ist i.d.R. undefiniertes Verhalten.
 
ja mein erster plan war es wie schon von dir geschrieben über die formel

LEDs=2^x;
x++;

zu machen jedoch versteht c glaube ich ^ nicht als hoch?

da brauche ich doch dann die formel pow(x,y) richtig?

was bedeutet das von dir verwendete floor()?

PORTD=1<<(leds%8); das % hier sagt das es das nur machen soll wenn es maximal 8 ist? oder was bringt hier das %8?


das ergibt das:

LEDs=pow(2,x);
x++;

und

LEDs=LEDs<<1;

das gleiche bezwecken sowie

LEDs=pow(2,x);
x--; (wenn wir davon ausgehen das wir nun einfach bei einem x wert von 8 starten und bei 0 aufhören, natürlich würde er hier auch ins minus gehen)

das selbe ist wie

LEDs=LEDs>>1;


richtig verstanden? :D
 
Ja, für "hoch" brauchst du pow (oder bei 2 hoch die << und >>). ^ ist XOR (exklusiv oder bitweise). Brauchst du nicht so oft, aber zu wissen ist es gut.

floor rundet ab (in Richtung -Inf, also floor(-1.5)=2).

Das % ist der Rest-Operator, da ich ja nur immer LED 0 bis 7 anschalten will, bekomme ich bei %8 immer 0-7 raus.

Ja, <<n ist *pow(2,n), und >>n ist /pow(2,n). Wichtig, es ist deutlich einfacher zu lesen, wenn du den Index der LED als Zählvariable hast und nicht die Bitmaske für das Register, da so die Wartung erschwert wird. Beispiel: LED=64, welche LED leuchtet (*rechnen... log_2(64)= hmmm: 6*) die Sechste. Aber wenn x=6 und PORTD=1<<x weiß ich ohne Rechnen, welche LED tatsächlich leuchtet.

Wenn man komplexere Programme hat, macht man dann oft set und get Funktionen, die nur den Index nehmen.
 
Zurück
Oben