Konwersja liczby zmiennoprzecin. wg normy IEEE 754

0

Witam Szanownych Forumowiczów,
mam problem z którym nie mogę sobie poradzić chodzi o konwersję liczby zmienno przecinkowej zapisanej
szesnastkowo. Napisałem prosty programik który ma na celu odczyt wartości z modułu falownika pewnych danych a dokładniej prędkości obrotowej silnika jakim steruje ten falownik. Komunikacja ze sterownikiem odbywa się poprzez port COM (rs232 na rs485) i oparta jest o protokół ModBus. Z komunikacją nie ma żadnego problemu, falownik odpowiada na wysłane do niego ramki zapytania.
Problem jest właśnie ze zdekodowaniem tych wartości które zwrócił falownik.
Wyjaśnię to na przykładzie:
wysyłam do falownika ramkę: 01 03 00 01 00 02 95 CB
i falownik odpowiada ramką: 01 03 04 E6 9A AB 43 D3 95
gdzie:
01 - adres falownika
03 - funkcja 3 odczytu rejestrow
04 - ilość bajtów danych
E6 9A AB 43 - dane wartość zmiennoprzecinkowa
D3 95 - crc

Problem jest właśnie ze zdekodowaniem tej wartości E6 9A AB 43 jako wartość decimal jest w przedziale 300.000 - 350.000 w tych okolicach pokazuje falownik na wyświetlaczu.
Prosił bym bardzo o podanie algorytmu jak taką liczbę zdekodować no chyba że jest taka funkcja w Delphi
która to realizuje, każde sugestie linki mile widziane.
Pozdrawiam

0

sprawa jest dość prosta, wystarczy żeby te 4 odczytane bajty znalazły się w odpowiednim miejscu w pamięci. Tu jest to rozpisane na bity:

http://pl.wikipedia.org/wiki/IEEE_754

czyli bity 0..7 to pierwszy bajt, 8..15 drugi, itd. Następnie traktujemy to miejsce w pamięci jak by tam był float 32 czyli typ Single. Poniżej przykład wykorzystujący rekord z wariantem:

type
  T32bf=record
    case Boolean of // ten sam obszar pamieci jako:
      True: (b1, b2, b3, b4: Byte); // 4 bajty
      False: (f1: Single);// 32-float
  end;
(...)
var
  A32f: T32bf;
(...)
begin
  //zapis odczytanych war. hex
  A32f.b1:=$E6;
  A32f.b2:=$9A;
  A32f.b3:=$AB;
  A32f.b4:=$43;
  //i odczyt jako f-32
  WriteLn( A32f.f1 )
  //lub np. ShowMessage( FloatToStr( A32f.f1 ) );
end
(...)
0

Wielce szanowny forumowiczu. To co napisałeś to nic innego jak protokół MODBUS. Wartości decymalne kodowane są na 4 bitach zgodnie z normą IEEE 754 wg schematu:

Z CCCCCCCC MMMMMMMMMMMMMMMMMMMMMMM
gdzie: Z – znak, C – cecha, M – mantysa.

To co jest powyżej to zapis binarny 4 oktetów (bitów) liczby zmiennoprzecinkowej

kodowanie dziesiętne uzyskuje się jako:

L=(-1)ZM2(C-127)

czyli wartości dziesiętne mantysy mnozymy przez 2 do potęgi (cecha-127). A znak z=0 to liczba dodatnia, z=1 to liczba ujemna

w razie wątpliwości pisz na gg: 709952

1 użytkowników online, w tym zalogowanych: 0, gości: 1