Hallo @ all Ich möchte Daten von den Ports einlesen. Der Datenbus ist 8 Bit breit. Zuerst übertrage ich das Low-Byte und anschließend das High-Byte. Danach möchte ich das Low-Byte und High-Byte zusammenfassen zu einem unsigned int. Hier mein Quellcode: bit status; char low_byte, high_byte; if(status == LOW_BYTE) { low_byte = PINC; status = HIGH_BYTE; } else { high_byte = PINC; ptr_datenpuffer[i] = high_byte; ptr_datenpuffer[i] = ptr_datenpuffer[i] << 8; ptr_datenpuffer[i] = low_byte; status = LOW_BYTE; } Ich dachte das durch die Wertzuweisung die unteren 8 Bits des unsigned int beschrieben werden. Anschließend wollte ich das ganze um 8 Stellen nach links schieben und dann das Low-Byte zuweisen. Dies scheint so aber nicht zu funktionieren Grüsse Sebastian
> ptr_datenpuffer[i] = high_byte; > ptr_datenpuffer[i] = ptr_datenpuffer[i] << 8; > ptr_datenpuffer[i] = low_byte; Oder einfacher und kürzer: ptr_datenpuffer[i] = ((int) high_byte )<<8) | low_byte;
@Sebastian : ja, aber schau dir noch mal das Beispiel von Rahul an. (Typenumwandlung) x=((unsigned int)hi << 8) + lo;
oder so: union{ unsigned short u_s; char u_c[2]; }convert_var; convert_var.u_c[0]=byte_1; convert_var.u_c[1]=byte_2; Ergebniss: convert_var.u_s;
Die Lösung mit der Union ist kein sauberes C, weil man je nach Compiler/Prozessor verschiedene Ergebnisse bekommen kann (Stichwort Endianness), deshalb sollte man lieber Shifts verwenden.
ptr_datenpuffer[i] = (((int) high_byte )<<8) | low_byte; Wieso muss der Datentyp vom low_byte nicht verändert werden? Schließlich führe ich doch eine Veroderung von zwei unterschiedlichen Datentypen durch. Grüsse Sebastian
Vorschlag: ausschießlich unsigned verwenden, zb so:
1 | bit status; |
2 | unsigned char low_byte, high_byte; |
3 | |
4 | // unsigned short ptr_datenpuffer[300];
|
5 | |
6 | if(status == LOW_BYTE) |
7 | {
|
8 | low_byte = PINC; |
9 | status = HIGH_BYTE; |
10 | }
|
11 | else
|
12 | {
|
13 | high_byte = PINC; |
14 | ptr_datenpuffer[i] = (high_byte<<8)+low_byte; |
15 | status = LOW_BYTE; |
16 | }
|
Wieso braucht man denn mit einmal keine Typenumwandlung mehr?
>Wieso braucht man denn mit einmal keine Typenumwandlung mehr?
Das erledigt der Compiler. Unsigned char und unsigned short haben
ja schon den gleichen Typ, nur unterschiedliche Größe.
Hi, wie wärs mit int intvalue=0; char *low_byte = (char*) &intvalue; char *high_byte = (char*) (&intvalue)+1; Schneller gehts nicht, weil hier nicht gerechnet werden muss. Die ARMs haben idR. nen Barrelshifter drin, so dass man da in einem Takt bis zu 32Bit shiften kann. Die AVRs glaub ich nicht... Greetz, /th.
Ich habe mich jetzt für diese Lösung entschieden (((int) high_byte )<<8) | low_byte; Vielen Dank für die Antworten. Es war sehr Aufschlußreich Grüsse Sebastian
Sebastian wrote: > Ich habe mich jetzt für diese Lösung entschieden > > (((int) high_byte )<<8) | low_byte; Das kann aber auch nach hinten losgehen. Schiebeoperationen sollte man möglichst nur mit vorzeichenlosen Datentypen machen.
wieso castest Du nach int, Du wolltest doch eigentlich unsigned?
Mein Fehler im Quellcode habe ich natürlich ptr_datenpuffer[i] = (((unsigned int) high_byte )<<8) | low_byte; benutzt
Thorsten De buhr wrote: > int intvalue=0; > char *low_byte = (char*) &intvalue; > char *high_byte = (char*) (&intvalue)+1; Auch das ist nicht portabel. Je nach Prozessor kann es sein dass das low_byte hier gar nicht das low byte ist, sondern das high byte. > Schneller gehts nicht, weil hier nicht gerechnet werden muss. Die ARMs > haben idR. nen Barrelshifter drin, so dass man da in einem Takt bis zu > 32Bit shiften kann. Die AVRs glaub ich nicht... Der Compiler setzt das beim AVR in zwei Byte-Zugriffe um, geschoben wird da gar nicht.
>> int intvalue=0; >> char *low_byte = (char*) &intvalue; >> char *high_byte = (char*) (&intvalue)+1; >Auch das ist nicht portabel. Je nach Prozessor kann es sein dass das >low_byte hier gar nicht das low byte ist, sondern das high byte. Das was Thorsten vorgeschlagen hat, macht doch eigentlich der Compiler, wobei dieser dann auch die richtige Zuordnung (Position der Bytes) trifft, oder?
Der AVR shiftet überhaupt nicht, weil der Compiler schlau genug ist einen 8-Bit-Shift durch einen entsprechenden Bytezugriff zu ersetzen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.