Temat nie jest skomplikowany, a potrzeba taka rodzi się co jakiś czas. Za każdym razem kiedy muszę przeprowadzić operacje na bitach, po pierwsze przychodzi myśl cholera jak to było ….
A no tak:
1. prawie jak RESET
Dla skasowania wybranego bitu w bajcie stosujemy operator logiczny AND maska „0” resetuje dany bit.
2. prawie jak SET
Dla ustawienia wybranego bitu w słowie trzeba skorzystać z operatora OR, gdzie maska „1” ustawia dany bit.
3. prawie jak TOGGLE
I trzecia możliwość – modyfikacja bitu na stan przeciwny, dzięki operatorowi XOR, możemy sobie zmienić w słowie wartości poszczególnych bitów na przeciwne. W tym celu stosujemy maskę „1„.
Bascom AVR posiada jeszcze operator NOT ale w tym artykule się nam nie przyda taka funkcjonalność.
Specjalnie użyłem porównań prawie jak … aby sprawa stała się jeszcze prostsza do zapamiętania. Oczywiście użyte porównania dotyczą operacji związanych z typem BIT. My modyfikować będziemy zmienne typu byte i każde inne, tylko i wyłącznie na wybranych pozycjach poszczególnych bitów. Ktoś powie no dobra przecież mamy operację wyłuskania bitowego … no tak ale jedna instrukcja załatwia jeden bit i generuje znaczną ilość kodu wynikowego. Stosując metodę, którą opisuję, za jednym razem „załatwimy” dowolną (potrzebną) ilość bitów słowa, bez względu na to czy te bity są po kolei w słowie czy też nie. ;-p Proste praktyczne i bardzo skuteczne. W dodatku dostępne we wszystkich językach programowania 😉
Niektórym spędza to sen z oczu, a inni czytając te słowa będą na twarzy mieli grymas w kształcie banana myśląc – przecież to podstawa …. ;-p
Jak to działa? Z powyższych dobrodziejstw można korzystać w sposób następujący. Dla ułatwienia omówię sprawę na przykładzie konfiguracji bajtu powiedzmy że odczytanego z rejestru konfiguracyjnego jakiegoś scalaka. Zakładam tak: odczytano &B00110101 i teraz dla jasności umówię się, że skrajny bit po prawej jest najmłodszy i ma numer zero. A więc potrzebuję wyzerować bity 2, 3 i 7 dla uzyskania zamierzonej funkcjonalności, a potem trzeba zmodyfikowane słowo wysłać z powrotem. I teraz można by to wykonać w sposób następujący:
1 2 3 4 5 |
Dim bajt_konfiguracyjny As Byte Bajt_konfiguracyjny.2=0 Reset Bajt_konfiguracyjny.3 Bajt_konfiguracyjny.7=0 |
A można to zrobić tak:
1 2 3 |
Dim bajt_konfiguracyjny As Byte Bajt_konfiguracyjny=Bajt_konfiguracyjny AND &B01110011 |
Specjalnie zastosowałem notację binarną, aby było ładnie widać mój zamiar. Analogicznie postępujemy w podobnych przypadkach, oraz z pozostałymi operatorami.
A teraz proszę pomyśleć – co by było gdybyśmy zdefiniowali stałą o nazwie Preset, w której uwieczniona będzie wartość &B01110011. Kod staje się czytelny i wygodny … Możliwości stają otworem.
I to co najważniejsze niech każdy spróbuje sobie skompilować powyższe kawałki i wyciągnie BEZCENNE wnioski 😉 jaki mają wpływ przeprowadzone operacje na bitach, na końcowy kod wynikowy.
A.D. 2017-03-25
Byłbym wielce niesprawiedliwy pomijając w tym temacie dwie ciekawe funkcje. Są to NBITS oraz BITS. Ich skutek działania jest analogiczny jak w przedstawionych propozycjach. Niemniej dla niektórych zapis może być wygodniejszy.
Pierwsza wykona operację – ustaw wszystkie bity z wyjątkiem określonych bitów na 1,
druga (BITS) – ustaw wszystkie określone bity na 1.