Struktury – ustawienie bitów w Word

0

mam taką deklaracje

    txObj.word[0] = 0;
    txObj.word[1] = 0;
     
    txObj.bF.id.SID = 0x300;
    txObj.bF.id.EID = 0;                       to 
    txObj.bF.ctrl.FDF = 1;
    txObj.bF.ctrl.BRS = 1;
    txObj.bF.ctrl.IDE = 0;
    txObj.bF.ctrl.RTR = 0;
    txObj.bF.ctrl.DLC = MCP2517FD_DLC_64;
    txObj.bF.ctrl.SEQ = 1;

Jak za pomocą:

txObj.bF.ctrl.FDF = 1;

zapalić np 6 bit TXObj.word[0]?

0

To nie są deklaracje – to wypełnianie danymi struktury ze zmiennej. Nie mam zielonego pojęcia co chcesz osiągnąć, bo nie opisałeś problemu szczegółowo, a przede wszystkim nie pokazałeś deklaracji typu danych tego txObj.

Do takich rzeczy zwykle używa się tzw. variant records (potocznie: z case w środku) i pól bitowych, jednak nie mogę na ten temat znaleźć informacji, jeśli o Delphi chodzi. Z tego względu sądzę, że po prostu nie obsługuje pól bitowych, więc pozostaje ręczna manipulacja zawartością danego bajtu (koniunkcja do gaszenia bitów, alternatywa do ich zapalania).

0

nikt nie ma szklanej kuli aby wywróżyć czym jest txObj

0
T_txMsgObj               txObj;


typedef struct
{
    uint32_t DLC : 4;
    uint32_t IDE : 1;
    uint32_t RTR : 1;
    uint32_t BRS : 1;
    uint32_t FDF : 1;
    uint32_t ESI : 1;
    uint32_t SEQ : 7;
    uint32_t unimplemented1 : 16;

} T_txMsgObjCtl;

can.png

0

Dobrze, że podałeś deklarację typu w C/C++, ale przydałoby się też wiedzieć jak ten typ masz zadeklarowany w Delphi. No to może zróbmy inaczej, bo widzę, że nie możemy się dogadać.

Dla przykładu, mamy zbiorczy bufor o rozmiarze 32 bitów. Nieważne jakim typem sobie go reprezentujesz – ważne, aby dało się go potraktować jako liczbę 32-bitową. Wzór na zapalenie konkretnego bitu poniżej:

Buffer := (Value shl BitPos) or Buffer;

Gdzie Buffer to nasz zbiorczy bufor (liczba 32-bitowa), Value to wartość, jaką chcemy wrzucić do bufora, a BitPos to numer bitu w buforze (najmłodszego dla wrzucanej wartości). Pamiętaj, że mowa o indeksowaniu bitów od 0.

Przykład zapalenia szóstego bitu (o indeksie 5):

var
  Buffer: UInt32 = 0;
  Value: UInt32 = 1;
begin
  Buffer := (Value shl 5) or Buffer;

Po konwersji na liczbę binarną, dostaniemy poniższe:

0b00000000000000000000000000100000

Szósty bit jak widać zapalił się. Teraz wrzucimy sobie dwubitową wartość do pustego bufora:

var
  Buffer: UInt32 = 0;
  Value: UInt32 = 3;
begin
  Buffer := (Value shl 5) or Buffer;

W rezultacie dostaniemy poniższe:

0b00000000000000000000000001100000

Jak widać wartość została wrzucona w miejsce szóstego bitu, ale że zajmuje dwa bity, to zapaliliśmy bit szósty i siódmy. Rozumiesz jak to działa?

0

No tak to będzie działać tylko jeśli będziemy mieli wartość

0b00000000000000000000000001100000

a będziemy chcieli wpisać wartość nie 3 tylko 2 to or nie zadziała.

czyli po operacji chcemy mieć

0b00000000000000000000000001000000

Tylko tak myślę jak to jest realizowane w C/C++ bo nigdy nie programowałem, Co raz częściej mi się wydaje, że ten język jest bardziej przyjazny i prosty.

0
piter2004 napisał(a):

a będziemy chcieli wpisać wartość nie 3 tylko 2 to or nie zadziała.

Oczywiście – jeśli w buforze znajdują się już jakieś dane (zapalone bity) i chcesz niektóre zapalić, a niektóre zgasić, to najpierw przeprowadzasz koniunkcję na danych bitach (gasząc je, używając zer), a następnie alternatywą zapalasz tylko te, które we wrzucanej liczbie są zapalone.

Pamiętaj, że aby zgasić tylko dany zakres bitów, maska musi mieć zapalone wszystkie pozostałe bity – w przeciwnym razie inne też zostaną zgaszone. Dla przykładu weźmy liczbę 8-bitową, żeby tyle zer nie pisać. Ma ona taką zawartość:

0b00101110

Teraz chcesz wrzucić swoją 2-bitową liczbę w miejsce trzeciego bitu, czyli manipulować bitami o indeksach 2 i 3. Jeśli użyjesz wyłącznie alternatywy, to wartość się nie zmieni, bo trzeci i czwarty bit są już zapalone.

    0b00001000  (2 binarnie shl 2)
or  0b00101110  (bieżąca zawartość bufora)
------------------------------------------
    0b00101110  (wynik – nadal 3)
          ^^

Dlatego też najpierw musisz koniunkcją zgasić te dwa bity, a następnie alternatywą zapalić na nowo, używając nowej wartości:

     0b11110011  (maska gasząca interesujące nas bity)
and  0b00101110  (bieżąca zawartość bufora)
-------------------------------------------
     0b00100010  (wynik gaszenia bitów)
or   0b00001000  (2 binarnie shl 2)
-------------------------------------------
     0b00101010  (wynik – 2)
           ^^

^ oznaczają bity, na których nam zależy.

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