Rejestry AVR i operacje bitowe na zmiennych w C
W czasie programowania procesorów AVR mamy do dyspozycji rejestr kierunku – DDRx(x – A, B, C.. dla portów PORTA, PORTB, PORTC…). Możemy w nim zapisać kierunek przepływu danych – aby to wykonać musimy modyfikować poszczególne bity tego rejestru. Używamy także PORTx – rejestr wyjściowy, oraz PINx – rejestr wejściowy.
Aby programować poszczególne nogi procesora należy modyfikować poszczególne bity rejestrów. Jak to zrobić? Na początek przytoczę tabele prawdy funkcji boolowskich:
|
|
|
|
W języku C operatory(bitowe) zapisujemy następująco:
Operator | Nazwa | Zapis w C |
OR | alternatywa | | |
AND | koniunkcja | & |
XOR | alternatywa wykluczająca | ^ |
NOT | negacja | ~ |
Używając ich odpowiednio możemy modyfikować poszczególne bity rejestrów – a ogólnie mówiąc zmiennych.
Rejestry mają po 8 bitów(procesory 8-bitowe)
Ustawianie bitu
Ustawianie x-owego bitu zmiennej abc:
abc |= (1<<x);[/code] Przykładowo, chcemy ustawić 3 bit rejestru kierunkowego DDRD - port PD3.Korzystamy z kodu podanego wcześniej: [code]DDRD |= (1<<3);[/code] albo [code]DDRD |= (1<<PD3);[/code] Jak to działa? Najpierw liczba 1 (binarnie: <span style="font-family: courier new,courier;">0b00000001</span>, <span style="font-family: courier new,courier;">0b</span>-nieformalny przedrostek trybu binarnego w AVR-GCC) zostaje przesunięta o 4 w lewo: 00000001 << 4 -> 00001000
Następnie jest ona poddawana bitowemu OR z rejestrem. Niech ten rejestr ma stan początkowy(0b00000000):
00000000 00001000 OR -------- 00001000
W wypadku kiedy byśmy już mieli ustawiony ten i kilka pozostałych bitów w rejestrze:
00101110 00001000 OR -------- 00101110
Stan rejestru się nie zmienia, bit nr 4 jest cały czas ustawiony.
Reset bitu
Zresetowanie x-owego bitu zmiennej abc:
abc &= ~(1<<x);[/code] Reset 4 bitu wykonujemy poleceniem: [code]DDR &= ~(1<<4);[/code] Następuje przesunięcie oraz negacja tego przesunięcia: [code] 00001000 NOT -------- 11110111 [/code] następnie wynik jest poddawany koniunkcji z rejestrem(0b00000000): [code] 00101110 11110111 AND -------- 00100110 [/code] Co w wypadku, gdy rejestr posiada inne bity ustawione? [code] 00000000 11110111 AND -------- 00000000 [/code] Analogicznie jak z alternatywą, pozostają one na swoim miejscu. <hr /> <h2>Odwrócenie(wymiana) bitu</h2> Odwrócenie x-owego bitu zmiennej abc. Polega to na tym, że jeśli dany bit ma wartość 1 to zostanie on zamieniony na 0 i odwrotnie: abc ^= (1<<x);[/code] Odwrócenie 7 bitu: [code]abc ^= (1<<7);[/code] W tabeli: [code] 10111001 01000000 XOR -------- 11111001 [/code] <hr /> <h2>Operacje bitowe na kilku bitach na raz</h2> Oczywiście można przyspieszyć ustawianie bitów robiąc to w jednej komendzie - używamy operatora bitowego OR do ich połączenia. Przykład: wyłączenie(reset) bitu 2,3,6,8 w zmiennej x: x &= ~( 1<<2 | 1<<3 | 1<<6 | 1<<8 );[/code] W tabelce: [code] 00000010 00000100 00100000 10000000 OR -------- 10100110 ~ -------- 01011001 [/code] Dla zmiennej x = <span style="font-family: courier new,courier;">0b10100111</span>: 10100111 01011001 & -------- 00000001
Dodatkowa literatura:
[TUT] [C] Bit manipulation (AKA "Programming 101")
Problemy C - Ustawianie i zerowanie bitów
Zagrożenia ze stosowania #define
AVR-GCC - wejście i wyjście binarne
TrackBack
TrackBack URL dla tej wiadomości:
https://blog.kkthx.pl/2012/02/rejestry-avr-i-operacje-bitowe-na-zmiennych-w-c/trackback/
Komentarze
Mały błąd się wkradł 🙂 W ostatnim przykładzie wynikiem powinna być wartość 00000001
Autor: Dariusz | Kwiecień 24th, 2017 10:29
Dzięki za sugestię – poprawione 😉
Autor: Łukasz | Kwiecień 28th, 2017 22:39