www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Aus 2 char ein unsigned int erzeugen


Autor: Sebastian (Gast)
Datum:

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

Autor: Obelix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du überschreibst den wert damit.
x=(hi << 8) + lo;

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist x=(hi << 8) + lo; denn die Lösung?

Autor: Rahul Der trollige (rahul)
Datum:

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

Autor: Obelix X. (obelix)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Sebastian : ja, aber schau dir noch mal das Beispiel von Rahul an. 
(Typenumwandlung)


x=((unsigned int)hi << 8) + lo;

Autor: Tobias Rohde (tobiasrohde)
Datum:

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

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

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

Autor: Sebastian (Gast)
Datum:

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

Autor: Lötnagel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vorschlag: ausschießlich unsigned verwenden, zb so:
bit status;
unsigned char low_byte, high_byte;

// unsigned short ptr_datenpuffer[300];

if(status == LOW_BYTE)
{
   low_byte = PINC;
   status = HIGH_BYTE;
}
else
{
   high_byte = PINC;
   ptr_datenpuffer[i] = (high_byte<<8)+low_byte;
   status = LOW_BYTE;
}

  

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso braucht man denn mit einmal keine Typenumwandlung mehr?

Autor: Lötnagel (Gast)
Datum:

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

Autor: Random ... (thorstendb) Benutzerseite
Datum:

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

Autor: Sebastian (Gast)
Datum:

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

Autor: Johannes M. (johnny-m)
Datum:

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

Autor: Willi Wacker (williwacker)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wieso castest Du nach int, Du wolltest doch eigentlich unsigned?

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Fehler im Quellcode habe ich natürlich

ptr_datenpuffer[i] = (((unsigned int) high_byte )<<8) | low_byte;

benutzt

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

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

Autor: STK500-Besitzer (Gast)
Datum:

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

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
shiftet denn der avr 8x in einem takt?

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der AVR shiftet überhaupt nicht, weil der Compiler schlau genug ist 
einen 8-Bit-Shift durch einen entsprechenden Bytezugriff zu ersetzen.

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.