ComposeInt32 (10023)

1) Do czego służy ComposeInt32
ComposeInt32 służy do złożenia jednej liczby 32-bitowej typu całkowitego ze znakiem (Int32 / I32) z dwóch liczb 16-bitowych (dwóch „słów” / WORDów po 16 bitów).
W praktyce blok wykonuje operację „sklejenia bitów”:
low → młodsze 16 bitów (bits 0…15)
high → starsze 16 bitów (bits 16…31)
out → wynik Int32 (I32)
2) Interfejs bloku (wejścia/wyjście)
Wejścia
low
Wejście dla dolnego słowa (LSW – Least Significant Word).
Wchodzi tu wartość, której bity trafią na pozycje 0…15 w wyniku.
high
Wejście dla górnego słowa (MSW – Most Significant Word).
Wchodzi tu wartość, której bity trafią na pozycje 16…31 w wyniku.
Wyjście
out
Wynik złożenia: I32 (Int32) – liczba 32-bitowa ze znakiem.
3) Zasada działania (bit po bicie)
Blok składa wynik w następujący sposób:
Bierze 16 bitów z wejścia low i umieszcza je jako młodsze 16 bitów wyniku.
Bierze 16 bitów z wejścia high i umieszcza je jako starsze 16 bitów wyniku (czyli „przesuwa” je o 16 bitów w lewo).
W zapisie bitowym (logika składania):
out[15:0] = low[15:0]
out[31:16] = high[15:0]
W formie „matematycznej na bitach” (typowy zapis dla składania słów):
out = (high << 16) OR (low & 0xFFFF)
4) Co ze znakiem (liczby ujemne)
Ponieważ out jest Int32, znak wyniku zależy od najstarszego bitu (bit 31) – a ten pochodzi z wejścia high.
Jeśli w high ustawiony jest bit 15 (czyli „znak” dla 16 bitów), to po złożeniu będzie ustawiony bit 31 w out i wynik może być ujemny (zgodnie z kodem U2 / two’s complement).
To nie jest „błąd” – to normalne zachowanie przy składaniu surowych bitów w typ ze znakiem.
5) Najważniejsza uwaga praktyczna: kolejność słów (endianness słów)
Urządzenia komunikacyjne bardzo często przesyłają 32 bity jako dwa rejestry 16-bitowe, ale kolejność bywa różna:
wariant A (najczęstszy w opisach “low/high”)
pierwszy rejestr = low (młodsze słowo), drugi = high (starsze słowo)
wariant B (zamieniona kolejność słów)
pierwszy rejestr = high, drugi = low
Jeżeli po złożeniu dostajesz „dziwne” wartości (np. liczba jest gigantyczna albo kompletnie inna niż oczekiwana), to najpierw zamień miejscami podłączenia low i high.
6) Procedura użycia krok po kroku
Ustal, które 16 bitów są „low”, a które „high” w Twoim źródle danych (np. z urządzenia, rejestrów, zmiennych).
Podłącz młodsze słowo do low.
Podłącz starsze słowo do high.
Odczytaj wynik na out jako Int32 (I32).
Jeśli wynik nie odpowiada rzeczywistości – zamień low ↔ high i sprawdź ponownie.
7) Przykład na konkretnych liczbach (z obliczeniem)
Przykład 1 (prosty, dodatni wynik)
Załóżmy:
low = 1 (czyli 0x0001)
high = 2 (czyli 0x0002)
Składanie:
high << 16 = 0x0002 << 16 = 0x00020000
out = 0x00020000 OR 0x00000001 = 0x00020001
Wynik:
out = 0x00020001 = 131073 (dziesiętnie)
Czyli blok zwróci na wyjściu out wartość 131073.
Przykład 2 (wynik ujemny – pokazuje wpływ high)
Załóżmy:
low = 0 (0x0000)
high = -1 (w 16 bitach to 0xFFFF)
Składanie:
high jako bity = 0xFFFF
high << 16 = 0xFFFF0000
out = 0xFFFF0000 OR 0x00000000 = 0xFFFF0000
W Int32:
0xFFFF0000 = -65536
Czyli out będzie -65536.
8) Jak można go wykorzystać (praktyczne zastosowania)
Blok ComposeInt32 wykorzystasz zawsze wtedy, gdy:
masz wartość 32-bitową przesłaną/rozbitą na dwa słowa 16-bitowe,
chcesz ją złożyć do jednej zmiennej Int32 (I32) w programie.
Najczęstsze przypadki:
odczyt danych z komunikacji, gdzie urządzenie zwraca 32 bity jako 2 rejestry 16-bit,
składanie licznika, pozycji, energii, czasu, przepływu itp., gdy są „przychodzą” w dwóch częściach.