Forum: Mikrocontroller und Digitale Elektronik C Schiebebefehle


von Anfänger (Gast)


Lesenswert?

Hallo zusammen, ich bin gerade am C programmieren auf einem Mega32.
Ich bin leider noch nicht so erfahren in Umgang mit C. Darum wäre ich 
über eure Hilfe dankbar.

Ich bekomme über einen Pin am µC seriell Manchester Codiert Daten rein. 
Ich hab es auch hin bekommen die einzelnen Bits zu decodieren.

Nun zu meinem Problem!
Diese Bits kommen jetzt nacheinander rein und lösen einen Interrupt aus. 
Ich bekomme immer direkt Eins oder Null von meiner Funktion zurück 
geliefert.
Nun möchte ich diese Bits nacheinander in einem Byte speichern. Wie 
mache ich das am Besten?

Gibt es in C Schiebebefehle, mit denen man Einsen oder Nullen in ein 
Byte schieben kann. Oder gibts da nur die normalen Schiebebefehle (<< 
oder >>), bei denen mit Null aufgefüllt wird? Dann könnte ich einfach 
die Bits, wie sie mit ihren logischen Zuständen rein kommen, in das Byte 
schieben und ich wär fertig?

Geht das?

Oder wie mach ich das am Besten?

Gruß und Danke an alle.

von Michael H. (michael_h45)


Lesenswert?

1
unsigned char byte=0;
2
if(aktuelles_bit) byte|=1;
3
byte <<= 1;

Am besten keine Konstrukte mit Shifts variabler Anzahl. Dauert länger, 
weil ein Shift ein einzelner Befehl ist.

von Anfänger (Gast)


Lesenswert?

Stimmt, so einfach kanns sein.
Vielen Dank!

Aber habe ich das richtig verstanden, man kann in C keine
Einsen nach schieben.

Gruß

von Karl H. (kbuchegg)


Lesenswert?

Anfänger schrieb:

> Aber habe ich das richtig verstanden, man kann in C keine
> Einsen nach schieben.

Wozu ein extra Sprachkonstrukt einführen, wenn man denselben Effekt mit 
bereits vorhandenen Mitteln leicht erreichen kann?

von Anfänger (Gast)


Lesenswert?

OK, dann gibt es das also wirklich nicht!

Ja, ihr habt schon recht, es funktioniert natürlich so sehr einfach.
Man braucht als Anfänger manchmal einen Denkanstoß und dann gehts 
weiter, aber hier bin ich echt auf dem Schlauch gestanden.

Vielen Dank nochmal!

von (prx) A. K. (prx)


Lesenswert?

Anfänger schrieb:

> Diese Bits kommen jetzt nacheinander rein und lösen einen Interrupt aus.
> Ich bekomme immer direkt Eins oder Null von meiner Funktion zurück
> geliefert.

Linksrum wirds einfach, da deine Funktion 0/1 liefert:
   byte = (byte << 1) | function();

von Anfänger (Gast)


Lesenswert?

Ach noch was.

@Michael:
>Am besten keine Konstrukte mit Shifts variabler Anzahl. Dauert länger,
>weil ein Shift ein einzelner Befehl ist.

Danke für den Tipp, das wusste ich nicht, da muss man aufpassen.
Das heißt, wenn ich <<8 schreibe, wird 8 mal der Schiebebefehl 
ausgeführt?

Gruß

von Michael H. (michael_h45)


Lesenswert?

Anfänger schrieb:
> Aber habe ich das richtig verstanden, man kann in C keine
> Einsen nach schieben.
Ein klares Jein.
Der Compiler wählt anhand des deklarierten Datentyps zwischen logical 
und arithmetical shift aus.
Je nachdem wird entweder mit einer 0 aufgefüllt, oder mit dem Bit, das 
nach dem Shift im Überlauf sitzt.

Ich wüsste allerdings nicht, wie man die Entscheidung beeinflussen 
könnte.
Vielleicht geht es mit einem Parameter - aber der hat sich mir noch 
nicht vorgestellt.

Anfänger schrieb:
> Das heißt, wenn ich <<8 schreibe, wird 8 mal der Schiebebefehl
> ausgeführt?
Bei genau 8 wird der Compiler vermutlich optimieren und einfach das 
ganze Byte einfach anders adressieren. Ebenso vermutlich bei konstanter 
Shift-Anzahl.
Aber prinzipiell richtig, es wird x mal der einfache Shift ausgeführt.

von Anfänger (Gast)


Lesenswert?

@A. K.
> Linksrum wirds einfach, da deine Funktion 0/1 liefert:
>   byte = (byte << 1) | function();

Das wäre ja noch einfacher !!!
Mit links schieben hast du schon recht, das MSB kommt zuerst.

Danke!

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


Lesenswert?

Anfänger schrieb:
> wenn ich <<8 schreibe, wird 8 mal der Schiebebefehl ausgeführt?
Das kommt auf den Prozessor an.
Wenn der einen Barrelshifter hat, wird sofort um 8 Bits geschoben. Wenn 
der Byte-orientiert ist, dann ist es evtl. besser, gleich ganze Bytes 
auszutauschen.

> wenn ich <<8 schreibe, wird 8 mal der Schiebebefehl ausgeführt?
Dann wird also das was links davon steht irgendwie um 8 bits nach 
links geschoben.

