www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C Schiebebefehle


Autor: Anfänger (Gast)
Datum:

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

Autor: Michael H. (michael_h45)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
unsigned char byte=0;
if(aktuelles_bit) byte|=1;
byte <<= 1;

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

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt, so einfach kanns sein.
Vielen Dank!

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

Gruß

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

Autor: Anfänger (Gast)
Datum:

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

Autor: A. K. (prx)
Datum:

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

Autor: Anfänger (Gast)
Datum:

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

Autor: Michael H. (michael_h45)
Datum:

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

Autor: Anfänger (Gast)
Datum:

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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

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

Autor: Anfänger (Gast)
Datum:

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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

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

Autor: Anfänger (Gast)
Datum:

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

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

Autor: Michael H. (michael_h45)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

Autor: Michael H. (michael_h45)
Datum:

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

Autor: Anfänger (Gast)
Datum:

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

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.