Zoran Šćepanović

Aug 252013
 

U prethodnom primeru napravili smo tzv. brojačku petlju upotrebom promenljive “brojac”, tj. postavili smo njeno početno stanje, uvećavali je i proveravali da li je stigla do zadate vrednosti. Obzirom da su ovake petlje veoma česte pri programiranju, u PBP-u postoji naredba FOR … NEXT koja olakšava izradu brojačkih petlji. Ovaj primer je realizovan uz pomoć te naredbe.

Tutor20.bas

Da vidimo kako tačno funkcioniše naredba “FOR … NEXT” čija puna sintaksa glasi:

FOR brojač = početak TO kraj {STEP {-}uvećanje}{naredba} NEXT {brojač}

Ova naredba omogućava izvršavanje neke naredbe ili bloka naredbi odredjeni broj puta koristeći promenljivu brojač. Obzirom da je relativno kompleksna, najbolje da rad ove naredbe objasnimo korak po korak:

1. Vrednost promenljive početak dodeljuje se promenljivoj brojač koja može da bude bilo kog tipa, u zavisnosti od potrebe.

2. Izvršava se naredba ili blok naredbi izmedju FOR i NEXT; ta naredba je opciona, tj. može i da se izostavi pa bi imali praznu FOR … NEXT petlju koja bi u tom slučaju mogla da se iskoristi kao vremenska zadrška.

3. Pri nailasku na reč NEXT, ako se upotrebi reč STEP vrednost uvećanje se dodaje (ili oduzima ako se upotrebi predznak -) promenljivoj brojač. Ako se STEP izostavi, brojač se uvećava za 1.

4. Ako nakon uvećanja brojač nije veći od vrednosti kraj, ili nije došlo do prekoračenja tipa promenljive, program se vraća na korak 2. U protivnom program nastavlja izvršavanje naredbe posle NEXT.

5. Moguće je izaći pre kraja uslova iz petlje upotrebom naredbe EXIT.

Da analiziramo sada naš primer. Pri nailasku na naredbu “for brojac=0 to 14”, promenljivoj “brojac” biće dodeljena prva vrednost, tj. nula. Zatim se izvršava naredba “LOOKUP” za koju već znamo šta radi. Posle pauze program nailazi na naredbu “next brojac” koja uvećava za 1 promenljivu “brojac” i proverava da li je njena vrednost veća od 14; ako nije, program se vraća na izvršavanje prve naredbe posle FOR, tj. u ovom slučaju LOOKUP naredbe, a u protivnom nastavlja dalje, tj. nailazi na naredbu “goto pocetak” kojom se započinje novi ciklus, i tako unedogled.

Vidimo da smo, kao i kod naredbe DO … LOOP, sve naredbe izmedju FOR i NEXT uvukli jer one čine jedan blok i bilo bi dobro da prihvatite tu praksu.

Ako uporedimo dužinu ovog primera videćemo da je duži za 2 vorda u odnosu na prethodni, što i nije mnogo ako se uzme u obzir komfor koji ova naredba pruža, ali ako Vam je cilj ušteda programske memorije, upotrebite način iz prethodnog primera za izradu brojačke petlje.

Aug 252013
 

U prethodnim primerima pravili smo efekat trčećeg svetla koristeći matematičke operacije. Međutim, u slučaju kada ne možemo da izračunamo sledeću kombinaciju jedini način da uradimo nešto takvo je upotreba tabele i u tu svrhu u PDS-u je implementirana naredba LOOKUP koju smo upotrebili u ovom primeru.

Tutor19.bas

