LOW-LEVEL PROGRAMIRANJE ARDUINA: BITWISE OPERATORI

UVOD
U drugom tuturialu low-level programiranja Arduina koristiti ćemo Port D, odnosno digitalne pinove 0-7. Pinovi 0 i 1 porta D koriste se za serijsku komunikaciju i većina ljudi ne želi ih koristiti za ništa drugo. Stvari mogu postati čudne ako se igrate s njima. Tako da je uobičajena praksa ne dirati 0 i 1 bitove DDRD i PORTD registra. Kako bi to uspješno izveli potrebno nam je predznanje iz matematike bitova.
Nakon kratkog uvoda u bitove, programirati ćemo tipkalo i LEDicu. Ukoliko ste preskočili prvu lekciju, vratite se ovdje.
BINARNI SUSTAV
Da se binarni sustav sastoji od hrpe 0 i 1 već znate, kao i kako jedan bajt ima 8 bitova. Ako pričamo o registrima 8bitnim mikrokontrolerima, svaki registar ima 8 bitova numeriranih do 0 do 7 s desna na lijevo. Kada smo govorili o registrima koji upravljaju GPIO pinovima spomenili smo kako im stanje možemo mijenjati u različitim brojevnim sustavima. Prije nego nastavimo, ponovimo pretvaranje.
Binarni u dekadski
U dekadski sustav pretvaramo tako da bazu, broj 2, potenciramo pozicijom bita. Bit 0 je 2 na 0, bit 1 je 2 na 1, bit 3 je 2 na 2 i td. U primjeru iz prošlog tutoriala:
Kada zbrojimo rezultate dobijemo 32, što je ekvivaletno binarnom broju B00100000.
Binarni u heksadekadski
Heksadekadski sustav je najčešće korišten pri mijenjanju stana registara kod mikrokontrolera. 8bitni binarni broj podijeliti ćemo na dva 4bitna, na bitnove 7-4 te 3-0. svaki zasebno potencirat ćemo s brojevima 1,2,4 i 8 s lijeva na desno. Evo kako to izgleda na našem primjeru:
Zbroj rezultata registra 7-4 je 2, dok je zbroj 3-0 jednak 0. Rezultat zapisujemo na način da zapišemo prvi broj do drugoga, odnosno 20. Kako bi razaznali da se radi o heksadekadskom broju u Arduino ćemo ga zapisati kao 0x20.
Pogledajmo što se događa kada rezultat 4 bita bude veći od 9 na primjeru:
Ukupan rezultat je 8+4+1 što je jednako 13, odnosno “D”. Pa tako binarni broj B1101 iz primjera je ekvivalent heksadekadskom 0xD.
BITWISE OPERATORI
Idemo obraditi bitwise operatore koji su nam nužni za ovaj tutorial i općenito prilikom korištenja bitova.
Bitwise AND, “&”
PRAVILO: samo ako su oba bita istina(1) rezultat je istina(1).
0 & 0 == 0
0 & 1 == 0
1 & 0 == 0
1 & 1 == 1
Dakle:
Bitwise OR, “|”
PRAVILO: ako je jedann od bitova istinit(1), rezultat je istinit(1)
0 | 0 == 0
0 | 1 == 1
1 | 0 == 1
1 | 1 == 1
Dakle:
Bitwise XOR, “^”
PRAVILO: rezultat je istinit(1) samo ako su oba bita jednaka, oba 1 ili oba 0.
0 ^ 0 == 1
0 ^ 1 == 0
1 ^ 0 == 0
1 ^ 1 == 1
Dakle:
ARDUINO KOD
Registri porta D izgledaju ovako:
Spojimo tipkalo i LEDicu prema Fritzing shemi:
LEDicu smo spojili na D7, tipkalo na D2 Dasduino pločice. Postavimo pin D7 kao izlazni, a pin D2 kao ulazni ne mijenjajući stanja pinova D0 i D1 koje koristimo za serijsku komunikaciju. Pinu D2 uključiti ćemo interni pull-up otpornik kako bismo izbjegli floatanje pina. Ubacite kod dolje u Arduino IDE i isprobavajte.
void
setup
()
{
// postavimo prvo digitalni pin7 (D7) kao izlazni
// bit za smjer povog pina na lazi se na poziciji 7 DDRD registra
// deafult stanje DDRD registra je B00000000
DDRD = DDRD | B10000000;
// "|" znaci logički OR
// sada smo sigurni da je 7 bit == 1
// te znao da bitove 0 i 1 nismo mijenjali
// medjutim, ne znamo stanje bita 2 kojeg koristimo za tipkalo
// postavimo ih prvo na 0 bez da mijenjamo stanja bitova 0,1 i 7
DDRD = DDRD & B10000011;
// koristeći logicki AND, sada smo sigurni da registar glasi: B100000000
// tako smo postavili sto smo zeljeli
// postavimo sada PORTD registar
// postavimo sve bitove u 0, ne mijenjajuci D0 i D1
PORTD = PORTD & B00000011;
// preostaje nam jos da stavimo bit 2(D2) u HIGH stanje - ukljucimo interni pull-up
// usput pazimo da ne mijenjamo stanje niti jednog drugog bita
PORTD = PORTD | B00000100;
}
void
loop
()
{
// citamo stanje digitalnog pina 2
int
tipkalo = PIND;
// u varijablu "tipkaalo" spremili smo cijeli registar
// medjutim zanima nas samo stanje bita 2 u ovom registru
// buduci da koristimo interni pull-up otpornik
// kada je tipkalo nije aktivirano stanje bit2 ce biti 1
// a kada je pritisnuto stanje ce biti 0 (fizicki cemo pin povezati na gnd)
tipkalo = tipkalo & B00000100;
// sada registar izleda ovako:
// kada je tipka aktivna: B00000000, u dekadskom sustavu == 0
// kada tipka nije aktivna: B00000100, u dekadskom sustavu == 2^2 = 4.
// napisimo uvjet koji ce upaliti LEDicu kada je tipka aktivirana
if
( tipkalo == 0)
{
// LEDicu na D7 palimo tako da 7mi bit stavimo u stanje "1"
// ponovno ne mijenjajuci stanje niti jednog drugog bita
PORTD = PORTD | B10000000;
}
// preostaje nam jos ugasiti LEDicu kada tipka vise nije aktivna
PORTD = PORTD & B00000111;
// posljednja naredba staviti ce sve bitove u 0
// osim poslijednja 3 koja ce ostati nepormijenjena
}
U sljedećem tutorialu vidjeti ćemo kako napisati vlastitu delay() funkciju te testirati brzinu izvođenja programa pomoću Arduino librarya i načina na koji upravo radimo.
S obzirom kako se void setup() izvodi samo jednom olakšati si možemo korištenjem Arduino pinMode() funkcije za ovaj dio. Čisto podsjetnik kako to izgleda:
void
setup
()
{
pinMode
(7,
OUTPUT
);
pinMode
(2,
INPUT_PULLUP
);
}