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:

Spojimo tipkalo i LEDicu prema Fritzing shemi:

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);
}