Nakon inicijalizacije dodeljujemo nulu promenljivoj “brojac”, a zatim LOOKUP naredba uzima prvi podatak iz liste (jer promenljiva “brojac” ima vrednost 0), a to je 128 i stavlja ga u registar LATB čime se na LE diodama postavlja prva kombinacija; pretvorite broj 128 u binarni oblik i videćete koja LED se pali. Nakon pauze uvećavamo “brojac” i proveravamo da li je vrednost veća od 14 pošto lista u LOOKUP naredbi ima 15 elemenata; u slučaju da vrednost pređe 14, registar LATB ne bi promenio sadržaj jer ne postoji elemenat u listi na koji bi “brojac” pokazivao i zato se vraćamo na labelu “pocetak” kako bi resetovali promenljivu “brojac”. U slučaju da uslov za IF nije ispunjen, idemo na labelu “tabela”, tj. na uzimanje novog podatka iz LOOKUP liste jer smo prethodno uvećali “brojac” za 1.

Na kraju linije u kojoj se nalazi LOOKUP naredba vidimo donju crtu “_” koja u PDS-u služi da se dugačka linija “prelomi” u sledeći ekranski red. To znači da je ta naredba mogla da bude i u jednoj liniji (bez donje crte), ali smo je zbog njene dužine prelomili na 2 reda.

Iskreno rečeno, i ovaj efekat je mogao da se ostvari uz malo matematike, ali je cilj da savladamo korišćenje naredbe LOOKUP jer je veoma korisna za tabele, odn. liste i trebaće nam u mnogim primerima.

May 072013
 

Prethodni primer može da se napiše tako da potroši još 1 vorda više uz pomoć asmeblerskih naredbi koje smo upotrebili kako bismo se polako upoznavali sa njima jer nam njihovo poznavanje može biti od koristi kada budemo radili interapte. Njihovom upotrebom ostvarili smo i optimizaciju u smislu uštede programske memorije, mada postoji mišljenje da je danas sa ovim cenama bolje kupiti kontroler sa više memorije nego trošiti vreme na optimizaciju koja smanjuje veličinu programa. Optimizacija ili ne, odlučite sami šta više odgovara vašim potrebama i stilu pogramiranja.

Tutor18.bas

Sve BASIC naredbe su nam poznate pa ćemo da se posvetimo asemblerskim. Prva, “bcf STATUS, C” ima sintaksu koja glasi:

bcf f, b

Reč “bcf” je skraćenica od “bit clear file” gde “bit” označava da radimo sa jednim bitom, “clear” da “čistimo” oredjeni bit, tj. da ga postavljamo na 0, a “file” označava odredjenu promenljivu koja može da bude ili SFR ili neka naša promenljiva, tj. bilo koja lokacija u RAM-u kontrolera. Slovo “f” iza reči “bcf” označava da sledi naziv registra, a slovo “b” označava da sledi oznaka bita koji se resetuje – oznaka može da bude broj ili naziv bita. Da bi se koristio naziv, pre toga mora da bude definisan. Kraće rečeno, ova naredba resetuje odredjeni bit u nekom registru. A konkretno u ovom primeru ova naredba resetuje, tj. postavlja na nulu, u registru koji se zove STATUS, bit označen slovom C.

Naziv ovog registra i naziv bita su već definisani u PDS-u (kao i svi ostali SFR registri i njihovi bitovi) i njihove nazive ne moramo da pišemo velikim slovima u asemblerskim naredbama.

STATUS je SFR registar, čiji kompletan opis možete da vidite u tehničkim podacima na strani 21, koji čuva informacije o, kako mu i ime kaže, statusu nekih dogadjaja u kontroleru. Njegov bit 0 ima naziv “C” od reči “carry” koji služi kao informacija o prekoračenju rezultata nakon sabiranja ili oduzimanja. On se takodje koristi i u sledećoj naredbi u programu i ubrzo ćete videti zašto smo ga resetovali.

Postoji i asemblerska naredba koja setuje, tj. postavlja na 1 neki bit, a njena sintaksa glasi:

bsf f, b

Reč “bsf” je skraćenica od “bit set file”.

Sledeća naredba u programu je “rrf LATB, 1” čija sintaksa glasi:

rrf f, d