von Anfänger (Gast)


Lesenswert?

@Michael:
Du hast recht, 8 ist ein blödes Beispiel.
Aber, dass es so kompliziert ist wusste ich nicht, ich glaube ich muss
mir das nochmal genau rein ziehen.
Das heißt, über das Carry- Bit könnte ich irgendwie auch Einsen 
schieben?
Nicht, dass ich es jetzt noch bräuchte, aber mich interessiert es 
irgendwie jetzt!

Gruß

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


Lesenswert?

Anfänger schrieb:
> Das heißt, über das Carry- Bit könnte ich irgendwie auch Einsen
> schieben?
Du kannst das Carry-Flag in C leider nicht so richtig ansprechen...  :-/

von Anfänger (Gast)


Lesenswert?

>Du kannst das Carry-Flag in C leider nicht so richtig ansprechen...  :-/

Versteh ich jetzt nicht ganz! Kann ich es ansprechen, oder nicht?

von Karl H. (kbuchegg)


Lesenswert?

Anfänger schrieb:

> Das heißt, über das Carry- Bit könnte ich irgendwie auch Einsen
> schieben?

Nein.
In C gibt es kein Carry Bit. :-)

Das was Michael H. geschrieben hat, ist zwar nicht grundsätzlich falsch, 
aber grundsätzlich richtig ist es auch nicht.

von Karl H. (kbuchegg)


Lesenswert?

Anfänger schrieb:
>>Du kannst das Carry-Flag in C leider nicht so richtig ansprechen...  :-/
>
> Versteh ich jetzt nicht ganz! Kann ich es ansprechen, oder nicht?

Vergiss am besten gleich wieder, dass es in deiner CPU ein Carry Bit 
gibt. C macht niemals irgendwelche Annahmen über darunterliegende 
Hardware. Die Programmiersprache C ist mithilfe einer abstrakten 
Maschine definiert, die das alles nicht kennt. In der Sprachdefinition 
ist festgelegt was zu passieren hat und nicht wie es zu implementieren 
ist.

von Michael H. (michael_h45)


Lesenswert?

Karl heinz Buchegger schrieb:
> Das was Michael H. geschrieben hat, ist zwar nicht grundsätzlich falsch,
> aber grundsätzlich richtig ist es auch nicht.
Hm.
Meinst du damit den Begriff "Überlauf"? Das war wohl etwas unglücklich 
gewählt, weil das gleich mit einem ominösen Carry-Bit assoziiert wird.

Hier wirds schön erklärt: http://en.wikipedia.org/wiki/Arithmetic_shift

von Karl H. (kbuchegg)


Lesenswert?

Michael H. schrieb:
> Karl heinz Buchegger schrieb:
>> Das was Michael H. geschrieben hat, ist zwar nicht grundsätzlich falsch,
>> aber grundsätzlich richtig ist es auch nicht.
> Hm.
> Meinst du damit den Begriff "Überlauf"?

Eigentlich meine ich, dass es in C so etwas wie einen arithmetischen 
Shift gar nicht gibt. C hat nichts dazu zu sagen, was passieren soll, 
wenn man mit signed Typen Bitschieben betreibt. Bitschieben ist nur auf 
unsigned Typen 100% definiert, für alles andere ist in C streng genommen 
nichts vorgesehen.

Und das Carry Flag spielt da schon gar nicht mit rein, weil es höchstens 
dann vom Compiler benutzt wird um ein Bit über die Byte Grenze bei 16 
Bit Datentypen zu bringen. Das ist aber Compiler-Internals und hat mit C 
an sich erst mal gar nichts zu tun. Aus C Sicht gibt es kein Carry.

von Michael H. (michael_h45)


Lesenswert?

Karl heinz Buchegger schrieb:
> Eigentlich meine ich, dass es in C so etwas wie einen arithmetischen
> Shift gar nicht gibt. C hat nichts dazu zu sagen, was passieren soll,
> wenn man mit signed Typen Bitschieben betreibt. Bitschieben ist nur auf
> unsigned Typen 100% definiert, für alles andere ist in C streng genommen
> nichts vorgesehen.
Jetzt ist mir klar, was du meinst.
Danke, war mir teilweise neu.

> Und das Carry Flag spielt da schon gar nicht mit rein, weil es höchstens
Das wollte ich auch nie ins Spiel bringen.

von Anfänger (Gast)


Lesenswert?

Das Carry hab ich ins Spiel gebracht ;)

>Vergiss am besten gleich wieder, dass es in deiner CPU ein Carry Bit
>gibt. C macht niemals irgendwelche Annahmen über darunterliegende
>Hardware. Die Programmiersprache C ist mithilfe einer abstrakten
>Maschine definiert, die das alles nicht kennt. In der Sprachdefinition
>ist festgelegt was zu passieren hat und nicht wie es zu implementieren
>ist.

Ich halte mich an das, dann kann ich nix falsch machen.

>Eigentlich meine ich, dass es in C so etwas wie einen arithmetischen
>Shift gar nicht gibt. C hat nichts dazu zu sagen, was passieren soll,
>wenn man mit signed Typen Bitschieben betreibt. Bitschieben ist nur auf
>unsigned Typen 100% definiert, für alles andere ist in C streng genommen
>nichts vorgesehen.

Das ist mir auch neu, vielen Dank!

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.