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:
 
bin 2 dec
 
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:
 
1
 
2
 
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:
 
3
 
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:
 
and
 
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:
 
or
 
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:
 
xor

Arduino kod

 
Registri porta D izgledaju ovako:
 
port D
 
Spojimo tipkalo i LEDicu prema Fritzing shemi:
 
tipkalo i ledica
 
LEDicu smo spojili na D7, tipkalo na D2. 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);
}
Leave a Reply