co oznacza: i&=~(1<<(7-j)) (kod na STM32)

0

Hej, pracuję nad kodem na STM32 i mam zadanie w funkcji zapisać bajt, odczytując kolejno w pętli składające się na niego 8 bitów (na podstawie odebranego sygnału). Bajt zapisywany jest w zmiennej uint8_t i. Wiem, że instrukcje dopisujące odpowiednio 1 lub 0 powinny wyglądać tak :
i&=~(1<<(7-j)); //write 0
i|=(1<<(7-j)); //write 1
ale niestety nie rozumiem tej składni (poza przesunięciem bitowym w nawiasie) i bardzo proszę o wytłumaczenie jak to działa

7

x &= cośtam to to samo, co x = x & cośtam, a samo & to koniunkcja bitowa. Analogicznie, x |= cośtam to x = x | cośtam, a | to alternatywa bitowa. ~ to negacja bitowa, a - to odejmowanie. Wszystko po // to komentarz.

0

@Althorion: bardzo dziękuję!

2

i|= "dodaj" binarnie do i
(1<<7-j) weź jedynkę (0000 0001) i przesuń ją o liczbę pozycji 7-j w lewo, czyli np przy j == 3 przesuń jedynkę o cztery pozycje by w rezultacie otrzymać 0001 0000
czyli
i|=(1<<(7-j)); "dodaj" binarnie jedynkę do i na pozycji 7 - j, oraz zera na pozostałych pozycjach, w rezultacie na tej pozycji po tej operacji na pewno będzie jedynka niezależnie od wcześnie ustawionej wartości, a wartości na pozostałych pozycjach pozostaną niezmienione

i&= "pomnóż" binarnie i
~ negacja
czyli
~(1<<7-j) ustaw jedynkę na pozycji 7 - j a potem zaneguj całą wartość czyli 0000 0001->0001 0000->1110 1111
czyli
i&=~(1<<(7-j)); "pomnóż" binarnie i przez 1110 1111 czyli w efekcie na pozycji 7 - j na pewno będzie zero niezależnie od wcześniej ustawionej wartości, a wartości na pozostałych pozycjach pozostaną niezmienione

Słowa "dodaj" i "pomnóż" są w cudzysłowach bo reprezentują one moje skróty myślowe. Chcąc być całkowicie poprawnym | oznacza alternatywę (z elektroniki OR, łatwiej zapamiętać) a & oznacza koniunkcję (w elektronice AND).

3

Zerowanie bitu 7-j w zmiennej i.
(najmniej znaczący bit to bit 0)

2
/**
 * clears n-bit oldest bit
 */
void clearNOldestBit(uint8_t &i, int n)
{
    i&=~(1<<(7-n));
}

/**
 * sets n-bit oldest bit
 */
void setNOldestBit(uint8_t &i, int n)
{
    i|=(1<<(7-n));
}
1

@MarekR22: eee, chyba wszystko się zgadza

jeśli j jest od 0 do 7, to 7 - j będzie od 7 do 0, czyli dalej można zaadresować wszystkie 8 bitów (ponumerowane od 0 do 7)

1

Tu masz rozwinięcie tematu:

Te "7 - j" to jakaś niepotrzebna komplikacja, w linku powyżej jest to napisane prościej.

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