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