Zwei Byte aus array in Word konvertieren

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Zwei Byte aus array in Word konvertieren

Beitrag von DL3AD »

Hallo,
aus einer I2C Antwort erhalte ich zwei Byte in einem Array und möchte nun die beiden Byte als word weiter verarbeiten.
Hier ist meine derzeitige Lösung.

Code: Alles auswählen

 
procedure TForm1.Button3Click(Sender: TObject);
var
  WR: WordRec;
begin
  buf2[1] := $0F;//Bufferbyte 1
  buf2[2] := $8C;//und Bufferbyte 2 kommt von einer I2C Antwort
 
  WR.Hi := buf2[1];
  WR.Lo := buf2[2];
 
  Edit1.Text:= IntToStr(word(WR));//Word Wert zum weiterverarbeiten
 
end;     


Es funktioniert - meine Frage - Geht es noch einfacher ?

Gruß Frank

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Zwei Byte aus array in Word konvertieren

Beitrag von Timm Thaler »

DL3AD hat geschrieben:Es funktioniert - meine Frage - Geht es noch einfacher ?


Ja, gleich per I2C ein Word abfragen. Hängt davon ab, wie / womit Du die I2C Daten liest.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Zwei Byte aus array in Word konvertieren

Beitrag von wp_xyz »

Wenn die Daten in einem Byte-Array b stehen und du die Bytes am Index i und am folgenden Index i+1 zusammen als Word auslesen willst, hilft auch dieses:

Code: Alles auswählen

var
  w: Word;
...
  w := PWord(@b[i])^;

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Zwei Byte aus array in Word konvertieren

Beitrag von af0815 »

@wp Das ist fast schon ein wenig C. SCNR :shock:
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Zwei Byte aus array in Word konvertieren

Beitrag von siro »

Du kannst Dir einen sogenannten Varianten Record selbst bilden:

Code: Alles auswählen

 
Type TMyWordRec = record
  case boolean of
    FALSE : (Lo:Byte; Hi:Byte);
    TRUE  : (value:Word);
  end;
 


Nun kannst Du auf die einzelnen Bytes oder auf den gesamten Wert zugreifen:

Code: Alles auswählen

 
procedure TForm1.FormCreate(Sender: TObject);
var x:TMyWordRec;
begin
  x.Lo:=0;
  x.Hi:=1;
  caption:=IntToStr(x.value)// ergibt 256
end;                     


Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Zwei Byte aus array in Word konvertieren

Beitrag von wp_xyz »

af0815 hat geschrieben:@wp Das ist fast schon ein wenig C. SCNR :shock:

Hab ich für dExif/fpExif gelernt...

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Zwei Byte aus array in Word konvertieren

Beitrag von af0815 »

Code: Alles auswählen

function BytesToSingle(B1, B2, B3, B4: Byte): single;
var
  buf : array[0..3] of byte;
  ASingle : Single absolute buf;
begin
  buf[0] := B1;
  buf[1] := B2;
  buf[2] := B3;
  buf[3] := B4;
  Result := ASingle;
end;

Ich bevorzuge eher sowas, da steige ich auch beim schnellen lesen noch ohne Augenkrampf durch :-)
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Zwei Byte aus array in Word konvertieren

Beitrag von Timm Thaler »

Auf nem AVR würd ich das aber nicht machen wollen. Da ist es sauberer, sich eine Routine zu machen, die gleich den Wert als Word ausliest.

Also kommt drauf an: Wo kommen die Werte her und womit werden die gelesen.

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Zwei Byte aus array in Word konvertieren

Beitrag von Warf »

Erstmal, vorsicht, das kommt natürlich immer auf deine Endianess an. x86 benutzt Little Endian, also endet in der kleinsten byte addresse. Das heißt der Aufbau eines Ints 0xAABBCCDD würde im speicher als [DD][CC][BB][AA] dargestellt werden (das kleinstwertigste byte zu erst, und das byte mit addresse 0 ([AA]) am schluss). Auf einem Big Endian System würde es aber [AA][BB][CC][DD] gespeichert werden.
Bei x86 ists noch einfach, da da die Spezifikation besagt das es little endian ist. Bei ARM hat man aber nicht das glück, da lässt die Spezifikation es offen. Das heißt z.B. ist der Raspberry Pi Prozessor, sowie die Qualcomm prozessoren die in Android geräten drin sind alle Little endian, das muss aber nicht für jeden ARM prozessor gelten.

