poniedziałek, 18 stycznia 2016
AVR cz2 - arytmetyka bitowa.
Aby efektywnie oprogramowywać mikrokontrolery AVR kluczową umiejętnością jest umiejętność programowania w języku C ze szczególnym uwzględnieniem operatorów bitowych. Jako pierwsze omówmy przesunięcie bitowe w lewo ( operator << ). Polega to na przesunięciu bitów w bajcie o określoną ilość pozycji, bity z prawej strony uzupełniane są zerami). Na przykład zapis PORTB<<3 oznacza przesunięcie w lewo bitów portu PORTB o 3 bity.
PORTB 00010101
PORTB<<3 10101000
Często spotykany zapis w programowaniu AVR to na przykład 1<<PD3. Piny Atmegi oznaczamy jako Pxy - x oznacza port (B,C,D), y - numer pinu(bitu) w porcie (0,1,3,...,7). Co to oznacza? Oznacza to tyle, że zapisana binarnie jedynka zostanie przesunięta to pozycji pinu D3 (3 pozycje w lewo, gdyż bity numerujemy od 0 ). Czyli mamy:
1 00000001
1<<PD3 00001000
Widać, że przesunięcie bitowe możemy użyć do ustawiania dowolnego bitu w porcie. W języku C może to wyglądać:
PORTD=0x0; //zerujemy port D
PORTD=1<<PD2; //pin 2 portu D ustawiamy na 1
Niestety łatwo zauważyć, że zastosowanie tej metody nie jest do końca dobre. W razie jej zastosowania tracimy wartość innych bitów (pinów) portu. Czy można temu zaradzić? Okazuje się, że tak. Wystarczy użyć logicznej funkcji OR. Funkcja OR dwóch bajtów w systemie binarnym daje w wyniku same 1 z wyjątkiem gdy alternatywie poddajemy dwa 0 wtedy jej wartość wynosi 0. Na przykład:
BAJT_A 11011011
BAJT_B 01100010
BAJT_A|BAJT_B 11111011
Zapis | oznacza OR w języku C. Co nam to daje. Rozważmy przykład.
PORTD 11100000 /początkowa wartość portu
1<<PD3 00001000
PORTD|(1<<PD3) 11101000
"Zapaliliśmy" bit3 nie zmieniając wartości innych bitów. Oznacza to, że funkcję OR możemy używać do zapalania bitów. Możemy jednocześnie zapalać kilka bitów. W języku C zapisujemy to jako:
PORTD|=(1<<PD3)|(1<<PD1) //zapalamy bity 3 i 1
Zapis PORTD|=(1<<PD3)|(1<<PD1) oznacza w notacji C: PORTD=PORTD|(1<<PD3)|(1<<PD1).
Skoro istnieje prosty sposób na zapalanie bitów to musi istnieć również metoda ich gaszenia. Aby to osiągnąć musimy rozważyć dwa następne operatory binarne NOT (~) i AND (&). Operator NOT zamienia wartość bitu na przeciwną czyli z 1 na 0 i z 0 na 1. Operator AND dwóch bajtów da wartość 1 tylko wtedy gdy dwa bity będą równe 1, w pozostałych przypadkach da wartość 0. Rozważmy przykład.
PORTD 11111011
1<<PD4 00010000
~(1<<PD4) 11101111
PORTD &~(1<<PD4) 11101011
Zauważmy, iż został zgaszony tylko bit 4. Zatem nasza metoda działa. Można też gasić bity hurtowo :
PORTD&=~((1<<PD4)|(1<<PD5));
Ostatnią przydatną metodą jest metoda negowania wybranego bitu. W tym celu musimy kykorzystać funkcję XOR (^). Wartość funkcji XOR dla dwóch bajtów przyjmuje wartość 1 gdy dwa bity są różne np. 0 i 1, jeżeli wartość bitów jest taka sama to XOR zwraca 0. Rozważmy przykład.
PORTD 11101011
1<<PD4 00010000
PORTD^(1<<PD4) 11111011
Zanegowaliśmy bit 4. I o to chodziło. W języku C można to zapisać jako:
PORTD^=(1<<PD4);
Przydatna tabelka wartości funkcji:
W następnej części pierwszy układ.
Subskrybuj:
Komentarze do posta (Atom)
Brak komentarzy:
Prześlij komentarz