Zwei Byte aus array in Word konvertieren

Für Fragen von Einsteigern und Programmieranfängern...

Zwei Byte aus array in Word konvertieren

Beitragvon DL3AD » 31. Jan 2019, 12:22 Zwei Byte aus array in Word konvertieren

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
DL3AD
 
Beiträge: 391
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.8.0 FPC 3.0.4) und Debian Stretch (L 1.8.0 FPC 3.0.4) | 
CPU-Target: 32Bit/64Bit
Nach oben

Beitragvon Timm Thaler » 31. Jan 2019, 12:58 Re: Zwei Byte aus array in Word konvertieren

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.
Timm Thaler
 
Beiträge: 873
Registriert: 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
Nach oben

Beitragvon wp_xyz » 31. Jan 2019, 13:52 Re: Zwei Byte aus array in Word konvertieren

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])^;
wp_xyz
 
Beiträge: 2862
Registriert: 8. Apr 2011, 08:01

Beitragvon af0815 » 31. Jan 2019, 14:07 Re: Zwei Byte aus array in Word konvertieren

@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).
af0815
 
Beiträge: 3616
Registriert: 7. Jan 2007, 10:20
Wohnort: Niederösterreich
OS, Lazarus, FPC: FPC 3.2 Lazarus 2.0 per fpcupdeluxe | 
CPU-Target: 32Bit (64Bit)
Nach oben

Beitragvon siro » 31. Jan 2019, 14:45 Re: Zwei Byte aus array in Word konvertieren

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...
siro
 
Beiträge: 333
Registriert: 23. Aug 2016, 13:25
Wohnort: Berlin
OS, Lazarus, FPC: Windows 7 Windows 8.1 Windows 10 | 
CPU-Target: 64Bit
Nach oben

Beitragvon wp_xyz » 31. Jan 2019, 15:00 Re: Zwei Byte aus array in Word konvertieren

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

Hab ich für dExif/fpExif gelernt...
wp_xyz
 
Beiträge: 2862
Registriert: 8. Apr 2011, 08:01

Beitragvon af0815 » 31. Jan 2019, 15:57 Re: Zwei Byte aus array in Word konvertieren

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).
af0815
 
Beiträge: 3616
Registriert: 7. Jan 2007, 10:20
Wohnort: Niederösterreich
OS, Lazarus, FPC: FPC 3.2 Lazarus 2.0 per fpcupdeluxe | 
CPU-Target: 32Bit (64Bit)
Nach oben

Beitragvon Timm Thaler » 31. Jan 2019, 16:54 Re: Zwei Byte aus array in Word konvertieren

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.
Timm Thaler
 
Beiträge: 873
Registriert: 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
Nach oben

Beitragvon Warf » 31. Jan 2019, 16:59 Re: Zwei Byte aus array in Word konvertieren

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
Warf
 
Beiträge: 1081
Registriert: 23. Sep 2014, 16:46
Wohnort: Aachen
OS, Lazarus, FPC: Mac OSX 10.11 | Win 10 | FPC 3.0.0 | L trunk | 
CPU-Target: x86_64, i368, ARM
Nach oben

Beitragvon Timm Thaler » 31. Jan 2019, 17:44 Re: Zwei Byte aus array in Word konvertieren

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.
Timm Thaler
 
Beiträge: 873
Registriert: 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
Nach oben

Beitragvon wp_xyz » 31. Jan 2019, 18:22 Re: Zwei Byte aus array in Word konvertieren

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.
wp_xyz
 
Beiträge: 2862
Registriert: 8. Apr 2011, 08:01

Beitragvon Warf » 31. Jan 2019, 19:16 Re: Zwei Byte aus array in Word konvertieren

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.
Warf
 
Beiträge: 1081
Registriert: 23. Sep 2014, 16:46
Wohnort: Aachen
OS, Lazarus, FPC: Mac OSX 10.11 | Win 10 | FPC 3.0.0 | L trunk | 
CPU-Target: x86_64, i368, ARM
Nach oben

• Themenende •

Zurück zu Einsteigerfragen



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste

cron
porpoises-institution
accuracy-worried