Dafür bietet der FPC aber auch ein Macro:

Code: Alles auswählen

var convert: record
  case Boolean of
  {$IFDEF ENDIAN_LITTLE}
    True: (HiByte, LoByte: Byte);
  {$ELSE}
    True: (LoByte, HiByte: Byte);
  {$ENDIF} 
    False: (Value: Word);
  end;


Ansonsten wurde hier schon alles erwähnt, absolute keyword, pointer magic und variante records. Mein liebstes sind Variante records, da ich da die Endianess am einfachsten beachten kann

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Zwei Byte aus array in Word konvertieren

Beitrag von Timm Thaler »

Warf hat geschrieben:Erstmal, vorsicht, das kommt natürlich immer auf deine Endianess an.


Und nicht nur auf die vom Rechner.

Ich hatte letztens einen BME280 Drucksensor, da werden witzigerweise die Kalibrierdaten low-high gelesen, während die Messwerte high-low sind. Was auch immer sie sich dabei gedacht haben.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Zwei Byte aus array in Word konvertieren

Beitrag von wp_xyz »

Für die Behandlung der Endianness von Daten hält FPC in der System-Unit die folgenden Funktionen vor: BEToN(AValue), LEToN(AValue), NToBE(AValue), NToLE(AVAlue), wobei AValue ein SmallInt, Word, LongInt, DWord, Int64 oder QWord sein kann und das Funktionsergebnis wieder genau derselbe Datentyp ist.

Wenn eine Datei oder ein externes Gerät BigEndian-Daten liefert, werden diese mit BEtoN sicher in die Endianness des eigenen Rechners konvertiert, egal ob der Rechner selbst BigEndian oder LittleEndian hat: wenn der aktuelle Rechner auch BigEndian hat, passiert nichts, wenn er LittleEndian ist, wird die Byte-Reihenfolge umgedreht. Analog für LEToN.

Und wenn man Daten in eine Datei schreiben muss, die BigEndian-Daten verlangt (z.B. png-Graphikdatei), muss man sie unmittelbar vor dem Schreiben mit NToBE konvertieren - wieder: wenn der eigene Rechner auch BigEndian ist, passiert nichts, aber bei LittleEndian wird wieder die Byte-Reihenfolge gespiegelt. Und entsprechend auch für NToLE.

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Zwei Byte aus array in Word konvertieren

Beitrag von Warf »

Timm Thaler hat geschrieben:Und nicht nur auf die vom Rechner.

Ich hatte letztens einen BME280 Drucksensor, da werden witzigerweise die Kalibrierdaten low-high gelesen, während die Messwerte high-low sind. Was auch immer sie sich dabei gedacht haben.


Big endian wird gern als Network Byte Order verwendet, da die auch bei IP verwendet wird. Aber kenn ich auch, beim i2c protokoll gibts keine festgelegte Byte order, weshalb es da auch gerne mal vorkommt das man verschiedene Byte order für verschiedene Komponenten hat.

wp_xyz hat geschrieben:Für die Behandlung der Endianness von Daten hält FPC in der System-Unit die folgenden Funktionen vor: BEToN(AValue), LEToN(AValue), NToBE(AValue), NToLE(AVAlue), wobei AValue ein SmallInt, Word, LongInt, DWord, Int64 oder QWord sein kann und das Funktionsergebnis wieder genau derselbe Datentyp ist.

Wenn eine Datei oder ein externes Gerät BigEndian-Daten liefert, werden diese mit BEtoN sicher in die Endianness des eigenen Rechners konvertiert, egal ob der Rechner selbst BigEndian oder LittleEndian hat: wenn der aktuelle Rechner auch BigEndian hat, passiert nichts, wenn er LittleEndian ist, wird die Byte-Reihenfolge umgedreht. Analog für LEToN.

Und wenn man Daten in eine Datei schreiben muss, die BigEndian-Daten verlangt (z.B. png-Graphikdatei), muss man sie unmittelbar vor dem Schreiben mit NToBE konvertieren - wieder: wenn der eigene Rechner auch BigEndian ist, passiert nichts, aber bei LittleEndian wird wieder die Byte-Reihenfolge gespiegelt. Und entsprechend auch für NToLE.

Und nicht zu vergessen die ganzen funktionen aus der Sockets Unit wie htons oder ntohs, etc.

Antworten