Reč “rrf” je skraćenica od “rotate right file” što znači “rotiraj udesno promenljivu”; slovo “f” iza reči “rrf” označava da sledi naziv registra ili promenljive, a slovo “d” označava odredište (“destination”) koje može da bude ista ta promenljiva, ili može da bude “w” registar. Ako je odredište ista ta promenljiva, umesto “d” pišemo broj 1, a ako je “w” registar, onda pišemo broj 0. Registar “w” je interni registar kontrolera, slovo “w” potiče od naziva “working registar” i jedini je registar koji nije smešten u RAM, a služi za prenos podataka izmedju RAM lokacija i vrši matematičko-logičke operacije sa RAM lokacijama.

Naredba “rrf” radi rotaciju samo za jedan bit, ali radi rotaciju kroz C bit STATUS registra što može da nam napravi problem. Da bi bilo jasnije, evo slike koja pojašnjava šta se tačno dešava:

rrf
Vidimo da kod rotacije udesno (postoji i naredba za rotaciju ulevo) bit 7 prelazi na mesto bita 6, bit 6 na mesto bita 5 itd sve do bita 0 koji prelazi na mesto C bita, dok C bit prelazi na mesto bita 7. Pošto nama nije potrebna rotacija već pomeranje, pre samog rotiranja moramo C bit STATUS registra da postavimo na 0 kako ne bi smo “vrteli” u krug ceo registar.

Pažljiv posmatrač može da vidi da u konkretnom primeru, pošto nam je u LATB registru samo jedan bit setovan, naredba “bcf STATUS, C” može da se izostavi, ali generalno nam je neophodna za “pretvaranje” asemblerske naredbe za rotiranje u naredbu za pomeranje jer ovaj PIC nema asemblersku naredbu za pomeranje bitova.

Pomenuli smo i naredbu za rotiranje ulevo i verovatno ste već pogodili kako glasi njena sintaksa:

rlf f, d

Reč “rlf” je skraćenica od, pogadjate, “rotate left file”, a evo i slikovnog prikaza njenog delovanja:

rlf

Veličina iskompajliranog programa: 81 Word-a

May 072013
 

Prethodni primer ne možemo da optimizujemo analogno onome kao što smo uradili sa primerom 14 u primeru 15, tj. ne možemo sabiranje sa samim sobom da zamenimo oduzimanjem jer bi rezultat odmah bio nula. Medjutim, ipak možemo da izbegnemo deljenje i dobijemo kraći program upotrebom jedne operacije koja se zove pomeranje, odn. šiftovanje.

Tutor17.bas

U ovom primeru vidimo da je linija “latb=latb / 2” zamenjena sa “latb=latb >> 1”. Dva znaka “veće” (>>) predstavljaju operator pomeranja udesno, a broj iza označava za koliko bitova se vrši pomeranje. Analogno tome, dva znaka “manje” (<<) predstavljaju pomeranje ulevo, a iza se takodje navodi broj bitova. Upotrebom ovog operatora umesto deljenja uštedeli smo 17 vorda programske memorije.

Ovaj operator vrši pomeranje bitova za onoliko mesta za koliko je navedeno pri čemu se gube bitovi koji “izlaze”, a na mesto novih se ubacuju nule. Da bi bilo jasnije, pogledajmo primer ako u promenljivoj X tipa bajt imamo broj 100, tj. binarno 01100100:

X=%01100100

Y=X << 1       ; Y=%11001000
Y=X << 2       ; Y=%10010000
Y=X << 3       ; Y=%00100000

Y=X >> 1       ; Y=%00110010
Y=X >> 2       ; Y=%00011001
Y=X >> 3       ; Y=%00001100

Na ovaj način ujedno ostvarujemo brzo množenje ili deljenje brojem koji je stepen broja 2, tj. brojevima 2, 4, 8, 16 itd. Pomeranje udesno je deljenje, dok je pomeranje ulevo množenje. Naravno, pri tome morate da pazite na bitove koji “izlaze” iz promenljive jer možete da dobijete pogrešan rezultat.

Veličina iskompajliranog programa: 81 Word-a

May 062013
 

