logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Konwersja HEX 44 79 AC CD z Modbus na float 998.7 w Delphi – jak napisać procedurę?

Jarlist 24 Mar 2005 15:03 1794 7
REKLAMA
  • #1 1344639
    Jarlist
    Poziom 11  
    Posty: 34
    Ocena: 4
    Witam. Mam taki problem. Potrzebuje procedurki pod Delphi, ktora zamieni mi liczbe hexa 44 79 AC CD, na typ float 998.700012
    Jest to slowo odczytane z serwera modbus, a na wyswietlaczu jest wartosc 998.7
    Mam gotowy program, ktory mi to zamienil, ale nie mam zrodelka.
    Dziekuje za pomoc
    Pozdrawiam
    Jarek.
  • REKLAMA
  • #2 1345096
    Akane
    Poziom 27  
    Posty: 638
    Pomógł: 144
    Ocena: 33
    zdeklaruj sobie zmienną FLOAT i jakąś wskaźnikową, tej wskaźnikowej nadaj wartość adresu zmiennej float i poprostu wpisz tam te liczby co podałeś jako DWORD:
    POINTER pFloat
    FLOAT FL
    
    pFloat = FL :' pFloat = adres zmiennej FL
    
    'wpisanie liczby 0x4479ACCD pod adres <pFloat>
    *<UINT>pFloat = 0x4479ACCD
    
    setprecision 10
    print FL : getch()

    albo
    _asm
    	mov eax,$FL
    	mov dword[eax],0x4479ACCD
    _endasm


    napisało mi 998.7000122070
  • REKLAMA
  • #3 1346695
    Jarlist
    Poziom 11  
    Posty: 34
    Ocena: 4
    Dzieki, a czy moglbys mi to przetlumaczyc na delphi :)). Dzieki. Pozdrawiam.
  • REKLAMA
  • #4 1347246
    Akane
    Poziom 27  
    Posty: 638
    Pomógł: 144
    Ocena: 33
    Nie znam Delphi, ale wygoglowałem takie coś:
    var
     iValue, j : integer;
     pIntValue : ^integer;
    begin
      iValue := 2001;
      pIntValue := @iValue;
      ...
      j:= pIntValue^;
    end;


    mniejwięcej bym to tak napisał

    var
     iValue : float;
     pIntValue : ^integer; /* zwykła liczba 4-bajtowa! */
    begin
      pIntValue := @iValue;
      pIntValue^ := 0x4479ACCD;
    end;
    *** iValue = oczekiwany wynik ***


    nie zmieniaj ^integer na ^float bo nie zadziała jak powinno. Mam nadzieję że integer to liczba 4-bajtowa
  • #5 1347289
    Jaca
    Poziom 32  
    Posty: 1332
    Pomógł: 239
    Ocena: 217
    To jest poprawiona i działająca wersja kodu Akane:

    var
     fValue: single;
     pIntValue: ^integer;
    begin
      pIntValue:=@fValue;
      pIntValue^:=$4479ACCD;
    end;
  • #6 1360709
    Jarlist
    Poziom 11  
    Posty: 34
    Ocena: 4
    Dziekuje.
    Zawroce Wam jeszcze glowe czyms takim:
    Mam 4 bajty - 44 6F 0C CD, kazdy zapisany pod inna zmienna.
    Jak je zlozyc do "kupy" zeby podstawic do waszej funkcji i zeby wyszlo mi 956.200012
    Dzieki za odpowiedz. Pozdrawiam
    Jarek.
  • REKLAMA
  • #7 1360764
    Akane
    Poziom 27  
    Posty: 638
    Pomógł: 144
    Ocena: 33
    1. ($44*524288) + ($79*65536) + ($AC*256) + $CD
    2. ($44*524288) or ($79*65536) or ($AC*256) or $CD
    3. ($44 Shl 24) or ($79 Shl 16) or ($AC Shl 8) or $CD najszybsze chyba

    te bajty przedstawiają liczbę type DWORD więc musisz poprzez pointer wpisać je do zmiennej Float żeby wynik był poprawny. Albo jeśli wiesz jak jest skonstruowana zmienna float - to i tak potrzebujesz extra funkcji

    Te sklejone bajty jako zwyczajny integer przedstawiają liczbę 1.07G (komputerowe Giga)
  • #8 1360825
    Jaca
    Poziom 32  
    Posty: 1332
    Pomógł: 239
    Ocena: 217
    Przy pomocy wzorów Akane "skleciłem" funkcję, która zamieni bajty z tablicy na wartość float:

    function TForm1.BytesToFloat(Bytes: array of byte): single;
    var
     fValue: single;
     pIntValue: ^integer;
    begin
      pIntValue:=@fValue;
      pIntValue^:=(Bytes[0] Shl 24) or (Bytes[1] Shl 16) or (Bytes[2] Shl 8) or Bytes[3];
      Result:=fValue;
    end;


    Wywołanie tej funkcji może wyglądać następująco:

      Edit1.Text:=FloatToStr(BytesToFloat([$44,$6f,$0c,$cd]));


    Pozdrawiam...

Podsumowanie tematu

LABEL_AI_GENERATED
Dyskusja dotyczy konwersji wartości heksadecymalnej 44 79 AC CD odczytanej z serwera Modbus na typ float w Delphi, odpowiadającej liczbie 998.700012. Zaproponowano rozwiązanie polegające na użyciu wskaźnika do zmiennej typu float (single) i przypisaniu do niej 32-bitowej wartości DWORD w formacie heksadecymalnym. Przykładowy kod w Delphi wykorzystuje operator bitowego przesunięcia (Shl) i operację OR do składania czterech bajtów w jedną wartość DWORD, która następnie jest rzutowana na float przez wskaźnik. Funkcja BytesToFloat przyjmuje tablicę bajtów i zwraca odpowiadającą im wartość typu single. Omówiono także sposób łączenia pojedynczych bajtów w 32-bitową liczbę DWORD, co jest niezbędne do prawidłowej konwersji na float. Rozwiązanie umożliwia odczyt i konwersję danych Modbus zapisanych w formacie IEEE 754 float do wartości zmiennoprzecinkowej w Delphi.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA