mikrocontroller.net

Forum: Compiler & IDEs longint highbyte und lowbyte direkt ansprechen in C


Autor: pluto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich habe eine doofe Frage und habe auch über die Suche nix 
gefunden.
Aber vielleicht kann mir ja jemand weiterhelfen.
Gibt es eine Möglichkeit in C das High- und Lowbyte einer Longint 
Variable direkt anzusprechen (schreiben/lesen)?

Vielen Dank schonmal

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Übliche: Nimm eine union. Wenn Du mit Low- und High-"Byte" die 
oberen und unteren 16 Bit meinst (wobei 16 Bit aber 2 Bytes sind!), dann 
ganz kurz:
union
{
    unsigned long wert;
    unsigned int wert_hl[2];
}
Oder mit Maskierung.

Autor: Fisch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn es wirklich nur das Low- und Highbyte sein soll, mach es doch 
einfach so.
void main (void)
{
long int a=0xABCD;
char LB=0;
char HB=0;
LB=(char)a;
HB=(char)(a>>8);
}

Gruß Fisch

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> HB=(char)(a>>8);
Es geht um einen long int. Da musste etwas mehr schieben...

Autor: Fisch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast recht. Dann muss er halt 24 schieben.

Autor: pluto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, sorry ich meinte natürlich nicht long sondern short, also 16 Bit.
Dann sollte es aber so gehen wie Fisch geschrieben hat, oder?

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn man a als int und nicht als long int deklariert, dann ja. 
Allerdings ist ein sicheres Funktionieren nur mit unsigned-Variablen 
gewährleistet. Je nachdem, was der Compiler aus dem Vorzeichen-Bit 
macht, kann sonst eventuell Murks rauskommen...

Autor: pluto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was macht denn das (char)? Das (a>>8) schiebt ja alles um 8 Bit nach 
rechts.
Irgendwie steh ich voll auf dem Schlauch.
Und wie geht das in die Andere Richtung? also 2x char zu int

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

Bewertung
0 lesenswert
nicht lesenswert
Das (char) ist ein sog. 'cast'

Also:

* Zerlegen

  int i;
  uint8_t LowByte, HighByte;

  LowByte = (uint8_t) i;
  HighByte = (uint8_t)( ((uint16_t)i) >> 8 );

* Zusammensetzen

  int i;
  utin8_t LowByte, HighByte;

  i = (int)( HighByte << 8 | LowByte );

Am besten macht man sich dafür ein paar Makros oder
inline Funktionen

#define LOW(x)       ((uint8_t)(x))
#define HIGH(x)      ((uint8_t)(((uint16_t)(x)) >> 8)
#define TOWORD(x,y)  (((x) << 8) | y)

  int i, j;
  uint8_t LowByte, HighByte;

  LowByte = LOW(i);
  HighByte = HIGH(i);

  j = TOWORD(HighByte, LowByte);

Autor: pluto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Karl heinz Buchegger
was macht der 'cast' ich kapier das nicht.

@all
Ich habe mal 3 Funktiionen gebaut wäre schön wenn jemand mal 
drüberschauen könnte, ob die so in Ordnung sind.

Vielen Dank schonmal!


uint8_t highbyte(uint16_t a){return (uint8_t)(a>>8);}
uint8_t lowbyte(uint16_t a){return (uint8_t)a;}
uint16_t word(uint8_t a,uint8_t b){return (uint16_t)(a << 8 | b );}

Autor: Peter S. (psavr)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Buchegger

>#define TOWORD(x,y)  (((x) << 8) | y)

Solltest Du hier nicht erst auf 16Bit casten, bevor Du schiebst?

#define TOWORD(x,y)  (((uint16_t)x << 8) | y)

@Pluto
Ich würde Makros, wie die Buchegger vorschlägt verwenden statt 
Funktionen. Funktionen sind etwas langsamer, wegen dem Function-Call 
Overhead.

>uint16_t word(uint8_t a,uint8_t b){return (uint16_t)(a << 8 | b );}

Allenfalls müsstest Du vor dem Links shiften ebenfalls auf 16Bit casten 
und die Klammern anderst setzen. (Sicher ist sicher)

uint16_t word(uint8_t a,uint8_t b){return (uint16_t)(((uint16_t)a << 8) | b );}



Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter:
Berechnungen werden doch standardmäßig eh in 16 Bit durchgeführt, 
solange nichts anderes angegeben ist. Den cast nach uint16_t kann man 
sich also sparen.

@Pluto:
> was macht der 'cast' ich kapier das nicht.
Der cast sorgt dafür, dass das Ergebnis der Berechnung (das ja immer 
noch ein 16-Bit-Wert ist) als 8-Bit-Wert zurückgegeben wird. Du willst 
ja aus einem 16-Bit-Wert 2 8-Bit-Werte machen. Ohne den cast vor dem 
return wäre der Rückgabewert ein uint16_t und es würde eine 
Fehlermeldung geben, dass der Typ des Rückgabewertes (also uint16_t) 
nicht mit dem in der Funktionsdeklaration vereinbarten (also uint8_t) 
übereinstimmt. Beim cast von 16-Bit-unsigned int-Variablen auf 
8-Bit-unsigned int werden die 8 MSB des 16-Bit-int abgeschnitten und nur 
die 8 LSB bleiben übrig. Ich hoffe, die Erklärung war jetzt nicht zu 
unverständlich. Wie casts generell funktionieren (und auch wann sie 
nicht funktionieren) solltest Du im C-Buch Deines Vertrauens mal 
nachlesen.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"short, also 16 Bit."

Wobei short vorzeichenbehafet ist. Wenn dir klar ist, was das bedeutet, 
ist es gut, sonst nimm lieber das auch in den Beispielen genannte 
unsigned short bzw. uint16_t.

Oliver

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.