Ako nam treba suprotan smer “trčanja” LED-ova, možemo da upotrebimo ovaj program:

Tutor16.bas

Program je praktično isti kao primer 14 sem što u inicijalizaciji LATB postavljamo na 128 kako bi uključili LED D8, a da bi uključili sledeću LED koristi se deljenje sa 2, dok je uslov za ispitivanje poslednje kombinacije ostao isti jer je posle sedmog deljenja vrednost za LATB jednaka 1, tako da posle osmog deljenja dobijemo nulu obzirom da se radi o celim brojevima.

Veličina iskompajliranog programa: 81 Word-a

May 062013
 

Ovaj primer radi isto što i prethodni sa tom razlikom da smo množenje brojem 2 zamenili sabiranjem sa samim sobom, što je potpuno isto u matematičkom smislu, a da li je i u dužini programa?

Tutor15.bas

Ovaj program zauzima samo 82 vorda, čak 1 više od prethodnog primera. Iz ovoga se može zaključiti da su pisci kompajlera dobro odradili “domaći zadatak” kada je prevođenje i optimizacija koda u pitanju.

Veličina iskompajliranog programa: 82 Word-a

May 062013
 

Efekat trčećeg svetla može da se postigne na više načina; u primeru 12 upotrebljen je najočigledniji, a u ovom je primenjen način koji početnicima verovatno nije najjasniji.

Tutor14.bas

Pre nego što objasnimo program da vidimo prvo šta se dešava sa vrednostima B porta kod efekta trčećeg svetla. Napisaćemo svih 8 kombinacija, njihove binarne i dekadne vrednosti:

00000001     1
00000010     2
00000100     4
00001000     8
00010000    16
00100000    32
01000000    64
10000000   128

Vidimo da je vrednost B porta za svaku sledeću kombinaciju tačno 2 puta veća od prethodne, što je i logično obzirom na binarni sistem. To znači da za sledeću kombinaciju ne moramo da isključimo prethodno upaljenu LED pa da uključimo sledeću već možemo prethodnu vrednost da pomnožimo sa 2 i dobijemo sledeću, a to upravo i radimo u ovom primeru. Na ovaj način program je nešto lakši za pisanje, a i kraći od primera 12 za 13 vorda.

Naredbom “latb=1” postavimo početnu vrednost za leč porta B, tj. uključimo LED D1. Nakon toga u “While … Wend” petlji pravimo pauzu koliko želimo da nam svetli jedna LED i zatim vrednost leča množimo sa 2 kako bismo dobili sledeću vrednost. Zatim imamo novu naredbu čiji je osnovni oblik “IF … THEN” (kompletna sintaksa će biti objašnjena u sledećoj poruci) koja vrši poredjenje vrednosti registra LATB i ako je nula, dodeljuje mu ponovo vrednost 1, tj. ponovo uključuje D1.

Postavlja se pitanje kako je moguće da vrednost LATB registra bude 0 ako je početna vrednost 1, a svaka sledeća je duplo veća. To je zato što je LATB registar 8-bitni tj. njegova maksimalna vrednost je 255. Posle sedmog množenja njegova vrednost je 128 što znači da posle sledećeg množenja vrednost treba da bude 256, ali ona prevazlilazi maksimum za bajt pa njegova vrednost postaje 0. Da nam je potrebna regularna vrednost matematičke operacije, ovo bi bila greška, tj. očekivani rezultat nikada ne bismo dobili, ali u ovom slučaju nam ta greška omogućava da proverimo da li je trčeće svetlo došlo do poslednje kombinacije kako bismo ponovo postavili početnu.

Veličina iskompajliranog programa: 81 Word-a

May 062013
 

Ovo je isti program kao i prethodni, ali uz ograničenje broja izvršavanja petlje.

Tutor13.bas

najverovatnije da ste primetili da se u svakom programu u okviru ovog tutorijala nalazi i naredba Include o kojoj do sada nije bilo reči. Naredba kao parametar ima naziv fajla koji će prilikom kompajliranja biti ubačen na mesto gde se nalazi naredba Include.

Puna sintaksa je:

Include “ImeFajla”

Veličina iskompajliranog programa: 126 Word-a

May 062013
 

Ovaj program pali svih 8 LED sekvencijalno jednu po jednu praveći tzv. trčeći “light show”. Upotrebom konstante ‘pauza’ lako i brzo možemo da menjamo vreme izmedju dve promene, tj. da odredimo brzinu “trčanja” LE dioda.

Tutor12.bas

Vidimo da smo prvo isključili sve LED naredbom PORTB=0, a tek zatim postavili ceo B port kao izlazni. Na prvi pogled ovo bi moglo da deluje nelogično, ali obzirom da je po uključenju stanje B porta unapred nepoznato tj. proizvoljno, a sam port postavljen kao ulazni, ako bismo prvo postavili B port kao izlazni desilo bi se da bi neka od LED zasvetlela. Doduše, u našem slučaju to bi trajalo svega nekoliko µs što mi ne bismo primetili i nije toliko ni bitno, ali u slučaju da umesto LE diodama upravljamo nekim uredjajima kod kojih je to kratkotrajno uključenje nepoželjno, došlo bi do problema. Zato je dobra praksa da se pre prebacivanja porta u izlazni režim postavi početno stanje porta.

U tehničkim podacima u tabeli “TABLE 3-8” možete da vidite stanja svih registara nakon reseta; predzadnja kolona pokazuje stanja nakon POR (Power-On Reset, reset nakon uključenja napajanja) i BOR (Brown-Out Reset, reset nakon pada napona ispod dozvoljene granice), a zadnja pokazuje stanja nakon svih ostalih reseta. Na osnovu toga možete da vidite da li po uključenju imate potrebe da postavite odredjeno početno stanje za neki registar.

Za razliku od PBP, PDS ne poseduje DO … LOOP petlju.

Od petlji postoje:
For … Next
While … Wend
i
Repeat … Until

Vidimo i da smo izbacili GOTO naredbu i ubacili dve nove, While i Wend, koje čine celinu, a puna sintaksa glasi:

While uslov 

  naredba...  

Wend

Ova naredba se koristi za ponavljanje bloka naredbi koje se nalaze izmedju While i Wend

Za prevremeni izlaz iz petlje može da se upotrebi naredba Break.

Takodje vidimo i da smo sve naredbe izmedju While i Wend pomerili udesno što nije obavezno, ali je dobra programerska praksa kako bi se jasno video blok naredbi tj. jedna petlja. Ta praksa naročito može da bude korisna ako imate ugnježdene petlje, tj. petlju unutar petlje pa lako možete da vidite da li ste sve petlje “zatvorili” jer ako niste, kompajler će da javi grešku, a ako ste sve pisali ravno, imaćete problem da brzo utvrdite gde ste pogrešili.

Primeri upotrebe:

    i = 1  
    While i > 10
      SEROUT 0,N2400,[“No:”,#i,13,10] 
      i = i + 1  
    Wend 
 
 
    i = 1  
    While i <= 10  
      SEROUT 0,N2400,[“No:”,#i,13,10] 
      i = i + 1  
   Wend 
 
 
    i = 1  
    While  i <= 10
      SEROUT 0,N2400,[“No:”,#i,13,10] 
      i = i + 1  
      IF PORTB.0 = 0 THEN Break
    Wend 

 Veličina iskompajliranog programa: 119 Word-a

May 062013
 

Sada ćemo da napišemo program iz primera 3 uz upotrebu konstanti i aliasa.

Tutor11.bas

Vidimo da je program potpuno iste dužine kao i onaj iz primera 3, ali nam je sada lakše da promenimo pauzu izmedju uključenja i isključenja LED D1. Takodje je jednostavnije i promeniti LED sa kojom radimo, uz napomenu da pri promeni LED treba podesiti i TRISB registar.

Veličina iskompajliranog programa: 73 Word-a