[ rsinisa @ 26.07.2012. 08:11 ] @
Ovu temu sam zamislio kao pomoć početnicima ili onima sa nedovoljno iskustva da svaladaju rad sa PIC mikrokontrolerima i PicBasic Pro verzija 3 kompajlerom pošto se povremeno neko od njih javi ili na forum ili na privatnu adresu nekog od poznavalaca materije.

Krenućemo od nekih osnova, ali nećemo se za početak previše baviti teorijom - biće tu nešto malo uvoda pa ćemo jako brzo da predjemo na konkretne primere i uz njih objašnjavati teorijski deo kao i hardverske komponente mikrokontrolera.

Voleo bih da se sve poruke ovde odnose isključivo na temu, da se ne bavimo time šta je bolje, PIC , ATMEL ili nešto treće, ovaj ili onaj PIC itd, itd. Za tako nešto možete da iskoristite ovu temu:
http://www.elitesecurity.org/t453061-PIC-PBP-tutorial
ili otvorite novu. Uostalom, nije loše da pročitate ovu temu, ako već niste.

Što se tiče dinamike tekstova, imajte na umu da ja ovo radim u slobodno vreme (koga danas skoro niko nema previše) pa ne mogu ništa da obećam, ali ću da se trudim da bude bar 1 nedeljeno.

Pozdrav.
Sinisha


[ rsinisa @ 29.07.2012. 23:08 ] @
Ako hoćete da učite po ovom tutorijalu biće vam potrebne 3 stvari:

1. PICBASIC Pro 3 kompajler čiju probnu verziju, potpuno funkcionalnu u trajanju od 15 dana, možete da skinete sa sajta tvorca kompajlera:
http://pbp3.com/download.html
Prvi fajl od 122 MB sadrži sve što je potrebno, kompajler, MPLAB i IDE pod nazivom "Micro Code Studio" (u daljim tekstovima MCS), dok je drugi bez MPLAB-a i podrazumeva da ga već imate instaliranog (verziju 8.85).

2. programator za 16F1827.
Obzirom da ovaj PIC pripada novoj generaciji 8-bitnih PIC-eva sa unapredjenim jezgrom (enhanced na engleskom), malo je programatora koji mogu da ga programiraju i to jeste donekle problem. Tačnije, meni su za sada poznata samo dva programatora koji ga provereno programiraju, a to su PICKit 2 i PICKit 3 (PK2 i PK3 u daljim tekstovima). Po priči mnogih, PK2 se, iako stariji, pokazao bolje od PK3, ali ostaje na vama da se odlučite.
Ako radite u WINDOWS operativnom sistemu onda vam je svejedno, ali ako radite u LINUX-u, morate da znate da za PIC-eve sa unapredjenim jezgrom ne postoji podrška za PK2, tako da vam ostaje PK3. Pošto ja nemam PK3 molim one koji ga imaju, a rade u LINUX-u, da napišu ako imaju iskustva sa programiranjem ovih piceva sa unapredjenim jezgrom.
Medjutim, ovih dana ću da testiram dva programatora koja bi trebalo da rade i pod WINDOWS i pod LINUX OS-om, od kojih je jedan predvidjen za serijski, a drugi za USB port tako da će, ako sve bude kako treba, postojati mogućnost izbora za sve opcije.
Postoji i softver WINPIC800 koji u spisku podržanih ima ovaj PIC, ali ne može da se programira sa JDM baziranim hardverom. Koji hardver omogućava to, ne znam, ako neko ima iskustva neka napiše ovde.

3. Hardver na kome ćemo isprobavati programe.
U pripremi je mini razvojni sistem koji će nam pomoći u tome, uskoro će biti postavljena njegova shema (koncept možete da vidite ovde http://www.elitesecurity.org/p3140549) i nacrt za PCB.

Postoji i četvrta stvar koja nije neophodna, a može da posluži umesto hardvera, a to je program PROTEUS koji u sebi ima i odličan simulator pomoću koga će moći da se simulira možda i sve što ćemo ovde da radimo, tako da vam razvojni sistem i neće biti potreban, ali ipak preporučujem da se sve proba i na pravom hardveru.
Na ovoj adresi možete da skinete probnu verziju koja je potpuno funkcionalna sem učitavanja, snimanja i štampanja vaše sheme:
http://www.labcenter.com/download/prodemo_autodl_general.cfm

Pozdrav.
Sinisha
[ rsinisa @ 02.08.2012. 17:56 ] @
Dobre vesti za one koji bi da prate i isprobavaju primere koje ćemo da obradjujemo: pronašao sam još 2 programa koji mogu da programiraju PIC 16F1827 od kojih jedan omogućava nekoliko tipova programatora, a drugi je predvidjen za USB port, i za oba postoje verzije za LINUX i za WINDOWS operativni sistem. Oba su potpuno besplatna i javno dostupna.

Prvi program se zove WxPic koji podržava nekoliko tipova hardvera, a ja sam bio u prilici da probam sa ALLPIC-om koji je JDM baziran (mada u opcijama za hardver treba odabrati COM84). Da bi PIC16F1827 mogao da se programira, potrebno je modifikovati jedan fajl, a modifikaciju sam opisao ovde:
http://www.elitesecurity.org/p3146048

Drugi program je OpenProg, predvidjen za USB port, i to je ustvari komplet hardver + softver, a sve što je potrebno za njegovu izradu i korišćenje možete da pogledate na sledećem linku:
http://openprog.altervista.org/OP_eng.html

Eto, sada su pokriveni i LINUX i WINDOWS OS, kao i serijski i USB port, pa svako ko planira da prati ove tekstove kroz praktične primere, sada može da odabere šta mu odgovara.

Pozdrav.
Sinisha
[ rsinisa @ 09.08.2012. 21:54 ] @
Krećemo sa prvim tekstom u ovom tutorijalu u kome ćemo da se osvrnemo na neke teorijske stvari. Pre toga da napomenem da razvojni sistem nije još gotov, kao i da postoji još jedan USB PIC programator koji je napravljen po uzoru na PK2 (iako nije kopija već samostalan proizvod) koji se zove usbpicprog. Nisam ga još napravio, podrška za PIC16F1827 postoji, ali nije testirana. Ko je raspoložen za njegovu izradu može da pogleda sajt na kome se nalazi sve što je potrebno.
http://usbpicprog.org/
Za njega postoji softverska podrška za linux, windows i macintosh, tako da su sada sve opcije pokrivene i više nećemo da se bavimo novim programatorima, ova 3 pomenuta su više nego dovoljna.

Šta je to mikrokontroler
================
Pojava mikroprocesora, čipova koji su mogli da izvršavaju neki korisnički program, napravila je revoluciju u elektronici omogućivši izradu raznih uredjaja koji su odjednom postali manji, brži, sa više mogućnosti, pa čak dovela i do pojave prvih kompjutera.

Mikrokontroler nije isto što i mikroprocesor, moglo bi da se kaže da je mikrokontroler u stvari njihova nadgradnja. Mikroprocesor se sastoji od aritmetičko-logičke jedinice, nešto malo RAM-a i adresne magistrale kojom su se povezivali sa spoljnom memorijom i ulazno-izlaznim jedinicama. Neki od njih imaju u sebi i programsku memoriju u kojoj se nalazi program koji izvršavaju, dok ostali zahtevaju spoljnu memoriju.

Mikrokontroler takodje sadrži aritmetičko-logičku jedinicu, ali ne poseduje adresnu magistralu jer ima integrisanu programsku memoriju, a uz to ima ugradjene mnoge druge hardverske komponente, kao što su logički ulazno-izlazni pinovi, brojači, tajmeri, oscilatori, RAM, EEPROM, PWM moduli, A/D i D/A konvertori, komparatori, watch-dog tajmeri itd. Moglo bi da se kaže da su mikrokontroleri kompjuteri u malom - uz dodatak neke ulazne jedinice za komunikaciju sa korisnikom (tastatura, miš) i izlazne za prikaz rezultata (ekran, štampač) može da se napravi kompjuter koji bi daleko prevazišao performanse nekadašnjih kompjutera baziranih na osmobitnim mikropocesorima (npr. Z80). Naravno da danas ne bi imalo mnogo smisla praviti takve kompjutere, ali sa mikrokontrolerima možemo da napravimo mnoge zanimljive uredjaje koji mogu da nam posluže za zabavu, edukaciju pa čak i zaradu.

Treba imati na umu da se danas mikrokontroleri nalaze svuda: u digitalnim satovima, digitalnim fotoaparatima, mašinama za izradu fotografija, kafematima, punjačima baterija (ima ih i u samim baterijama), u džepnim baterijskim lampama, pa i u igračkama. U modernim automobilima ih ima na desetine i većina njih komunicira medju sobom (npr. samo u volanu može da ih bude nekoliko).

Cilj ovog tutorijala nije da napravimo neki visoko komercijalan uredjaj već da zainteresovani mogu da nauče osnove rada sa njima, jer je početniku upravo najveći problem da nauči osnove - ako to nema odakle da savlada, početni entuzijazam može brzo da predje u razočaranje.

Postoje mnogi proizvodjači mikrokontrolera, a svaki od njih ima nekoliko familija. Odlučiti se za nekog proizvodjača početniku je jako teško i postoje mnoga mišljenja oko toga šta je za početnika bolje. Mi nećemo da se bavimo tim pitanjima, ovo će biti tutorijal za mikrokontroler proizvodjača "Microchip" i to iz 8-bitne famillije sa unapredjenim jezgrom sa oznakom PIC16F1827. Učićemo kako se za njega pišu programi u programskom jeziku PICBasic Pro, a verovatno ćemo povremeno da se dotaknemo i asemblera. Kasnije, kada savlada osnove, svako može da odluči hoće li da ostane uz Microchip proizvode ili želi da predje na proizvode drugog proizvodjača u zavisnosti od potreba ili nekih drugih razloga.


[Ovu poruku je menjao rsinisa dana 09.08.2012. u 23:05 GMT+1]
[ rsinisa @ 10.08.2012. 22:26 ] @
Hteo bih da se osvrnem na samu reč "mikrokontroler" jer bi mogla pogrešno da se shvati. Naime, reč kontrola nema isto značenje u našem jeziku kao u engleskom. U našem jeziku ta reč označava nadzor, proveru, dok u engleskom jeziku ta reč (controll) označava upravljanje, tako da bi neki bukvalni prevod reči mikrokontroler bio mikroupravljač. Naravno, u našem jeziku se reč mikrokontroler odomaćila i svi poznavaoci materije znaju o čemu se radi tako da ćemo i mi ovde da je koristimo, a ona neće biti jedina koja se koristi u svom izvornom obliku, mada ću ja da se trudim da, kad god to ima smisla, koristim naše reči koje su manje-više odgovarajuće za neke pojomove. Ovo isključivo iz razloga što mislim (a postoje i neki dokazi od pametnih ljudi) da mnogi hoće da unište na razne načine naša nacionalna obeležja, a jedno do njih je svakako jezik.

Smatram da mi Srbi treba da budemo samosvesni i da se trudimo da sami očuvamo, koliko god je to moguće, naš nacionalni identitet na svim poljima, a jedno od njih je i jezik. Činjenica je da ima mnogo mladih koji su pročitali više teksta od svojih drugara preko raznih društvenih mreža nego iz knjiga domaćih autora i zato ne treba nikome zameriti jer je veoma moguće da za neke reči iz tehničke oblasti mladja populacija jednostavno ne zna domaći izraz. Naravno, nisam ni ja lingvista niti poznajem sve te reči, ali ću da se trudim koliko znam i umem da koristim domaće reči tamo gde to ima smisla.
Malo sam skrenuo sa teme i to je neka druga priča, za neko drugo mesto, ali sam hteo da obrazložim ukoliko naidjete na neku reč za koju smatrate da nije adekvatna za ovu oblasti, ili vam se učini besmislena.

Neke stvari će ovde biti objašnjene ukratko, ili možda karikirano i nedovoljno kako se ne bi uplitali u neke, bar za početak, nebitne stvari, a verovatno ću negde i da napravim grešku pa molim sve koji smatraju da nešto nije napisano kako treba, da se slobodno jave i isprave me.



[Ovu poruku je menjao rsinisa dana 11.08.2012. u 00:41 GMT+1]
[ rsinisa @ 10.08.2012. 23:34 ] @
Programiranje mikrokontrolera
====================
Kao što smo već rekli, mikrokontroler ima u sebi programsku memoriju u kojoj se nalazi program koji treba da se izvršava i upravlja nekim uredjajima i procesima. Postoje mikrokontroleri (u daljem tesku MCU od engleskog izraza "microcontroller unit") koji u sebi već imaju fabrički, u toku proizvodnje, upisan neki program, ali oni su specijalizovani za odredjene namene i nama nisu od neke koristi - nas zanimaju oni koje možemo sami da programiramo prema svojim potrebama. Pošto takvi MCU-i dolaze sa potpuno praznom programskom memorijom, kada bi ih ubacili u naše kolo koje smo projektovali, ništa se ne bi desilo, naše elektronsko čedo bilo bi potpuno "mrtvo", pa je potrebno da mi sami napišemo program i smestimo ga u programsku memoriju. PIC kontroler koji ćemo mi da koristimo ima tzv. FLASH (čita se fleš) programsku memoriju, odn. memoriju u koju možemo više puta da upisujemo naš program, brišemo ako nešto nije dobro, i ponovo upišemo drugi program. Broj takvih piši-briši ciklusa kod PIC MCU-a obično se kreće od 10 000 do 100 000 tako da nam je jedan PIC više nego dovoljan za eksperimetisanje. Jedna od osobina fleš memorije je da i nakon isključenja napona napajanja njen sadržaj ostaje nepromenjen, tako da je naš uredjaj spreman za rad pri savakom uključenju bez ponovnog programiranja. Sledeće logično pitanje koje se postavlja je kako se programira MCU.

Mašinski jezik i asembler
================
Pošto MCU pripada familiji digitalniih čipova koji prepoznaju isključivo dva stanja - nema napona što se obeležava sa cifrom 0, i ima napona što se obeležava sa cifrom 1, sve što on razume su instrukcije koje se sastoje iz nula i jedinica i te instrukcije se nazivaju mašinski jezik, što je prirodni "jezik" svakog mikroprocesora i mikrokontrolera. Brojni sistem u kome se koriste samo dve cifre zove se binarni brojni sistem ("bi" znači dva, i o brojim sistemima će biti reči kasnije) i on je najnepogodniji za čoveka i bilo bi jako teško i sporo pisati programe u tom obliku. Zato je osmišljen asembler, programski jezik najnižeg nivoa kod koga je za svaku mašinsku instrukciju, tj. za nizove nula i jedinica, osmišljena reč ili skraćenica koja je mnogo razumljivija za čoveka i kod koga svaka asemblerska instrukcija predstavlja jednu jedinu mašinsku instrukciju.
Doduše, da budem iskren, imao sam prilike da vidim da tvorci asemblera, ne bi li olakšali malo programerima, ugradjuju instrukcije koje se najčešće sastoje iz 2 ili 3 mašinske koje prirodno "idu zajedno". Takva je npr. instrukcija "bnz" u Microchipovom asembleru za PIC kontrolere koja ne postoji (bar kod 8-bitnih PIC-eva) i koja se u stvari sastoji iz dve mašinske instrukcije.
Pojavom asemblera programeri su znatno ubrzali pisanje programa jer je bilo mnogo lakše pamtiti skraćenice nego nizove 0 i 1. Tako napisan program je asembler prevodio u mašinski jezik koji se upisivao u mikroprocesore i kasnije mikrokontrolere.

Da napravim malu digresiju: svoje prve mašinske programe za mikroprocesor Z80 sam pisao na ZX-81 kompjuteru, ali pošto tada nisam imao asembler za njega, program sam pisao na papiru u asembleru, a onda iz tabele instrukcija ručno prevodio u brojeve koje sam, takodje ručno, upisivao u memoriju ZX-81 i izvršavao (iz ovoga se može zaključiti da nisam baš mlad). Ubrzo se pojavio čuveni paket sa asemblerom (pod nazivom GENS3M) i disasemblerom (MONS3M) i stvari su postale mnogo lakše.

Medjutim, asembler je, pošto je jezik najnižeg nivoa, ipak bio spor za pisanje jer mnogi tadašnji mikroprocesori, pa i današnji mikrokontroleri sem sabiranja, oduzimanja na nivou jednog bajta, i uporedjivanja nisu imali nikakve druge artimetičke operacije, pa je za svaku složeniju matematičku operaciju bilo potrebno napisati mnogo linija programa u asembleru te se tako pojavila potreba za drugim jezicima kod kojih se jedna linija programa prevodi u nekoliko asemblerskih, pa čak i u čitave potprograme. Tako su nastali viši programski jezici, iliti jezici višeg nivoa.
Oni su znatno ubrzali pisanje programa, ali je asemblerski jezik i danas povremeno u upotrebi - neki isključivo koriste njega jer su ili takve potrebe, ili su oni jednostavno zaljubljenici (neki bi rekli zaludjenici), a neki kombinuju viši programski jezik sa kritičnim delovima pisanim u asembleru jer se najbolja i napreciznija kontrola ostvaruje upravo primenom asemblera.


[Ovu poruku je menjao rsinisa dana 11.08.2012. u 00:44 GMT+1]
[ rsinisa @ 12.08.2012. 15:58 ] @
Viši programski jezici
==============
Program koji je napisan u nekom programskom jeziku zove se izvorni program, a uobičajen naziv je i sors (od engleske reči source - izvor) i predstavlja u stvari tekst samog programa (tesktualni fajl) i ako su potrebne izmene, prepravi se i ponovo kompajlira. Iz izvornog programa uvek može da se napravi mašinski, dok je obrnut slučaj moguć samo za asembler (i taj program se zove disasembler).

Kao što smo već rekli, viši programski jezici su se javili zbog potrebe bržeg pisanja programa i ograničenih mogućnosti mikroprocesora i mikrokontrolera. Npr. jedan prost izraz u nekom višem programskom jeziku kao što je:

a = 2 + 3

bi u PIC asembleru izgledao otprilike ovako:

movlw 2
addlw 3
movwf a

Iako je ovo najprostiji primer, već se ovde vidi koliko je za čoveka prirodnije napisati ovaj izraz u višem jeziku. Za izraz tipa:

a=(2 + 3) * 4

ne treba ni trošiti vreme, pogotovo što PIC koji ćemo da koristimo nema instrukciju za množenje, tako da bi ceo ovaj program imao desetak linija u asembleru.

Možemo da kažemo da danas na tržištu postoje praktično 3 viša programska jezika za PIC MCU, a to su: C, BASIC i PASCAL.

C je definitivno postao standard i ako želite da se zaposlite u nekoj firmi ili prodajete svoje izvorne programe drugima, najbolje da se odmah opredelite za njega; mada, ako ste baš apsolutni početnik i nemate drugi način da naučite osnove, krenite od ovog tutorijala, naučite osnove PBP-a pa se prebacite na C.
Ja sam pre mnogo godina napisao nekoliko programa za PC u C-u, ali mi je njegova sintaksa jednostavno odbojna i meni je on potpuno nezanimljiv i nisam ga koristio za mikrokontrolere. Obzirom da nemam iskustva sa C-om, mogu samo da pretpostavim da je njegova sintaksa standardizovana kod svih proizvodjača i verujem da su razlike, ako postoje, minimalne tako da bi, kada jednom savladate C, trebalo bez većih problema da možete da pišete programe za razne MCU-e.

Meni BASIC sasvim odgovara za moje skromne potrebe, mada moram da kažem da sam u BASIC-u pisao bez problema i znatno složenije programe. Ako pišete programe isključivo za sebe i svoje potrebe, možete slobodno da se posvetite BASIC-u, sintaksa nije komplikovana mada se malo razlikuje kod nekih kompajlera, ali ćete moći za kratko vreme da je savladate. Kao što smo već rekli, koristićemo PICBasic Pro kompajler koji je relativno skroman po svojim mogućnostima, ali po mom iskustvu sasvim je primeren PIC-u na kome ćemo da učimo.
Takodje prilično popularan, a veoma sličan PBP-u je PROTON BASIC kompajler koji ima nešto više instrukcija i većina programa pisanih u PBP-u može uz minimalne izmene da se kompajlira u PROTON-u.

Kada je u pitanju PASCAL, znam jedino za "MikroPASCAL PRO" domaćeg proizvodjača "Mikroelektronika"; možda postoje i drugi, ali meni nije poznato.

Većina viših programskih jezika omogućava mešanje i asmeblerskih instrukcija jer, kako smo već rekli, jedino uz pomoć njega možemo da napišemo kritične delove programa za koje moramo da znamo tačno za koje vreme se izvršavaju ili koje sve registre menjaju i sl. U većini slučajeva to nije neophodno, ali ja volim da u PBP ubacujem ponegde i asemblerske instrukcije pa će biti toga i u ovom tutorijalu. Još jedan razlog zbog koga volim je PBP što je stil pisanja donekle sličan asembleru pa imam utisak skoro potpune kotrole dešavanja.

Kako se pišu programi
===============
Moderni kompajleri imaju takozvano integrisano razvojno okruženje (na engleskom IDE - integrated development enviroment) u kome kucate program i pritiskom na jedan taster (ili jednim klikom na ikonicu) vaš izvorni program se prevodi u mašinski. Ako ima grešaka u programu, kompajler će da vas obavesti o tome, a ako nema, dobićete takozvani HEX fajl (fajl sa nastavkom .hex) koji se uz pomoć programatora ubacuje u mikrokontroler.
Ovde nećemo da pominjemo konkretne načine programiranja za razne programatore (sem ako bude izričitih zahteva), ali je suština kod svih maltene ista: startujete program, priključite programator na odgovarajući port računara, dovedete spoljno napajanje (ako je potrebno), podesite hardver (ako je potrebno), učitate hex fajl i kliknete na ikonu za upis programa u PIC. Posle par sekundi program će vam javiti da li je programiranje uspelo ili ne.
[ rsinisa @ 13.08.2012. 21:48 ] @
Iako sam planirao da teorijski uvod bude kratak, zaključio sam da je bolje da se neke bitne stvari objasne detaljno kako bi se postavila dobra osnova i neke stvari kasnije lakše shvatile. Prema tome, idemo dalje sa teorijom.

Broj(ev)ni sistemi
============
Opšte prihvaćen izraz je brojni sistem, mada se meni izraz brojevni sistem čini logičnijim, ali ćemo ipak koristiti prvi. Pre nego što obradimo temu, moram da kažem da sam primetio da neki ljudi ne razlikuju termin "broj" od "cifra", pa treba reći da je broj sastavljen od cifara, cifra je osnovni element za zapisivanje brojeva, kao što je slovo za reči.

Šta je brojni sistem? To je sistem, odnosno način, zapisivanja brojeva. Čudna mi čuda, pa to smo svi naučili još u osnovnoj školi (neki i pre), svi znamo da pišemo brojeve. Tačno, ali mi smo naučili dekadni brojni sistem koji je prirodan za nas, ali zato veoma nepogodan za rad sa digitalnom elektronikom. U tekstu o mašinskom jeziku napomenuli smo da mikrokontroleri mogu da rade sa samo dva stanja, a to su 0 i 1, što znači da znaju da rade samo u binarnom brojnom sistemu pa je dobro da ga i mi naučimo kako bi smo bolje razumeli neke stvari.

Hm, ako postoje dekadni i binarni, da li postoje još neki brojni sistemi? Naravno, moguće je napraviti bilo koji brojni sistem, sa bilo kojim brojem cifara, samo je pitanje ima li ikakve svrhe koristiti brojni sistem sa npr. 7 cifara (0, 1, 2, 3, 4, 5, 6). Ili npr sa 13 cifara, tačnije znakova. Doduše, sistem sa 3 cifre: 0, 1 i 2 koji bi se zvao (verovatno) trinarni bi imao primenu u realnom svetu, s tim što bi možda bolje bilo da brojevi budu -1, 0 i 1. Jedan od primera bi bio lift: 0 bi značilo da lift stoji, 1 da ide naviše, a -1 da ide naniže. Nekada se koristio i oktalni brojni sistem (sa osnovom 8), mada ga ja u praksi do sada nisam susreo.

Postoji još jedan brojni sistem koji se često koristi u praksi, zove se heksadekadni i koristi 10 cifara i 6 znakova, a to su: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E i F, gde slova od A do F predstavljaju brojeve od 10 do 15 respektivno. Videćemo kasnije čemu on služi.

Broj cifara koji čine brojni sistem zove se baza ili osnova, što znači da je dekadni sistem u stvari sistem sa osnovom 10, binarni sa osnovom 2, heksadekadni sa osnovom 16 itd. Svaki od ova 3 ćemo da obradimo detaljnije.


[Ovu poruku je menjao rsinisa dana 13.08.2012. u 22:58 GMT+1]
[ rsinisa @ 14.08.2012. 21:26 ] @
Dekadni brojni sistem
===================
To je brojni sistem koji srećemo svuda oko nas i koji je za ljude potpuno prirodan jer je nastao iz činjenice da mi imamo 10 prstiju. Da smo se rodili sa 8, najverovatnije da bi oktalni sistem bio nama najpogodniji i da nam dekadni nikada ne bi zatrebao.
Na dekadnom sistemu ćemo da shvatimo princip formiranja brojeva i računanja njihovih vrednosti što će da nam pomogne da lakše shvatimo isto to za bilo koji drugi brojni sistem.

Uzećemo, na primer, broj 3747, za koji svi znamo koja je to vrednost i znamo da krajnja leva cifra označava koliko ima hiljada u njemu, druga cifra gledano sa leva označava koliko ima stotina, treća cifra sa leva označava koliko ima desetina i poslednja sa leva označava koliko ima jedinica. To znači da ovaj broj možemo da napišemo i ovako:
3*1000 + 7*100 + 4*10 + 7*1.

Krajnja leva cifra u svakom broju zove se cifra najveće težine i kako idemo u desno tako vrednost cifre opada, a krajnja desna je cifra najmanje težine što se i vidi iz razloženog zapisa broja - vidimo da u našem broju imamo dve iste cifre, dve sedmice, ali vidimo da leva sedmica ima veću težinu jer označava stotine, dok krajnja desna sedmica označava jedinice. Vidimo da je vrednost svake leve cifre tačno 10 puta veća od one sa desne strane, a to je upravo zato što koristimo dekadni sistem, odn. sistem sa 10 cifara. Kada smo to shvatili, vidimo da isti izraz možemo da napišemo i ovako:
3*103 + 7*102 + 4*101 + 7*100
Malo objašnjenje za one koji ne stoje najbolje sa stepenovanjem: svaki broj stepenovan sa nulom jednak je 1, zato smo i krajnju desnu cifru upravo napisali korišćenjem osnove 10 stepenovanu sa nulom.

Vidimo da se broj 10 stepenuje sa mestom na kome se nalazi umanjenim za 1: za cifru na prvom mestu (krajnjem desnom) broj 10 (osnova) stepenuje se sa 0, za cifru na drugom mestu osnova se stepenuje sa 1, za cifru na trećem mestu osnova se stepenuje sa 2 i tako dalje. To znači da npr. broj 253068 možemo da predstavimo sledećim izrazom:
2*105 + 5*104 + 3*103 + 0*102 + 6*101 + 8*100
Ovde je cifra najveće težine 2 (na engleskom: most significant digit, skraćeno MSD), a cifra najmanje težine je 8 (na engleskom: less significant digit, skraćeno LSD).

Iz svega ovoga proizilazi formula kojom možemo da izračunamo dekadnu vrednost bilo kog broja zapisanog u bilo kom drugom brojnom sistemu:

Xn * Bn-1 + Xn-1 * Bn-2 + ... + X2 * B1 + X1 * B0

gde X predstavlja cifru na nekom mestu, n mesto na kome se nalazi cifra gledano sa desna u levo, i B bazu (osnovu) brojnog sistema (10 za dekadni, 2 za binarni, 16 za heksadekadni itd).

PBP ne "poznaje" decimalne brojeve, ali ćemo ukratko, radi kompletnosti teksta, napisati i kako se zapisuju decimalni brojevi, što je, videćete, vrlo jednostavno, a i logično.
Broj 42,573 primenom izraza za dekadni sistem može da se napiše kao:

4*101 + 2*100 + 5*10-1 + 7*10-2 + 3*10-3

dok bi univerzalni izraz izgledao ovako:

Xn * Bn-1 + Xn-1 * Bn-2 + ... + X2 * B1 + X1 * B0 + X-1 * B-1 + X-2 * B-2+ ... + X-n * B-n

gde se mesta desno od decimalnog zareza obeležavaju sa -1, -2 itd. gledano od zareza.
[ rsinisa @ 17.08.2012. 12:25 ] @
Binarni brojni sistem
==============
Kao što mu ime kaže, sastavljen je od samo 2 cifre, 0 i 1, i uz pomoć njih moguće je predstaviti sve brojeve, pa čak i decimale. One nas, za sada, ne zanimaju pa ćemo ukratko da obradimo cele brojeve.
Pošto imamo samo dve cifre, kako ćemo onda napisati npr. broj 2? Isto kao i kod decimalnog sistema, dopisivanjem cifara veće težine. Za broj 0 treba nam samo jedna cifra i on se u binarnom sistemu piše kao i u bilo kom drugom: 0. Broj jedan takodje se logično piše: 1. Pošto cifra 2 ne postoji u binarnom sistemu, moramo da prenesemo jednu cifru na mesto veće težine pa ćemo broj 2 da predstavimo sa: 10. Broj 3 predstavljamo tako što uvećavamo za 1 cifru najmanje težine pa pišemo: 11. Napisaćemo sada tabelu sa nekoliko prvih binarnih brojeva i njihovih dekadnih vrednosti:

0 = 0
1 = 1
10 = 2
11 = 3
100 = 4
101 = 5
110 = 6
111 = 7
1000 = 8
1001 = 9
1010 = 10 itd.

Proverićemo sada pomoću gore napisane formule da li je dekadna vrednost binarnog broja 1001 zaista 9.
Ako u formuli

Xn * Bn-1 + Xn-1 * Bn-2 + ... + X2 * B1 + X1 * B0

zamenimo B sa 2, jer je za binarni brojni sistem to baza, dobićemo sledeće za 1001:

1*23 + 0*22 + 0*21 + 1*10 = 8 + 0 + 0 + 1 = 9
[ rsinisa @ 19.08.2012. 16:27 ] @
Bit, bajt, vord
=========
Pre nego što predjemo na heksadekadni sistem, ovo je idealan momenat da objasnimo pojmove kao što su bit, bajt i vord.

Bit
---
U svetu digitalne elektronike binarni sistem je osnova svega jer je sve predstavljeno sa samo 2 nivoa: 0 za nema napona i 1 za ima napona. Da budem skroz precizan, postoji i nešto što se zove negativna logika gde su sada stanja zamenjena, pa se 0 upotrebljava za informaciju da ima napona, a 1 da nema.
Npr. ako imamo jedan prekidač, potrebna nam je informacija da li je on isključen ili uključen, i ta jedna informacija je osnovna informacija u digitalnoj elektronici koja se zove bit. Još jednom, bit je minimalna i osnovna informacija koja može da zauzme samo 2 stanja, 0 ili 1. Oznaka za bit je "b" (malo slovo b).

Bajt
----
Sa jednim bitom možemo, kao što smo videli, da prenesemo informaciju od samo 2 stanja, ali šta ako nam je potrebno da prenesemo više informacija? Zato je osmišljena veća jedinica koja se zove bajt i sastoji se iz 8 bitova što znači da je njegova maksimalna vrednost 11111111, što u dekadnom sistemu iznosi 255 (ko ne veruje neka proveri kroz formulu). Znači, jedan bajt može da sadrži ukupno 256 informacija (28), tj. bilo koji broj od 0 do 255. Oznaka za bajt je "B" (veliko slovo B).
Logično pitanje koje se postavlja je zašto je za bajt uzeto 8 bitova, a ne neki drugi broj, npr. 10? Pošto računari ne znaju za slova, interpunkcije i ostale simbole, trebalo ih je kodirati, tj. svaki od simbola predstaviti nekim brojem. Engleski alfabet ima 26 slova, sa velikim i malim slovima to čini 52, sa još 10 cifara, nekoliko znakova za interpunkciju i kontrolnih karaktera bilo bi potrebno nešto oko 100 kodova. Za 100 brojeva treba nam 7 bitova (jer sa 6 imamo samo 64 kombinacije: 26), ali je izabran broj 8 jer je u svetu digitalne elektronike sve podredjeno stepenu broja 2, a 8 je upravo 23.
Takodje treba pomenuti 1000 puta veću jedinicu, a to je kilobajt (piše se KB) koji u stvari nema 1000 bajtova već 1024. To je opet zbog stepena broja 2 jer je 210 upravo 1024, a to je najbliže broju 1000. Na isti način, 1 megabajt (MB) ima 1024 kB, tj. 1 048 576 bajtova.

Vord
----
Na engleskom se piše "word" i znači "reč", a radi se o 2 bajta, tj. 16 bitova, što znači da može da zauzme bilo koje stanje od 0 do 65535. U praksi se taj izraz povremeno sreće i za svaki broj koji ima od 9 do 16 bitova.
Nedavno sam jednom profesoru koji predaje osnove računara pomenuo tu memorijsku jedinicu, na šta je on rekao da nije čuo za to i da to ne postoji. Pa ... možda u "mudrijaškim" knjigama zaista ne postoji, ali ćete je u svetu mikrokontrolera često sretati.
Postoji još i izraz "long word" (dugačka reč) ili "double word" (dupla reč) što je naziv za 2 vorda koji sada čine jedan broj. Njegovu maksimalnu vrednost izračunajte sami.

Obzirom da je u svetu digitalne elektronike osnovna jedinica bit, krajni levi, bit najveće težine, obeležava se skraćenicom MSB (od engleskog "most significant bit" - bit najveće težine), dok se krajnji desni, bit najmanje težine obeležava sa LSB (od engleskog "less significant bit" - bit najmanje težine) što ćete povremeno sretati u praksi.
[ rsinisa @ 24.08.2012. 15:39 ] @
Heksadekadni sistem
==============
Iako brojni sistem sa osnovom 16 izgleda potpuno besmisleno, on je svoju praktičnu primenu u svetu računara doživeo kada je bilo potrebno zapisati veću količinu bajtova (8-bitnih brojeva). Mladjima će možda izgledati besmisleno, ali jedno vreme su se neki kratki mašinski programi, potprogrami ili tabelarni podaci za programe štampali u računarskim časopisima kako bi korisnici mogli da ih unesu i koriste jer u to vreme nije bilo interneta ili nekog sličnog mesta sa koga bi svi mogli da ih preuzmu. Zapisivanje velike količine brojeva u dekadnom obliku niti izgleda lepo niti može lako da se prekontroliše da li smo preskočili neku cifru kod prekucavanja. Tabela sa po 8 dekadnih brojeva bi izgledali recimo ovako:
Code:
23,101,3,55,111,0,236,97
219,189,201,188,1,137,101,89

itd...

Na prvi pogled se vidi da brojevi nisu zapisani jedan ispod drugog jer imaju različit broj cifara, i da izmedju svaka 2 broja stoji zarez. Ako sad pogledamo jedan bajt u binarnom obliku vidimo da tih 8 bitova možemo da podelimo u dve grupe od po 4 (grupa od 4 bita zove se nibl - na engleskom: nibble), od kojih svaka ima 16 mogućih stanja (eto prilike za primenu ovog brojnog sistema) i vidimo da sada svaki bajt zapisan u heksadekadnom obliku zauzima tačno 2 mesta i da nam onda čak ni zarezi nisu potrebni za odvajanje susednih brojeva, pa bi gornja tabela izgledala ovako:
Code:
176503376F00EC61
DBBDC9BC01896559

što izgleda neuporedivo urednije i znamo da u svakom redu moramo da imamo 16 znakova.

Prilično uobičajeno je i da se adrese memorijskih lokacija zapisuju u tom formatu.

Za vežbu ćemo heksadekadni broj A7E da pretvorimo u dekadni po već navedenoj formuli pa kad zamenimo šta treba dobijemo sledeći izraz:

A*162 + 7*161 + E*160 = 10*162 + 7*161 + 14*160 = 10 * 256 + 7 * 16 + 14 * 1 = 2686
[ rsinisa @ 30.08.2012. 20:13 ] @
Obeležavanje brojnih sistema
===================
Kada radimo sa više brojnih sistema moramo nekako da obeležimo broj kako bi smo znali u kom brojnom sistemu je zapisan. Npr. broj 1011 može da bude zapisan u bilo kom brojnom sistemu, a u matematici se to obeležava ovako:
101110 dekadni sistem
10112 binarni sistem
101116 heksadekadni sistem

U programiranju se to obeležava nešto drugačije jer je ovakav način zapisivanja nepraktičan pri kucanju na tastaturi. Najčešći načini zapisivanja su:
dekadni sistem = 1011,
binarni sistem = %1011 ili b1011 ili 1011b
heksadekadni sistem = $1011 ili 1011h illi 0x1011

PBP koristi načine koji su prvi prikazani za svaki od sistema.
[ rsinisa @ 02.09.2012. 17:06 ] @
Pretvaranje dekadnog broja u druge brojne sisteme
=================================
Najlakši način prebacivanja brojeva iz jednog u drugi brojni sistem su kalkulatori; u linuxu za to možete da upotrebite "galculator", a u windowsu onaj koji dolazi u standradnoj instalaciji: odaberete brojni sistem u kome je broj zapisan, otkucate ga i zatim kliknete na dugme koje označava drugi brojni sistem i na ekranu se pojavi rezultat.
Ako nemate pri ruci kalkulator pokazaćemo kako se to radi na primeru pretvaranja dekadnog broja u binarni. Nećemo da pišemo formulu, ali bi algoritam mogao da se opiše ovako:
broj koji pretvaramo deli se sa osnovom brojnog sistem u koji ga pretvaramo. Rezultat zapisujemo sa 2 broja, ceo broj i ostatak. Zatim taj ceo broj iz rezultata ponovo delimo sa osnovom i rezultat zapisujemo sa 2 broja i tako sve dok ne dodjemo do nule. Da bi to sve bilo jasnije, evo primera:
Pretvorićemo dekadni broj 19 u binarni.

19/2=9 (1)
9/2=4 (1)
4/2=2 (0)
2/2=1 (0)
1/2=0 (1)

Sada ostatke čitamo odozdo na gore i zapisujemo sa leva na desno:
10011
I eto našeg binarnog broja.
[ rsinisa @ 02.09.2012. 17:17 ] @
Da bi ste mogli da pratite praktične lekcije koje će da uslede posle teorije biće Vam potreban razvojni sistem na kome ćete sve to i da isprobate. On je u pripremi, uskoro će biti objavljeni svi fajlovi potrebni za samogradnju kao i shema. Sve vezano za ovaj razvojni sistem možete da pročitate (a i pitate) u ovoj temi:
http://www.elitesecurity.org/t454860-PIC-razvojni-sistem
[ rsinisa @ 07.09.2012. 21:39 ] @
Algoritam
=======
U prošloj lekciji smo pomenuli algoritam, pa da vidimo šta je to jer može da nam bude od koristi kod pisanja programa.
Jedna od zvaničnih definicija glasi: Algoritam je konačna i precizno definisana procedura, niz dobro definisanih pravila, kojom se ulazne vrednosti transformišu u izlazne, ili se opisuje izvršavanje nekog postupka. Jednostavnijim rečnikom rečeno, algoritam predstavlja opis izvršavanja nekog postupka razložen na pojedinačne korake i svaki korak mora biti potpuno jasan i nedvosmislen. To znači da npr. neki kulinarski recept možemo da smatramo algoritmom jer opisuje sve korake jednog postupka.

Npr. algoritam za pečenje palačinki može da izgleda ovako: 1. zamesiti testo za palačinke, 2. ostaviti da odstoji pola sata, 3. uključiti ringlu, 4. staviti tiganj na ringlu, 5. sipati testo u tiganj, 6. ispeći sa obe strane i izvaditi iz tiganja, 7. vratiti se na korak 5.
Za neke je ovo sasvim dovoljan opis, ali za neupućene nije dovoljno precizno jer ne znaju šta ide u testo, pa umesto tačke 1. može da se napiše preciznije taj deo postupka: uzeti brašno, jaja, mleko i pomešati sve zajedno. I ovako možemo da razložimo na još preciznije postupke svaku tačku za koju ne znamo dovoljno precizno kako da je izvedemo; time olakšavamo obavljanje postupka i smanjujemo mogućnost greške. Medjutim, dobar algoritam ne samo da sadrži detaljno opisan kompletan postupak već mora da sadrži postupke u slučaju kada nisu svi uslovi ispunjeni, kao i postupke u slučaju greške. Npr. posle tačke 4. možemo da dodamo tačku u kojoj proveravamo da li se ringla ugrejala na potrebnu temperaturu, i ako nije onda možemo da proverimo da li ima struje i sl. Takodje tačku 7. možemo da modifikujemo ovako: 7. vratiti se na korak 5 ako ima još testa, u protivnom isključiti ringlu i završiti postupak.

Algoritam može da se predstavi na nekoliko načina, a najčešći su: prirodni govorni jezik i dijagram toka. Algoritam opisan prirodnim jezikom smo upravo predstavili na primeru pečenja palačinki, a evo kako bi mogao da izgleda algoritam za popravku neispravne lampe predstavljen dijagramom toka (preuzeto sa wikipedije):



Za programere algoritam može da bude od velike koristi, pogotovo kada je u pitanju neka složenija procedura. Kada se jednom napiše, posle ga je moguće prevesti na bilo koji programski jezik prevodjenjem koraka u odredjene programske komande.
Za one sa manje programerskog iskustva preporučujem da za početak pišu algoritme za ceo program (ionako su početnički programi uglavnom jednostavni i kratki) jer mogu da im uštede mnogo časova nerviranja i traženja greške u programu samo zato što su prevideli neki korak.
Ovaj tutorijal neće više da se bavi ovime pa za više informacija o pisanju algoritama pogledajte na internetu, npr ovaj link:
http://bs.wikipedia.org/wiki/P...entarne_algoritamske_strukture
[ rsinisa @ 18.09.2012. 20:03 ] @
ASCII kodovi
=========
Već smo rekli da računari, tj. procesori, razumeju samo binarni oblik, ne poznaju slova, brojeve, interpunkcijske znakove i sl. pa je bilo potrebno da se svi ti znaci kodiraju, odn. da im se dodele brojevi - svaki znak jedan broj. Prvi standard je zvanično predstavljen 1963. godine, bio je 7-bitni, baziran na engleskom alfabetu, i služio je za komunikaciju pomoću teleprintera. Nazvan je ASCII (čita se aski) što je skraćnica od engleskog izraza "American Standard Code for Information Interchange" (američki kodni standard za razmenu informacija).

Sa 7 bitova moguće je ostvariti 128 kombinacija što je u ono vreme bilo sasvim dovoljno za namenu za koju je osmišljen jer je tu bilo mesta za sve znakove engleskog alfabeta i još za nekoliko kontrolnih kodova, tačnije 95 znakova za prikaz i 33 kontrolna karaktera (od kojih je većina zastarela). Evo tabele tih 128 znakova (preuzeto sa wikipedije):


Pomoću ove tabele možemo da odredimo heksadekadni broj (kod) za svaki prikazani karakter koji se odredjuje tako što se prvo pročita vertikalni, a zatim horizontalni znak. Npr. broj "0" ima kod $30, a veliko slovo "A" ima kod $41.

Pojavom računara koji su radili sa bajtovima (8 bitova) pojavilo se 128 praznih kodova, od 128 do 255, u koje su smešteni razni grafički karakteri koji su se koristili za crtanje jednostavnije grafike. Širenjem računara po celom svetu ukazala se potreba za novim znakovima koji su specifični za odredjenu zemlju, kao što su naša slova "čćšžđ" ili grčki alfabet, pa su izmišljene kodne strane kod kojih je prvih 128 znakova identično prvobitnoj tabeli, a u drugoj polovini tabele su smeštani potrebni specifični znaci i simobli. Nama kodne strane nisu bitne jer ćemo uglavnom da koristim kodove koji su standardizovani po IBM standardu ili koji su ubačeni u periferiju koju koristimo (npr. LCD displej).

[ rsinisa @ 28.09.2012. 22:10 ] @
Analogna i digitalna elektronika
====================
Nekoliko puta do sada smo pomenuli termin "digitalna elektronika" pa pre nego što objasnimo šta je to, da pomenemo da pored nje postoji i analogna elektronika.

Analogna elektronika
-------------------------
Definicija analogne elektronike bi mogla da glasi ovako: analogna elektronika operiše sa kontinulanim signalima po vremenu i amplitudi. Kontinualni signali su definisani u svakom vremenskom trenutku i mogu imati bilo koju vrednost amplitude.

Analogni signal ima praktično bezbroj vrednosti izmedju minimalne i maksimalne, samo je pitanje koja je preciznost instrumenta kojim se meri i koja je preciznost nama potrebna, odnosno dovoljna. Analogni signal je veoma podložan promenama usled smetnji.

Analogna elektronika je nastala iz činjenice da je većina fizičkih veličina analognog tipa, tj. da se menjaju kontinualno kao što su brzina, temperatura, pritisak itd. pa su napravljeni senzori koji tu veličinu pretvaraju u analogni električni signal. Evo kako bi mogao da izgleda grafik nekog analognog signala:




Digitalna elektronika
------------------------
Digitalna elektronika operiše sa diskretnim signalima. Diskretni signali mogu imati vrednost amplitude iz tačno određenog skupa, što je diskretizacija po amplitudi, i biti definisani samo u određenim vremenskim trenucima, što je diskretizacija po vremenu.
Diskretni signal je onaj kod koga je za odredjeni vremenski period amplituda signala konstantna, a zatim se menja na drugi konstantni nivo.
Mi smo već pomenuli da te nivoe obeležavamo sa 0 i 1, ali oni imaju svoje apsolutne vrednosti. Dugo su te dve vrednosti bile 0V i 5V, ali su u poslednje vreme veoma česte vrednosti od 0V i 3,3V.

Postoje i vrednosti koje nisu dozvoljene, odn. ako se napon nadje u nedozvoljenim granicama kažemo da signal nije definisan.
Za PIC 16F1827 maksimalna vrednost napona za logičku nulu se kreće od 0,8V do 1,5V, a minimalna za logičku jedinicu je od 2 do 5V, pri naponu napajanja od 5V. Sve vrednosti izmedju njih se smatraju nedozovoljenim. Granične vrednosti bi trebalo da budu fiksne, ali PIC ima raznovrsne hardverske komponente pa su prema njima odredjene i granice. Baš zbog činjenice da postoje granice, digitalni signal je mnogo otporniji na smetnje.

Evo primera jednog digitalnog signala:



[Ovu poruku je menjao rsinisa dana 28.09.2012. u 23:25 GMT+1]
[ rsinisa @ 06.10.2012. 11:44 ] @
AD i DA konvertori
=============
Vidimo da su analogna i digitalna elektronika dva potpuno različita sveta, signali su potpuno drugačiji i zbog toga nije moguće direktno povezivanje već nam je potreban prevodilac.

Znamo da nam je za govorni jezik dovoljan jedan prevodilac jer on može da prevodi u oba smera - prvo sluša na jednom, a zatim priča na drugom jeziku (jedan smer), nakon toga radi obrnuto.
U svetu elektronike su vam najčešće potrebna dva prevodioca, po jedan za svaki smer. To nije zato što je nemoguće smestiti oba na isti čip, već zato što nam najčešće nisu potrebna oba istovremeno, vrlo često je potreban samo jedan i to onaj koji prevodi analogni u digitalni signal.

Prevodilac koji prevodi signal iz analognog u digitalni zove se, sasvim logično, analogno-digitalni konvertor i u tekstovima se predstavlja na jedan od tri načina: ADC, AD konvertor ili A/D konvertor.
Prevodilac koji radi suprotnu stvar se, opet sasvim logično, zove digitalno-analogni konvertor i predstavlja se sa: DAC, DA konvertor ili D/A konvertor.

U prvim danima digitalne elektronike postojali su samo posebni čipovi, a pojavom mikrokontrolera sve je češća praksa da se u njih smešta samo ADC, samo DAC ili oba.
[ rsinisa @ 06.10.2012. 21:24 ] @
AD konvertor
=========
Princip rada
--------------
Uprošćeno gledano, princip rada ovog konvertora je relativno jednostavan - u nekom trenutku uzme uzorak analognog signala, zadrži ga, i nekom od mnogobrojnih metoda taj uzorak pretvara u digitalni oblik. Videli smo da analogni signal menja vrednost kontinualno tokom vremena pa je neophodno uzeti uzorak i zadržati ga tokom pretvaranja kako bi ta vrednost bila na istom nivou dok traje taj proces. Tu ulogu ima ulazni deo konvertora koji se zove "sample and hold", odn. "uzmi i zadrži", i najčešće se sastoji od kondenzatora spojenog na signal koji "uzima" uzorak signala, i prekidača koji odspaja kondenzator od ulaznog signala kako se uzeta vrednost ne bi promenila.
Neke od karakteristika AD konvertora su: broj bitova (tj. rezolucija), referentni napon, brzina konverzije i tip izlaza (serijski ili paralelni).

Broj bitova
--------------
Broj bitova odredjuje sa koliko različitih stanja AD konvertor može da predstavi analognu veličinu. Ako je to 8, znači da mereni signal možemo da predstavimo sa 256 različitih stanja. Ako imamo 10 bitova, kao PIC koji ćemo da koristimo, znači da imamo 1024 moguća stanja. Koliko je meni poznato, danas postoje AD konvertori do 32 bita, što je veoma velika rezolucija, odn. analogni signal može da se predstavi sa preko 4 milijarde stanja.
Postavlja se pitanje koja rezolucija je dovoljna? Sve zavisi od konkretnog slučaja, ali da uzmemo primer kada želimo na digitalnom displeju da prikažemo napon laboratorijskog ispravljača koji daje napon od 0 do 30V. Ako uzmemo 8-bitni AD, to znači da ceo opseg ispravljača (30V) možemo da podelimo na 256 stanja (30 / 256) i vidimo da dobijemo minimalni korak od 0,117V. Za ozbiljan laboratorijski ispravljač je to praktično premalo pa hajde da vidimo kakva je situacija sa 10 bitova, sa kojima imamo 1024 mogućih stanja. Kada podelimo 30 sa 1024, dobijemo minimalni korak od 0,029V što je sasvim zadovoljavajuće za tu namenu. Naravno, što veća rezolucija to bolje, ali povećanje rezolucije unosi neke probleme. Po meni, 10 bitova je sasvim dovoljna rezolucija za većinu primena, a i 8 zna da bude dovoljno.


[Ovu poruku je menjao rsinisa dana 06.10.2012. u 22:44 GMT+1]
[ ZAS011 @ 06.10.2012. 22:00 ] @
Da se nadovežem na ovo lepo pisanje vezano za ADC.

Elem, Siniša je uzeo za primer merenje napona na laboratorijskom ispravljaču uz pomoć 10 bitnog ADC-a. Malko je nezgodno za "matematiku" 0,029V po koraku, mnogo je lepše meriti maksimalni napon koji zadovoljava n x 1024, što bi u ovom slučaju bilo 30.72V
Proračuna se razdelnik napona tako da na pri ulaznih 30.72V ulaz na ADC pin-u bude tačno Vdd (ukoliko je uzet Vdd za Vref), iščitati ADC sukcesivno 3 puta i reziltat će sigurno biti celobrojna vrednost (WORD) veličine, što je izuzetno lako za prikazivanje na LCD-u.

Primer koda, kada za to dođe vreme, u Proton-u.
[ rsinisa @ 10.10.2012. 22:27 ] @
Referentni napon
--------------------
Da bi ADC znao kolika je u stvari vrednost napona koji meri, tj. kako da predstavi izmereni napon, neophodno je da ima neki drugi napon sa kojim će da vrši poredjenje, a taj napon se zove referentni napon i veoma je bitno da on bude što stabilniji. Kada je napon koji se meri jednak referentnom tada je rezultat maksimalan, tj. svi bitovi su postavljeni na 1, što znači da mereni napon ne sme da predje referentni jer ćemo imati pogrešan rezultat. Postoji i mogućnost da je napon koji merimo mnogo manji od referentnog pa ćemo da imamo mali opseg bez obzira na broj bitova samog ADC-a. Iz ovoga proizilazi da je najbolje kada je maksimalna vrednost merenog napona jednaka ili nešto malo niža od referentnog koji je obično jednak naponu napajanja ili nekom drugom iz spoljnog ili unutrašnjeg izvora. Često su to vrednosti jednake stepenu broja 2, npr. 1,024V, 2,048V ili 4,096V, mada može da bude bilo koje vrednosti jer kontroler uz malo matematike sve to lako preračuna, ali je uglavnom praktičnije ako su u odnosu sa stepenom broja 2.

Medjutim, retko kada se napon koji merimo poklapa sa referentnim i zato ga je potrebno dovesti na odgovarajući nivo. Kada je maksimalno očekivani mereni napon veći od referentnog, za njegovo smanjenje se veoma često koristi otpornički razdelnik napona, a kada je manji, za povećanje se koristi operacioni pojačavač.


[Ovu poruku je menjao rsinisa dana 10.10.2012. u 23:46 GMT+1]
[ rsinisa @ 13.10.2012. 01:47 ] @
Primer upotrebe ADC-a
-------------------------
Pošto je ADC relativno komplikovan za početnike, objasniću detaljno kako se koristi na primeru merenja napona od maksimalnih 10V, sa ADC-om od 10 bitova, i referentnim napon od 5V.
Da bi mereni napon doveli na nivo referentnog upotrebićemo razdelnik napona sa dva otpornika od po 10K. Za one koje ne znaju, otpornički razdelnik napona je ovo:



U1 je ulazni (veći) napon, U2 je izlazni (onaj koji vodimo na ADC), a odnos otpornika odredjuje odnos izmedju ulaznog i izlaznog napona. Formula glasi:

U2 = U1 * R2 / (R1 + R2)

Da vidimo sada kako da iz rezultata koji dobijemo na osnovu merenja U2, izračunamo koliki je zaista napon U1 u voltima.
Kada je U1 tačno 10V, U2 će biti 5V što je jednako referentnom naponu, pa će rezultat imati maksimalnu vrednost, tj %1111111111 ili 1023 dekadno. Vidimo da dobijeni rezultat moramo da podelimo sa 102,3 da bi dobili 10V, tj. da bi izračunali U1. Iako PBP ne podržava decimalne brojeve, ipak je ovde reč o mikrokontroleru i nije problem napraviti rutinu za decimalno deljenje i doći do rezultata, ali bi ta rutina bila velika i oduzela bi prilično vremena za njeno izvršavanje. Zato ćemo da pribegnemo jednom triku: ako već nećemo da delimo sa decimalama, onda ćemo da prilagodimo U2 tako da rezultat podelimo sa celim brojem, a u ovom slučaju bi bilo zgodno da to bude 100. To znači da moramo da promenimo odnos R1 i R2 tako da pri U1 od 10V, rezultat AD konverzije bude tačno 1000, pa ćemo da izračunamo koliko tačno treba da bude napon U2.

Postavićemo proporciju:
1023 : 5 = 1000 : U2
U2 = 5 * 1000 / 1023
U2 = 4,887 V

što znači da U2 mora da bude 4,887V kada je U1 = 10V. Otpornik R1 nećemo da menjamo tako da nam još ostaje da izračunamo R2 koji se, kada se izvuče iz gornje formule, računa ovako:

R2 = U2 * R1 / (U1 - U2)

Kada zamenimo vrednosti dobijemo da nam je potreban otpornik od 9,559 K. Pošto ta vrednost ne postoji, R2 ćemo da zamenimo trimer potenciometrom pa će naš razdelnik da izgleda ovako:



Vrednost za R2 ćemo najlakše da podesimo tako što ćemo da napišemo naš program koji vrednost dobijenu konverzijom deli sa 100 i prikazuje na displeju, podesimo U1 na 10 volti i podešavamo trimer R2 dok na displeju ne dobijemo prikaz od 10V.

Već smo rekli da PBP ne poznaje decimalne brojeve, što znači da će rezultat da bude celobrojni, bez ijedne decimale, ali pošto već imamo ADC sa dovoljnom rezolucijom, rezultat konverzije možemo da uvećamo 10 puta, tj. u ovom slučaju da podelimo sa 10 umesto sa 100, prikažemo ga na displeju i ispišemo decimalnu tačku izmedju jedinica i desetica; time smo dobili rezultat sa jednom decimalom. Koristan trik, zapamtite ga, trebaće vam.
[ rsinisa @ 16.10.2012. 13:16 ] @
U primeru iz prethodnog teksta namerno je na kraju izostavljen jedan detalj zbog testiranja vaše pažnje. Rekli smo da rezultat AD konverzije možemo da podelimo sa 10 i dobijemo jednu decimalu, a iz toga proizilazi da bez ikakvog deljenja rezultata dobijamo praktično dve decimale, s tim što i dalje imamo rezultat u obliku celobrojne vrednosti, a decimalnu tačku ispisujemo izmedju cifara stotica i desetica. Ako ste ovo videli, znači da ste shvatili princip dobijanja decimala pomoću celih brojeva, a ako niste, ne brinite, naučićete.

Brzina konverzije ADC-a
-----------------------------
Proces pretvaranja analogne veličine u digitalnu ima neko vreme trajanja i predstavlja parametar koji se zove brzina konverzije ("sampling rate" na engleskom). Ta brzina se ponekad izražava kao vreme, a ponekad kao frekvenca, a radi se, praktično, o dva obrnuto proporcionalna podatka (frekvenca = 1 / vreme, i obrnuto). Zašto je bitna ta brzina? Kao što smo rekli, analogni signal u svakom trenutku ima neku vrednost koja je, zavisno od signala, podložna promeni. Sa druge strane, digitalni signal je definisan samo u odredjenim trenucima što znači da postoji šansa da je analogni signal promenio vrednost izmedju dve uzastopne konverzije što rezultira netačnom predstavom signala u digitalnom obliku.

Po teoriji, potrebno je da frekvenca konverzije bude bar duplo veća od najveće očekivane frekvnce analognog signala da bi on bio koliko-toliko ispravno prikazan kasnije kroz rekonstrukciju pomoću DA konvertora i filtera. Zato je frekvenca uzorkovanja kod audio signala 44,1 kHz (muzički CD) jer ljudsko uvo čuje, u najboljem slučaju, frekvence do oko 20 kHz.

Medjutim, da bi signal sa velikom sigurnošću bio pretvoren u digitalni, teorija kaže da je potrebno da frekvenca uzorkovanja bude oko 10 puta veća od frekvence analognog signala koji se konvertuje. Na osnovu tog podatka možete, recimo, da uporedite dva digitalna osciloskopa od kojih oba mogu da "vide" signal do 100 Mhz, s tim da je brzina uzorkovanja kod jednog 1 GS/s (čita se "gigasempl u sekundi") i označava jednu milijardu uzoraka u jednoj sekundi, dok je kod drugog 500 MS/s (čita se "megasempl u sekundi") i predstavlja 500 miliona uzoraka u jednoj sekundi. Odmah je jasno da se treba opredeliti za prvi model jer će vernije da prikaže posmatrani signal. Doduše, i dalje postoji mogućnost da se neki kratki "špic" provuče neprimećen, ali to je jednostavno tako kod AD konverzije.

Ako obradjujemo jednosmeran signal, ili neki sa jako sporom promenom, jasno je da brzina konverzije ne predstavlja neku bitnu stvar jer su danas svi AD konvertori praktično prebrzi za taj zadatak. Medjutim, postoji situacija u kojoj bi nam možda veća brzina dobro došla čak i kod signala koji se sporo menja, a to je situacija kada nam je potrebna veoma velika preciznost pa moramo da upotrebimo ADC sa velikom rezolucijom. Pošto je osteljivost takvog ADC-a prilično velika (može da izmeri promenu reda mikrovolti), rezultat izmedju susednih konverzija može da varira zbog smetnji, iako se vrednost signala nije promenila. U tim situacijama se radi uprosečavanje signala tako što se sabere veći broj uzoraka pa se dobijena vrednost podeli sa brojem uzoraka, čime se donekle smanjuje uticaj tih smetnji softverskom metodom (postoje i hardverske upotrebom fitera i sl.).
[ rsinisa @ 22.10.2012. 18:53 ] @
Tip izlaza ADC-a
--------------------
Da bi AD konvertor preneo mikrokontroleru vrednost, potrebno je da se poveže sa njim odredjenim brojem pinova. AD konvertori koji imaju više pinova i koji odjednom prenose celu vrednost su kovertori sa paralelnim izlazom; oni imaju za svaki bit rezolucije po jedan pin za podatak. Njihova prednost je što se odjednom prenosi kompletna vrednost, ali taj način povezivanja ima više nedostataka: potreban je veliki broj pinova mikrokontrolera za povezivanje, zatim kod integralnih kola kućište sa puno pinova može da ima veću vrednost nego sam silicijum na kome je izradjen, a i čip sa više pinova zauzima više mesta na štampanoj ploči (što takodje ima svoju cenu). Zato je broj pinova za prenos podataka smanjen na samo dva i napravljen je serijski tip izlaza gde se vrednost prenosi jedan po jedan bit, tj. serijski, s tim da je jedan pin predvidjen za prenos podatka, a drugi za sinhronizacioni takt. Očigledno je da je takav način prenosa sporiji, ali danas su AD konvertori veoma brzi i za većinu primena to ne predstavlja problem.

Ovo važi za slučaj kada koristimo spoljni AD konvertor. Obzirom da PIC koji ćemo da koristimo ima ugradjen ADC i sve potrebne mehanizme za prenos podatka, o ovome ne treba da brinemo, naše je samo da nakon konverzije pročitamo vrednost iz registra koji je konstruktor predvideo za tu namenu i odjednom preuzmemo kompletan rezultat konverzije.
[ rsinisa @ 30.10.2012. 22:43 ] @
DA konvertor
=========
Ovaj sklop, kao što mu ime kaže, pretvara digitalni signal u analogni. Koristimo ga u dva slučaja: kada je potrebno da pomoću digitalnog signala generišemo neki proizvoljan analogni signal, ili kada hoćemo da vratimo u prvobitni oblik neki analogni signal koji smo prethodno pretvorili u digitalni.

Prvi slučaj je npr. kada hoćemo da generišemo signal odredjenog oblika (npr. sinusni, testerasti ili bilo koji) koji nam je potreban i u tom slučaju možemo da menjamo vrednosti bilo kojim brzinom koja nam odgovara.

Drugi slučaj je kada npr. hoćemo da slušamo muziku sa CD-a. Da bi analogni signal bio vraćen u prvobitan oblik, neophodno je da brzina menjanja stanja bude identična onoj kojom je signal pretvoren u digitalni.
Pošto znamo da je digitalni signal diskretan po vremenu i amplitudi, izlazni signal bi bio stepenast i ni blizu originalnom. Zato DAC izlaz ima neku vrstu filtera koji "pegla" signal kako bi što više ličio na željeni, odn. originalni.


Slika 1




Slika 2


Na prvoj slici sivom bojom je predstavljen originalni analogni signal, a crvenom trenutak konverzije i vrednost digitalnog signala.
Na drugoj slici je prikazan postupak vraćanja digitalnog signala (crvena boja) u analogni (siva boja). Vidi se da je analogni signal "ispeglan" izmedju 2 digitalna kako bi se dobio originalni oblik analognog signala.

Sada se verovatno neko pita zašto bi uopšte pretvarali audio signal u digitalni, pa ga potom opet vraćali u analogni jer u tom procesu dolazi do degradacije signala. Kao prvo, zaista dolazi do degradacije signala, ali one su tako minimalne da to naše uvo ne može da registruje, a i one su izraženije kod visokih frekvenci koje ionako slabije čujemo.
Kao drugo, glavni razlog je očuvanje kvaliteta signala jer se analogni signal deformiše vremenom, reprodukcijom i presnimavanjem, dok sa digitalnim takvih problema maltene nema. Digitalni signal, iako praktično u savršenom obliku za čuvanje i reprodukciju, podložan je jedino deformisanju zbog vremena, a za to je zaslužan kvalitet medijuma na kome je snimljen pa je potrebno presnimavati ga na odredjen broj godina.
Kvalitetni CD-ovi bi trebalo da izdrže bez problema i do 30 godina, ali nemojte da se iznenadite ako ne uspete da pročitate manje kvalitetan disk koji ste narezali pre svega par godina.

Neke od karakteristika DA konvertora su: broj bitova (tj. rezolucija), referentni napon i brzina konverzije.
[ rsinisa @ 07.11.2012. 22:20 ] @
Broj bitova
-------------
Kao i kod ADC-a, i ovde imamo broj bitova koji odredjuju rezoluciju DA konvertora; ako je np. broj bitova 8, to znači da DAC na svom izlazu može da proizvede 256 različlitih nivoa signala. Koliko je bitova dovoljno opet zavisi od konkretne primene, ali je bitno da se kod rekonstrukcije digitalnog signala u analogni broj bitova poklapa sa onim kod AD konverzije.

Referentni napon
---------------------
I kod DAC-a nam je potreban refeerntni napon kako bi on na svom izlazu mogao da postavi konkretnu vrednost. Kada su svi bitovi na logičkoj jedinici, izlazni napon je jednak referentnom naponu. Ponekad nam je taj napon dovoljan za dalju obradu i korišćenje, ali je često slučaj da ga treba povećati pa se upotrebljavaju operacioni pojačavači ili gotovi audio-pojačavači za audio tehniku.

Brzina konverzije
--------------------
Kao i kod AD konverzije, pretvaranje digitalnog signala u analogni takodje traje neko vreme pa i ovde imamo taj parametar o kome moramo da vodimo računa pri izboru DA konvertora.
Ako se radi o rekonstrukciji analognog signala, maksimalna brzina DA konvertora mora da bude jednaka ili veća od brzine kojom je analogni signal pretvoren u digitalni (naravno da brzina konverzije mora da bude jednaka brzini kojom je uradjena AD konverzija).

Kada hoćemo da rekonstruišemo neki analogni signal vrlo je jednostavno odabrati DAC sa odgovarajućom brzinom konverzije, ali kada hoćemo da generišemo neki signal, moramo malo da pripazimo na brzinu.
Recimo da hoćemo da generišemo sinusni signal frekvence do 10 kHz. Sledeće što treba da odlučimo je sa koliko uzoraka (segmenata) ćemo da napravimo tu sinusoidu - generalno gledano, važi pravilo "što više, to bolje", a tu dolazimo do ograničenja koje nam nameće brzina DA konvertora. Sa više uzoraka pravimo precizniji signal, medjutim pitanje je koja nam preciznost treba, i treba uzeti u obzir da se signal može popraviti filterima. Pogledajmo sledeću sliku:



Vidimo da je ovde jedna kompletna sinusoida predstavljena sa 32 segmenta pa ako to sada pomnožimo sa frekvencom signala, vidimo da nam je potreban DAC koji može da uradi 320 000 konverzija u sekundi. Ako nemamo tako brzi DA konvertor, moraćemo da smanjimo broj segmenata za jednu kompletnu periodu.
[ rsinisa @ 08.11.2012. 23:48 ] @
Operacioni pojačavači
==============
U prethodnim lekcijama pomenuli smo operacioni pojačavač (na srpskom skraćeno "OP", na engleskom "operational amplifier", ili skraćeno "op amp"), pa da vidimo šta je to.
To je sklop koji je spolja gledano veoma jednostavan, sastoji se od 2 ulaza, jednog pozitivnog i jednog negativnog, jednog izlaza i dva izvoda za napajanje. Šematski se prikazuje ovako:



Vidi se da se za napajanje koriste i pozitivan (+Vcc) i negativan napon (-Vcc), ali postoje i oni kojima je za rad dovoljan samo pozitivan napon (-Vcc se vezuje na masu).
Iako jednostavan, sa njime je moguće ostvariti jako puno različitih spojeva kao što su: neinvertujući pojačavač, invertujući pojačavač, integrator, diferencijali pojačavač, sabirač itd. Ovde ćemo samo ukratko da objasnimo njegovu primenu u spoju neinvertujućeg pojačavača jer će nam u praksi uglavnom biti potreban za pojačanje signala malih amplituda. Zove se neinvertujući jer je napon na izlazu istog znaka, tj. polariteta kao i napon na ulazu. Taj spoj izgleda ovako:



Izlazni napon računa se po formuli:
Vout = Vin * (1 + R2/R1)

Ako npr. želimo da AD konvertorom merimo signal maksimalne amplitude 0,5 V pri referentnom naponu od 5V, napravićemo ovaj pojačavač koji će da ima pojačanje od 10, što znači da otpornike odaberemo tako da njihov odnos bude 9. Za konkretne vrednosti treba konsultovati tehničke podatke za upotrebljeni OP.

U digitalnoj elektronici će nam uglavnom biti dovoljni OP sa jednostrukim napajanjem, a prilično dobar izbor je LM358 koji je u stvari dvostruki OP u DIP8 kućištu. Da ne bi sve bilo idealno, OP imaju i neke nepoželjne karakteristike na koje moramo da pazimo i koje moramo da kompenzujemo, ali više o tome potražite sami na internetu. Dobar tekst na srpskom jeziku imate na wikipediji:
http://sr.wikipedia.org/sr/Operacioni_poja%C4%8Dava%C4%8D

Ako govorite engleski (što je praktično neophodno za elektroniku) pogledajte npr. sledeće sajtove:
http://www.electronics-tutorials.ws/opamp/opamp_1.html
http://www.allaboutcircuits.com/vol_3/chpt_8/2.html
[ rsinisa @ 11.11.2012. 00:28 ] @
Logička sonda
=========
Prethodna lekcija je bila poslednja opšta teorijska lekcija, vreme je da predjemo na nešto konkrentije.
Obzirom da ćemo uskoro početi sa radom na pravom hardveru, trebaće vam ponešto od instrumenata radi otkrivanja eventualnih problema.
Ono što je neophodno je tzv. unimer (ili multimetar) i verovatno ga već posedujete, digitalni ili analogni, svejedno je. Ono što bi bilo lepo da imate je osciloskop, ali je prilično skup. A ono što bi svakako trebalo da imate, a možete i sami da napravite, je logička sonda.
Postoji jako puno šema, ali mnoge od njih imaju neke nedostatke pa preporučujem da napravite onu koju je Voja Antonić objavio u domaćem časopisu "PC" u broju 155. Pošto sam od Voje dobio dozvolu da objavim ovaj njegov projekat (i bilo koji ako zatreba), na ovom linku možete da skinete kompletan članak:

http://www.filedropper.com/logickasonda

Arhiva u kojoj je program za PIC, i PCB fajl radjen u PROTEL-u, prikačena je uz ovu poruku, fajl pod nazivom pc155sko.zip. Ako nemate PROTEL, možete i sami da projektujete štampanu ploču jer jer šema veoma jednostavna, a ionako je vojina verzija predvidjena za dvostranu pločicu.



Izgled štampane ploče za logičku sondu. Kliknite na sliku za veću.


Pored ovog, veoma koristan može da bude i instrument koji je Voja objavio u istom časopisu u brojevima 35 i 36, u članku pod nazivom "Alatka za digitalnu radionicu". Ceo projekat je preveden na engleski i objavljen od strane MICROCHIP-a pod nazivom "Engineering Assistant"; sve potrebne fajlove kao i ceo projekat možete da pronadjete na ovom linku:

http://www.microchip.com/stell...deId=1824&appnote=en027166

Uredjaj objedinjuje 4 instrumenta u jednom: logička sonda, logički analizator, analizator serijskog protokola, i frekvencmetar do 40 MHz. U časopisu je napisano da je maksimalna frekvenca 50 MHz, ali je Voja kasnije, uvidevši neke probleme, smanjio na 40 MHz.


[Ovu poruku je menjao rsinisa dana 11.11.2012. u 01:41 GMT+1]
[ rsinisa @ 18.11.2012. 20:07 ] @
REČNIK
=====
U elektronici se koristi mnogo stranih reči, izraza i skraćenica, uglavnom engleskih, od kojih neke imaju odgovarajuće domaće izraze, ali ima i mnogo onih koji ili nemaju adekvatan i razumljiv prevod, ili su se toliko odomaćile da im prevod nije potreban. Ovde su date neke osnovne reči, skraćenice i izrazi, a verovatno će biti i naknadnih dopuna kako bi sve te reči bile na jednom mestu.
Velikim slovima ispisan je originalni oblik, u zagradi približan izgovor, a iza crtice prevod ili objašnjenje.

* BLACK-OUT (blek aut) - označava nestanak napona.
* BROWN-OUT (braun aut) - označava variranje napona ispod granica normi, ali ne i pad napona na nulu.
* BUG (bag) - buba u svakdnevnom govoru, u elektronici označava nenamernu grešku u softveru ili hardveru zbog koje uredjaj ne radi onako kako je očekivano.
* DEBUG (dibag) - postupak oktrivanja greške.
* EEPROM (iprom ili eeprom) - vrsta memorije čiji se sadržaj upisuje i briše električnim putem, a čiji se sadržaj ne gubi nestankom napona napajanja. Uglavnom se koristi za smeštaj podataka koji se ne menjaju često ili čiji sadržaj treba zapamtiti nakon isključenja uredjaja.
* EPROM (eprom) - vrsta memorije čiji se sadržaj upisuje električnim putem, a briše ultraljubičastim zracima. Lako se prepoznaje po staklenom "prozoru" na sredini kućišta, takodje ne gubi sadržaj nestankom napona napajanja. Koristi se za smeštaj podataka koji se ne menjaju u toku rada uredjaja, ili za smeštaj programa kod mikroprocesora koji nemaju ugradjenu programsku memoriju.
* EUSART (jusart) - Napredni univerzalni sinhrono-asinhroni prijemnik/predajanik. Predstavlja sklop koji vrši komunikaciju sinhrono ili asinhrono sa drugim uredjajima.
* FLASH (fleš) - vrsta memorije čiji se sadržaj upisuje i briše električnim putem, a čiji se sadržaj ne gubi nestankom napona napajanja. Nastala je iz EEPROM-a, koristi se uglavnom u memorijskim karticama, USB fleš memorijama za smeštaj podataka, a kod PIC-a se koristi za smeštaj programa.
* HARDWARE (hardver) - sve fizičke komponente nekog uredjaja.
* I2C (aj skuerd si; i dva ce) - dvožična magistrala podataka za povezivanje raznih uredjaja.
* ICD (aj si di) - In Circuit Debuging, označava mogućnost traženja grešaka u kolu dok uredjaj radi.
* ICSP (aj si es pi) - In Circuit Serial Programming, predstavlja metod programiranja mikrokontrolera dok se nalazi na pločici uredjaja.
* INTERAPT - Prekid izvršavanja glavnog programa i prelazak na rutinu za obradu prekida.
* KOMPARATOR - Sklop koji ima dva ulaza i jedan izlaz (kao i OP, a jedan od sklopova sa OP je i taj) na kome se javlja napon napajanja ili masa, u zavisnosti od razlike napona na ulazima.
* POSTSKALER - delitelj iza brojača.
* PRESKALER - delitelj pre brojača.
* PULL-DOWN (pul daun) - obično se koristi pre reči "otpornik" i predstavlja otpornik koji se spaja jednim krajem na masu napajanja, a drugim na ulazni pin čime se taj pin drži na niskom logičkom nivou.
* PULL-UP (pul ap) - kao i PULL-DOWN s tim da je otpornik jednim krajem vezan na pozitivan kraj napajanja čime se ulaz dovodi na visok logički nivo.
* PWM (pi vi em) - Pulse Width Modulation, označava vrstu modulacije kod koje se menja odnos izmedju impulsa i pauze pri čemu frekvenca ostaje ista. Najčešće se koristi za kontrolu intenziteta LED, regulaciju brzine motora, generisanje različitih nivoa napona i sl.
* RAIL-TO-RAIL OUTPUT (reil to reil autput) - označava mogućnost da neki izlaz može da postigne napone jednake najnižem i najvišem kojim se napaja integralno kolo. Ako nema tu mogućnost, izlaz postiže napone niže za par desetina mV u odnosu na napon napajanja.
* RAM (ram) - vrsta memorije koja se koristi za smeštaj podataka (kod računara i za smeštaj programa), a čiji sadržaj se gubi nestankom napajanja.
* ROM (rom) - vrsta memorije koja je unapred popunjena od strane proizvodjača, njen sadržaj ne može da se menja, a često sadrži operativni sistem za manje računare ili neke druge važne podatke.
* SINK CURRENT (sink karent) - označava struju koja ulazi u neki pin.
* SLEEP MODE (slip mod) - režim rada mikrokontrolera u kome je privremeno zaustavljeno izvršavanje programa, čeka da ga nešto opet pokrene, a potrošnja je minimalna.
* SOFTWARE (softver) - sve nefizičke komponente, u praksi je to program.
* SOURCE CURRENT (sours karent) - označava struju koja izlazi iz nekog pina.
* STACK (stek) - skladište koje privremeno čuva neke važne informacije, obično je RAM tipa i nije veliki, može da bude jedna RAM lokacija ili par desetina.
* WATCHDOG (vočdog) - bukvalno pas čuvar; u elektronici je to sklop kojim se omogućuje resetovanje, odn. ponovno pokretanje nekog uredjaja koji iz nekog razloga (najčešće smetnja u naponu napajanja) ne radi kako je očekivano.


[Ovu poruku je menjao rsinisa dana 19.11.2012. u 13:09 GMT+1]
[ rsinisa @ 19.11.2012. 21:08 ] @
PIC16F1827 - karakteristike
==================
Mikrokontroler koji ćemo da koristimo proizvod je firme "MICROCHIP", nosi oznaku PIC16F1827, i sada ćemo malo da se upoznamo sa njim i nekim od njegovih karakteristika koje možete da pronadjete u originalnom dokumentu koji možete da skinete sa ove adrese:
http://ww1.microchip.com/downloads/en/DeviceDoc/41391D.pdf
Preporuka je da ga obavezno skinete jer će Vam biti neophodan za ozbiljan rad, a i steći ćete naviku da čitate tehničku dokumentaciju bez čijeg pažljivog čitanja mogu mnoge stvari da Vam ostanu nejasne. Mnogi ljudi već znaju za moju izreku "Čitati, čitati i samo čitati" tako da je preporuka da se toga pridržavate - naučićete mnogo, nećete morati da čekate odgovor od drugih, a možda ćete nekome i da pomognete svojim znanjem.

Sada ćemo da nabrojimo veći deo karakteristika navedenog PIC-a, a u sledećim porukama ćemo da objasnimo malo detaljnije neke od njih.
- 3 tipa kućišta: 18-pinski DIP, 20-pinski SSOP i 28-pinski QFN/UQFN.
- 256 bajtova EEPROM-a
- 8 Kb programske memorije (FLASH tipa)
- 384 bajtova RAM-a
- Mogućnost interapta sa automatskim snimanjem važnih registara
- Stek od 16 nivoa
- Interni oscilator od 31 kHz do 32 MHz sa 1% preciznosti
- Radni napon od 1,8V do 5,5V
- Više vrsta reseta
- Vočdog tajmer sa periodom od 1ms do 268 sekundi
- Zaštita od isčitavanja programa
- Programiranje u kolu
- ICD funkcija
- Potrošnja struje u radu od 75 uA (mikroampera) pri taktu od 1 MHz i naponu 1,8V
- Potrošnja u stanju mirovanja (sleep) od 30 nA
- Jedan 10-bitni ADC modul sa 12 kanala
- Dva analogna komparatora
- Modul referentnog napona sa 1,024V, 2,048V i 4,096V
- 15 ulazno/izlaznih pinova i 1 isključivo ulazni pin
- Mogućnost davanja i primanja po 25mA po svakom pinu
- Pull-up otpornici na nekim pinovima
- Tajmer 0: 8-bitni tajmer/brojač sa 8-bitnim preskalerom
- Tajmer 1: 16-bitni tajmer/brojač sa preskalerom
- Tri tajmera 2: 8-bitni tajmer/brojač sa preskalerom i postskalerom
- Dva PWM modula
- EUSART modul
- Modul sa kapacitivnim senzorom: 12 ulaznih kanala
[ ZAS011 @ 19.11.2012. 23:07 ] @
Citat:
rsinisa: Logička sonda
=========

Pored ovog, veoma koristan može da bude i instrument koji je Voja objavio u istom časopisu u brojevima 35 i 36, u članku pod nazivom "Alatka za digitalnu radionicu". Ceo projekat je preveden na engleski i objavljen od strane MICROCHIP-a pod nazivom "Engineering Assistant"; sve potrebne fajlove kao i ceo projekat možete da pronadjete na ovom linku:

http://www.microchip.com/stell...deId=1824&appnote=en027166

Uredjaj objedinjuje 4 instrumenta u jednom: logička sonda, logički analizator, analizator serijskog protokola, i frekvencmetar do 40 MHz. U časopisu je napisano da je maksimalna frekvenca 50 MHz, ali je Voja kasnije, uvidevši neke probleme, smanjio na 40 MHz.


[Ovu poruku je menjao rsinisa dana 11.11.2012. u 01:41 GMT+1]


Da ne bude reklama, posedujem količinu od 5 komada pločica za Vojinu sondu, a čini mi se da imam i PIC-onje za iste :)
Pločice su dvostrane, pravljene u Ei-PCB

Slika Pločice

Petoro koji se jave posle 17:00 (putem PP) bi mogli da postanu vlasnici istih, sa sve PIC-onjom, za 15 € + poštarina.

Lista najbržih sa vremenima slanja PP, da ne bude varanja, biće javno objavljena ovde.

Samo jedna "zvrčka": Teritorija Srbije.
[ rsinisa @ 25.11.2012. 07:13 ] @
PIC16F1827 - detaljnije
================
Sada ćemo neke od navedenih karakteristika da upoznamo detaljnije.

- 8 KB programske memorije: Ovaj kontroler ima 14-to bitno jezgro što znači da se za jednu instrukciju koristi 14 bitova programske memorije, tj. 1 vord od 14 bitova. Obzirom da bajt ima 8 bitova, to znači da ovaj kontroler ima 4 KW (kilovord - označava 1024 vorda) memorije za programske instrukcije, tj u njemu ima mesta za tačno 4096 programskih instrukcija. Medjutim, taj podatak važi za asmeblerske instrukcije jer svaka zauzima tačno 1 vord, dok kod viših programskih jezika, kako smo već rekli, jedna instrukcija može da se sastoji iz nekoliko desetina asemblerskih.

- Stek od 16 nivoa: Dok se izvršava glavni program, često se nameće potreba da se pozove neki potprogram (to je kratak program koji se često koristi pa se izdvoji kao posebna celina) i kada se on izvrši, MCU mora da zna gde treba da se vrati. Pre poziva potprograma, MCU na stek stavi adresu sledeće instrukcije koja treba da se izvrši, pa nakon izvršenja potprograma, on uzme sa steka tu adresu i tako nastavlja tačno tamo gde je stao. Obzirom da stek ima 16 nivoa, to znači da iz jednog potprograma možemo da pozovemo drugi i tako sve do 16, tj. dok se stek ne popuni. Medjutim, PBP za svoje potrebe koristi nekoliko nivao steka, tako da je u PBP-u taj broj nešto manji.

- Interni oscilator od 31 kHz do 32 MHz sa 1% preciznosti: Da bi MCU mogao da radi, potreban mu je "dirigent" koji će da uskladi sva dešavanja unutar njega. Tome služi oscilator koji daje takt sa kojim se sve sinhronizuje. Ovaj oscilator može da bude spoljni ili unutrašnji (interni); ovaj PIC ima veliki izbor unapred odredjenih frekvenci koje može da proizvede, a to su:

* 32 MHz
* 16 MHz
* 8 MHz
* 4 MHz
* 2 MHz
* 1 MHz
* 500 kHz
* 250 kHz
* 125 kHz
* 62.5 kHz
* 31.25 kHz
* 31 kHz

Od svih ovih, jedino 31 kHz nije kalibrisana frekvenca, ostale imaju preciznost od 1%. Spoljni oscilator se koristi kada nam je potrebna velika preciznost i to je obično kristalni oscilator, dok se interni koristi kada nam je odstupanje od 1% prihvatljivo. Postavlja se pitanje koju frekvencu izabrati? Često je to najmanja koja nam je dovoljna za odredjeni uredjaj jer se sa povećanjem frekence povećava potrošnja.

- Više vrsta reseta: Reset predstavlja početak ili prekid u toku izvršavanja programa kada MCU počinje da izvršava program od unapred poznate adrese. Kod PIC-a (kao i kod većine MCU-a), nakon reseta program se izvršava od samog početka, tj, od adrese 0 (nula). Razlog za reset je situacija kada više nismo sigurni da bi se dalje izvršavanje programa odvijalo kako treba pa je potrebno da program krene od poznate lokacije, a kod ovog PIC-a su to: reset pri uključenju (POR - power-on reset), reset pri variranju napona ispod dozvoljene granice (BOR - brown-out reset), spoljni reset dovodjenjem logičke nule na pin -MCLR, WDT reset, reset instrukcija, greška pri prepunjavanju steka. Adresa od koje se vrši reset zove se još i "reset vektor".
[ rsinisa @ 25.11.2012. 07:52 ] @
- Vočdog tajmer sa periodom od 1ms do 268 sekundi: ovaj sklop radi praktično kao tajmer sa resetom; u toku izvršavanja programa, na pogodnim mestima se postavi instrukcija koja resetuje ovaj tajmer, tj. njegov tajmer kreće od nule. Ako se program iz nekog razloga "zaglavi", resetovanje tajmera neće da se izvrši pa će on, nakon isteka zadatog vremena, da "natera" MCU da krene izvršavanje programa od poznate lokacije, u ovom slučaju od reset vektora, tj. da resetuje mikrokontroler. Vreme za koje mora da se izvrši resetovanje WDT tajmera može da se podešava od 1 ms do čak 268 sekundi, a zavisi od vremena potrebnog da se izvrši najduži deo programa ili najduži potprogram.

- Zaštita od isčitavanja programa: Uložili ste veliki trud u razvoj nekog uredjaja, pustili ste ga u prodaju, a onda nakon kratkog vremena vidite da je neko iskopirao uredjaj koji ste razvijali mesecima. Da se to ne bi desilo, možete da uključite zaštitu od isčitavanja program čime onemogućujete kopiranje vašeg intelektualnog vlasništva. Ova zaštita nije 100-postotna, ali će Vas zaštiti od većine "lopova".

- Potrošnja u stanju mirovanja (sleep) od 30 nA: Postoje situacije u kojima nije potrebno da MCU radi non-stop, već se on prebacuje u režim spavanja (sleep mod) iz koga ga budi odredjeni unapred definisani dogadjaj. U tom režimu potrošnja je minimalna tako da se on koristi najčešće u uredjajima koji se napajaju baterijski.

- Jedan 10-bitni ADC modul sa 12 kanala: Ovo znači da PIC ima jedan ADC, ali sa 12 ulaza s tim da je u jednom trenutku moguće očitati vrednost sa samo jednog ulaza. Obzirom da je brzina AD konverzije velika, za većinu potreba ovo je idealan kompromis jer sa samo jednim ADC-om možemo da očitavamo čak 12 analognih signala.
[ rsinisa @ 30.11.2012. 04:09 ] @
- Dva analogna komparatora: Već smo rekli šta je komparator, samo još da kažemo da ovi koji su ugradjeni u PIC mogu kao referenetni napon da koriste onaj proizveden pomoću DAC-a, napon iz modula referentnog napona ili neki spoljni napon.

- Modul referentnog napona sa 1,024V, 2,048V i 4,096V: Kao što smo rekli u lekcijama, za normalan rad ADC i DAC modula potreban nam je referentni napon što veće preciznosti. Zato ovaj PIC ima ugradjen modul koji proizvodi taj napon i vidimo da su oni jednaki stepenu broja 2, a preciznost je sasvim zadovoljavajuća za većinu primena.

- Pull-up otpornici na nekim pinovima: Ovi otpornici su često potrebni kada na neki pin priključimo prekidač, taster, ili bilo koju komponentu koja ima samo jedno stabilno stanje pa nam je potrebno, dok komponenta nije u aktivnom stanju, da preko otpornika povežemo pin na pozitivan napon kako bi na pinu uvek imali poznato stanje. Pošto spoljni otpornik zahteva mesta na PCB-u, vrlo je korisno što su ovi otpornici ugradjeni u sam PIC. Možda vam ovo trenutno nije baš najjasnije, ali uskoro ćete razumeti o čemu se radi.

- Tajmeri: Služe nam za preciznu kontrolu nekih dogadjaja, merenje intervala i sl, a stanje brojača se uvećava dovodjenjem odredjenog impulsa na ulaz. Mogu da se sinhronizuju sa taktom oscilatora ili sa nekim spoljnim izvorom frekvence, odn. impulsa.

- Modul sa kapacitivnim senzorom: 12 ulaznih kanala: Ovaj modul omogućava interakciju sa korisnikom bez mehaničkih komponenti kao što su tasteri, prekidači i sl. Najčešće se na samom PCB-u predvidi bakarna površina koju korisnik dodiruje prstom čime se vrši promena kapaciteta koju ovaj modul registruje. Obzirom da ima 12 ulaza, to znači da možemo da imamo 12 tastera, ali uz pomoć multipleksa, moguće je dobiti i veći broj.
[ rsinisa @ 09.12.2012. 00:19 ] @
Naš drugar sa foruma, Zoran Šćepanović poznat na ES-u kao ZAS011, odlučio je da sve primere koje uradim u PBP-u on napiše u PROTON BASIC-u tako da ćete imati praktično dva kursa odjednom. Otvoriće posebnu temu u kojoj će biti ti primeri, odradiće ih kada bude imao vremena, a link ka temi će biti postavljen naknadno.

Microcode studio
===============
Programe za PBP moguće je pisati u običnom tekst editoru pa ih posle kompajlirati iz komandne linije, ali danas se to radi uglavnom iz IDE okruženja jer je mnogo jednostavnije, lakše i preglednije. IDE za PBP se zove MicroCode Studio (MCS u daljem tekstu) i sada ćemo veoma kratko da se upoznamo sa par osnovnih detalja koji su Vam potrebni da bi ste počeli da pišete programe.
Kada pokrenete MCS i hoćete da pišete novi program, kliknite na ikonu NEW i imaćete situaciju kao na slici:


Slika 1


U gornjem redu vidite meni, ispod njega ikone, ispod njih levo vidi se polje za izbor mikrokontrolera (početno je odabran PIC16F628A), ispod njega sa leve strane nalazi se polje u kome se vide definicije, konstante, promenljive i sl, a desno je veliko polje u kome se piše program. Vidimo da je program sam ubacio zaglavlje u kome se nalazi nekoliko linija komentara. Odmah ispod zaglavlja je prostor u kome se piše program. Kada završimo pisanje, pritiskom na F9 ili klikom na Compile vrši se prevodjenje (kompajliranje) PBP programa i kao rezultat, ako je sve bez grešaka, dobije se HEX fajl kojim se programira mikrokontroler.

Pre samog programa potrebno je napisati nekoliko stvari kao što su: konfiguracija, definicije, promenljive i sl.
Na sledećoj slici vidi se sam početak programa za testiranje MINI PIC 1 razvojnog sistema


Slika 2


Zaglavlje je u zelenoj boji jer je to boja kojom MCS označava komentare. Ispod toga je u komentaru navedeno za koji PIC je program. Ni zaglavlje ni komentar o PIC-u nisu neophodni, ali mogu da budu zgodni kao informacije.
Ispod vidimo konfiguraciju izmedju linija #CONFIG i #ENDCONFIG koja takodje nije neophodna, ali olakšava posao pri programiranju jer bi u protivnom morali ručno da je podesimo u softveru za programiranje. Ispod je DEFINE pseudo naredba koja takodje nije neophodna ako koristimo oscilator na 4 MHz jer je to podrazumevana vrednost za PBP. Medjutim, da ne bi bilo zabune dobra je ideja postaviti i tu liniju.

U dnu prozora vidimo polje nakon kompajlirana u kome se nalaze informacije u slučaju neuspelog kompajliranja, a u zadnjoj liniji vidimo koliko je programskih reči utrošeno. Na sredini te linije nalaze se koordinate u kojima se nalazi kursor.

[Ovu poruku je menjao rsinisa dana 09.12.2012. u 01:34 GMT+1]
[ rsinisa @ 09.12.2012. 15:20 ] @
Evo linka ka temi koja će paralelno ovom tutorijalu da se bavi PROTON BASIC kompajlerom.

http://www.elitesecurity.org/t...rijal-Proton-PicBasic-PDS-PICF

Pozdrav.
Sinisha
[ rsinisa @ 15.12.2012. 05:53 ] @
Prvi koraci
========
Na početku svakog programa potrebno je uraditi nekoliko stvari koje praktično ne čine sam program, ali su bitne za rad kompajlera i mikrokontrolera.

Pokrenite MCS i dobićete ekran sličan slici 1 u pretposlednjoj poruci. U gornjem levom uglu nalazi se izbornik "Microcontroller" iz čije liste treba da odaberete PIC16F1827 i time ste kompajleru stavili do znanja za koji PIC pišete program. Sledeće što možete da uradite je da u zaglavlje upišete neke podatke o vašem programu, odn. čemu program služi, mada to možete da uradite i ispod zaglavlja kao komentar. U PBP sintaksi komentar se piše tako što se ispred njega stavi gornji apostrof (') ili tačka-zarez (;) i sve iza toga do kraja linije kompajler neće da uzima u obzir, jednostavno će da ignoriše sve što piše iza znaka za komentar sve do kraja linije, tj. dok ne pritisnete ENTER. U MCS-u komentari su obeleženi zelenom bojom.
Moja navika je da za komentar stavljam znak ";" jer često kombinujem PBP i ASM, a za ASM naredbe jedino je ";" validan za komentar.

Nakon toga možete u komentar da stavite i oznaku PIC-a za koji je progam pisan jer može da se desi da MCS "izgubi" tu informaciju ili da nekome pošaljete program kao tekst.

Sledeće što treba da uradite je da postavite konfiguraciju. O čemu se zapravo radi? Svaki PIC ima jedan ili više registara čiji sadržaj može da se postavi samo u toku programiranja i koji služe da se podese neki parametri kao što su vrsta oscilatora, zaštita memorije od isčitavanja, parametri WATCHDOG tajmera (u daljem tekstu WDT), itd. Konfiguraciju nije neophodno postaviti u programu jer većina softvera za progamiranje dozvoljava ručno postavljanje pre samog programiranja, ali to nije pametno jer ćete u nekom momentu i vi sami da zaboravite koja je konfiguracija u pitanju za odredjeni program. Zato je veoma zgodno da se konfiguracija podesi u samom progamu čime se ona nakon kompajliranja nalazi u HEX fajlu i softver za programiranje automatski podesi sve kako ste zamislili.

PIC16F1827 ima dva konfiguraciona registra koji imaju neke podrazumevane vrednosti pa je u programu dovoljno podesiti samo one parametre koji se menjaju. Konfiguracija se navodi izmedju pseudo-naredbi #CONFIG i #ENDCONFIG (pseudo-naredbe su one koje ne menjaju sam program već služe kao informacija za kompajler) i za program kojim se testira MINI PIC 1 izgleda ovako:

#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _MCLRE_OFF & _WDTE_OFF
__config _CONFIG2, _PLLEN_OFF & _LVP_OFF
#ENDCONFIG

Medjutim, bolje je postaviti sve konfiguracione parametre u ovaj deo programa kako bi svi bili izlistani i kako ne bi morali svaki put da gledamo u tehničke podatke šta su podrazumevane vrednosti. Sve vrednosti za PIC16F1827 možete da pronadjete u PBP3 direktorijumu, poddirektorijum DEVICE_REFERENCE, fajl "PIC16F1827.INFO", a za naš tutorijal konfiguracija koju ćemo da koristimo u početnim primerima izgleda ovako:

#config
__config _CONFIG1, _FOSC_INTOSC, _WDTE_OFF, _PWRTE_ON, _MCLRE_OFF, _CP_OFF, _CPD_OFF, _BOREN_OFF, _CLKOUTEN_OFF, _IESO_OFF, _FCMEN_OFF
__config _CONFIG2, _WRT_ALL, _PLLEN_OFF, _STVREN_OFF, _BORV_19, _LVP_OFF
#endconfig

Ove dve pseudo-naredbe mogu da budu napisane i malim i velikim slovima. MCS ima tu osobinu da neke rezervisane reči sam prepravi u velika ili mala slova, a takav je slučaj i sa #ENDCONFIG - ako je kucate velikim slovima, nakon zadnjeg slova videćete da je automatski pretvorena u mala slova. Nema potrebe da vas to zbunjuje, sama reč je zaista napisana velikim slovima, ali je MCS prikazuje kao da je pisana malim. Pošto je to ionako nebitno, možete da pišete kako hoćete.

Za one koji hoće da znaju više o konfiguracionim registrima: pogledajte tehničke podatke za PIC16F1827, poglavlje "4.0 DEVICE CONFIGURATION".


I na kraju treba kompajleru staviti do znanja koja je frekvenca oscilatora koju koristimo, a to se radi sa DEFINE pseudo-naredbom:

DEFINE OSC 4

Ova naredba MORA da bude napisana velikim slovima, a sama definicija je nepotrebna ako koristimo oscilator na 4 MHz, ali je svakako poželjno da je postavimo. Ovu informaciju koristi kompajler kako bi preračunao neke od vremenski zavisnih naredbi, kao što je PAUSE. Vrednosti koje PBP podržava su (u MHz): 3 (za 3,58 MHz), 4, 8, 10, 12, 16, 20, 24, 25, 32, 33, 40, 48 i 64.
U slučaju da koristite neku frekvencu koja ovde nije navedena, moraćete sami da preračunate parametre za vremenski zavisne naredbe. Pretpostavimo da koristite oscilator na 2 MHz; u tom slučaju zgodno je upotrebiti DEFINE OSC 4 i onda sve vremenske parametre jednostavno duplirate, pa bi za pauzu od 20 ms trebalo napisati PAUSE 40.
[ rsinisa @ 26.12.2012. 08:32 ] @
Postavka 1
=======
U narednim primerima koristićemo sledeća podešavanja.

Razvojni sistem:
J1 uvek mora da bude postavljen kako bi PIC mogao normalno da radi.
J2 postavljen na RA6/RA7
J3 postavljen na ZV
J4 nebitno
SW1 svi prekidači uključeni
SW2 svi prekidači isključeni
SW3 svi prekidači isključeni
LCD izvadjen
IC2 izvadjen
CON4 prazan
CON5 prazan
XT1 nebitno, može da bude postavljen kristal, a i ne mora jer se koristi interni oscilator

Konfiguracija PIC-a:
#config
__config _CONFIG1 & _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__config _CONFIG2, _WRT_ALL & _PLLEN_OFF & _STVREN_OFF & _BORV_19 & _LVP_OFF
#endconfig

DEFINE OSC 4


[Ovu poruku je menjao rsinisa dana 26.12.2012. u 13:31 GMT+1]
[ rsinisa @ 26.12.2012. 10:21 ] @
Primer 1
======
Vreme je da napišemo naš prvi program.
Uradite stvari koje smo naveli u tekstu "Prvi koraci" i nakon toga program bi trebalo da izgleda otprilike ovako:



Obratite pažnju da se na slici vidi da je pseudonaredba DEFINE napisana malim slovima, a treba velikim. Problem je u samom editoru koji, kao što je već rečeno, nekim rečima sam menja veličinu slova, ali zapamtite da sve DEFINE naredbe MORAJU da budu napisane velikim slovima, a da će MSC editor da ih pretvori u mala.

Ubuduće sav programski kod koji budemo pisali biće napisan bez zaglavlja i konfiguracije jer se podrazumeva da ona ide na početku svakog programa.

Počećemo sa veoma jednostavnim primerom; palićemo i gasiti LED na pinu 0 porta B sa pauzom od pola sekunde izmedju. LED je skraćenica za "Light Emithing Diode", odn. za diodu koja emituje svetlost; koristi se kao i svaka dioda i kada je polarisana direktno, tj. kada kroz nju protiče struja ona svetli nekom bojom koja zavisi od materijala od koga je izradjeno vlakno. Još je bitno napomenuti da se LED napaja strujno, a ne naponski, a za standardnu LED je potrebno ograničiti struju na 15 do 20 mA. To se radi vezivanjem otpornika na red sa LED, a otpornik se proračunava prema padu napona na LED. Na MINI PIC 1 razvojnom sistemu se već nalazi otpornik, ali ćemo radi vežbe da uradimo jedan proračun.
Za crvenu, pri struji od oko 20 mA, pad napona je približno 2 volta pa ćemo prema omovom zakonu da izračunamo vrednost otpornika tako što od napona napajanja oduzmemo pad napona na LED. U našem slučaju napon napajanja je 5V, pad napona na LED je 2V pa je vrednost za otpornik:

R=U/I = (5 - 2) / 0,02 = 3 / 0,02 = 150 oma. To je vrednost koja postoji u standradnoj ponudi, a ako se desi da ne postoji, uzima se prva sledeća veća vrednost. Ako se koristi LED sa visokim sjajem, taj otpornik može da se poveća ako je sjaj prejak.

Idemo dalje sa programom. Ispod naredbe DEFINE OSC 4 kucajte sledeće:

Code:

pocetak:
    high portb.0        ;uključi LED na pinu 0 porta B
    pause 500           ;napravi pauzu od 500 milisekundi
    low portb.0         ;isključi LED
    pause 500           ;napravi pauzu od 500 milisekundi
    goto pocetak        ;idi na labelu pocetak
end                     ;oznaka kompajleru da je ovde kraj našeg programa


Sada bi prozor MCS-a trebalo da izgleda ovako:



Kao što vidimo, prva linija programa počinje nečim što nije naredba i završava dvotačkom, tj.
labelom 'pocetak:'. Pre nego što objasnimo šta je labela, vratićemo se malo unazad, u prve
dane BASIC-a.


P.S. Mala izmena na koju me je uputio Pedja089. Pseudo naredba DEFINE ne mora da bude napisana velikim slovima, ali ono iza nje mora. To znači da bi u našem primeru moglo i da se napiše

define OSC 4

Naravno, nije greška ako napišete i DEFINE velikim slovima.

[Ovu poruku je menjao rsinisa dana 26.12.2012. u 13:19 GMT+1]
[ rsinisa @ 26.12.2012. 11:12 ] @
U prvim verzijama BASIC-a programi su na početku svake linije imali broj koji je služio za identifikaciju i omogućavao da se program po potrebi preusmeri na odredjenu liniju naredbom GOTO ili GOSUB. Pokazalo se da je to veliki izvor grešaka jer je moguće pogrešiti pri kucanju i umesto jednog broja otkucati drugi pri čemu program nastavlja na pogrešnom mestu i ne radi kako treba. Kada bi ovaj program bio pisan na taj način, izgledao bi ovako:

10 high portb.0
20 pause 500
30 low portb.0
40 pause 500
50 goto 10

Ako u poslednjoj naredbi greškom otkucamo

50 goto 20

program će samo u prvom prolazu da uključi LED i više nikada neće doći na liniju 10 tako da će LED stalno biti isključena. U ovako kratkom programu i nije problem uočiti grešku, ali zamislite program sa više stotina, ili čak hiljada linija u kojima postoji greška u broju linije!
Zato su uvedene labele odn. oznake, čime je mogućnost greške drastično smanjena. Labela se, slično broju, postavlja pre neke instrukcije, ali ne i pre svake, čime se mogućnost greške drastično smanjuje. Labela u PBP-u može da sadrži cifre, slova i donju crtu, ali ne može da počne cifrom, a obavezno završava dvotačkom (samo kod definisanja, ne i kada je argument komande). Dužina je praktično neograničena, ali PBP uzima u obzir samo 31 karakter ako je naziv labele duži. Sasvim je svejedno da li je labela pisana velikim ili malim slovima, to znači da se labele 'POcetAK ' i 'pocEtaK ' tretiraju kao da su iste. Moguće je u istoj liniji staviti i labelu i PBP naredbu

Code:
pocetak:  high portb.0


mada je moj običaj da labelu stavim u zasebnu liniju čime se postiže dobra optička odvojenost labela.
[ rsinisa @ 27.12.2012. 01:53 ] @
Kao prvo, kako se program uopšte izvršava? Tako što mikrokontroler izvršava jednu po jednu naredbu, počev od prve pa na dole - čim završi jednu, prelazi na sledeću, i može da izvršava SAMO JEDNU naredbu u jednom trenutku. A koliko traje izvršavanje jedne naredbe, tj. koliko je u stvari brz mikrokontroler?

Jedna asemblerska naredba se kod PIC MCU-a izvršava za jedan ili dva mašinska ciklusa (zavisi od naredbe), a jedan mašinski ciklus traje 4 takta oscilatora. Pošto u ovim primerima koristimo interni oscilator na 4 MHz, jedan mašinski ciklus traje tačno jednu mikrosekundu (1 us). Medjutim, PBP je program višeg nivoa kod koga se jedna naredba prevodi u jednu ili nekoliko asemblerskih, zavisi od njene složenosti, ali se jednostavnije naredbe izvršavaju za nekoliko mašinskih ciklusa (sem naredbi kao PAUSE koja izaziva namerno zasutavljanje odn. pauzu u izvršavanju programa). Naredbe HIGH i LOW traju svega nekoliko mikrosekundi jer se sastoje od malog broja asemblerskih naredbi tako da možemo da kažemo da se izvršavaju gotovo trenutno.

Hajde da sada analiziramo program. Primećujemo da se iza svake naredbe nalazi odredjeni tekst koji počinje sa znakom tačka-zarez (;). Njime se u PBP-u odvaja komentar od programa i veoma je dobra praksa da se program bogato komentariše jer će vam posle nekog vremena verovatno biti nejasno zašto ste upotrebili baš tu naredbu. Iako zahteva malo više kucanja, utrošeno vreme u komentarisanje može višestruko da vam se isplati ako posle nekog vremena treba da analizirate ili prepravite program, pogotovo što komentari ne povećavaju sam izvršni program, već samo izvorni kod programa. Takodje je moguće koristiti i apostrof ('), ali je dobro da se naviknete na korišćenje tačka-zarez znaka zbog ubacivanja asemblerskih instrukcija u PBP program, koje ne mogu da se komentarišu apostrofom.

Prva naredba u programu, 'high portb.0' postavlja visok logički nivo, postavlja tzv. logičku jedinicu (tj. postavlja napon jednak naponu napajanja) na pin 0 porta B, čime uključuje LED povezanu na pin 0 porta B. MCU koji koristimo ima dva tzv. porta koji su obeleženi slovima A i B, od kojih svaki ima po 8 pinova koji su obeleženi brojevima od 0 do 7, gde je pin broj 0 povezan sa bitom najmanje težine. Odredjeni bit se adresira nazivom porta nakon koga sledi tačka i zatim broj odredjenog bita. Kod ovog PIC-a, PORTB.0 je fizički povezan sa pinom broj 6 na kućištu (ostale veze pogledajte na šemi).

Sledeća naredba, 'pause 500', pravi pauzu od 500 milisekundi, dok naredba 'low portb.0' isključuje LED tako što postavlja nizak logički nivo, postavlja tzv. logičku nulu (tj. postavlja napon jednak masi) na pin 0 porta B. Sledeća linija, kao što smo već naučili, pravi pauzu od pola sekunde, a naredba 'goto pocetak' preusmerava izvršavanje programa na naredbu koja se nalazi neposredno posle labele 'pocetak'. Kao što vidimo, u nazivu labele iza naredbi ne koristi se dvotačka; ona se upotrebljava samo kod kreiranja labele, ne i kod poziva na nju, tj. kada se koristi kao argument uz naredbe GOTO i GOSUB. I tako program počinje da se izvršava opet od početka, što znači da ovaj program bekosnačno ukjučuje i isključuje LED povezanu na pin 0 B porta sa pauzama od po pola sekunde, sve dok ne isključimo napajanje.

Na kraju se nalazi pseudonaredba 'end', a zovemo je tako jer ona nije zaista prava naredba za PIC, ne proizvodi nikakav kod, već služi da kompajler zna gde je kraj našeg programa. Da budemo precizni, naredba END u svari proizvodi jednu asemblersku instrukciju koja se koristi kao neka vrsta zaštite, ali to za nas u ovom trenutku nije bitno.



[Ovu poruku je menjao rsinisa dana 27.12.2012. u 07:08 GMT+1]
[ rsinisa @ 28.12.2012. 21:37 ] @
PIC koji koristimo je pun raznih hardverskih modula i to je sa jedne strane veoma dobro, ali sa druge strane zahteva pažljivo čitanje dokumentacije i podešavanje mnogobrojnih registara koji kontrolišu rad svih periferija. Jedna od mogućnosti ovog PIC-a je veliki izbor frekvenci internog oscilatora, kao što smo videli u jednoj od prethodnih poruka. PIC koji sam jako dugo koristio ima samo 4MHz interni oscilator pa sam u brzini prevideo da je potrebno podesiti jedan registar za 16F1827 kako bi oscilator radio na 4 MHz, jer podrazumevana vrednost je svega 500 kHz tako da primer koji smo napisali radi 8 puta sporije od predvidjene brzine. Da bi frekvenca bila adekvatna, porebno je podesiti registar OSCCON koji kontroliše rad oscilatora; pre početka programa treba dodati jednu liniju tako da program sada izgleda ovako:

Code:

    osccon=%01101000

pocetak:
    high portb.0        ;uključi LED na pinu 0 porta B
    pause 500           ;napravi pauzu od 500 milisekundi
    low portb.0         ;isključi LED
    pause 500           ;napravi pauzu od 500 milisekundi
    goto pocetak        ;idi na labelu pocetak
end                     ;oznaka kompajleru da je ovde kraj našeg programa


I još jedna napomena: naredba PAUSE x pravi pauzu u izvršavanju programa gde x predstavlja milisekunde, a može da bude od 1 do 65535.

Za one koji hoće da znaju više o registru OSCCON: pogledajte tehničke podatke za PIC16F1827, strana 65, "5.6 Oscillator Control Registers".
[ rsinisa @ 28.12.2012. 22:38 ] @
Sada kada imamo kompletan i ispravan program treba ga kompajlirati čime ćemo da dobijemo tzv. heks (.HEX) fajl kojim ćemo da programiramo mikrokontroler.
Pre kompajliranja treba snimiti program na standardan način, iz menija "File", opcija "Save" - možda je dobra varijanta da napravite direktorijum sa nazivom "PBP_tutorijal" ili sl. u kome ćete da čuvate sve primere koje ćemo da obradimo. Ako program nije prethodno snimljen, pri kompajliranju MCS će prvo od vas da zahteva da ga snimite. Ovaj program možete npr. da snimite pod imenom "primer_1".

Kompajliranje možemo da izvršimo na nekoliko načina: iz menija opcija "Project" pa "Compile", klikom na sličicu/dugme ispod menija na kome piše "Compile", ili pritiskom na taster F9. Koju god opciju da odaberete, ako je kompajliranje bilo uspešno u dnu MCS prozora treba da vidite poruku o uspešnosti i o količini utrošene programske memorije:



Vidi se da ovaj program zauzima 65 vorda.

Ako sada pogledate u direktorijum u koji ste snimili izvorni program videćete nekoliko fajlova od kojih svi imaju isto ime, ali različite nastavke (ekstenzije). Najvažniji su nam "primer_1.pbp" koji je tekstualni fajl izvornog programa i "primer_1.HEX" (takodje tekstualni fajl, ali specijalno formatizovan) kojim ćemo da isprogramiramo mikrokontroler.
[ rsinisa @ 29.12.2012. 07:03 ] @
Došlo je vreme da najzad isprobamo naš prvi program, tj. da njime isprogramiramo razvojni sistem; ovde ćemo detaljno da opišemo taj postupak pomoću PICKit2 programatora.

U konektor za napajanje CON7 uključite konektor iz ispravljača (plus pol je u sredini) napona od 7 do 25V (najbolje što približnije 12V, sve preko toga izazvaće povećano zagrevanje stabilizatora 7805 - IC3). Priključite PICkit2 (PK2 u daljem tekstu) programator u USB port, priključite ICSP konektor od PK2 na ICSP konektor razvojnog sistema (CON2). Programator ima konektor od 6 pinova, a na razvojnom sistemu ih ima 5 (jer je to dovoljno za programiranje) pa pazite da pin 1 od PK2 spojite na pin 1 ISCP konektora, kao prema slici, i pri tome ostaje jedan pin programatora slobodan (zaokružen na slici).



Sada pokrenite program "PICkit 2 V2.61". Softver bi trebalo da prepozna PIC i ispiše njegovu oznaku u drugom redu ispod menija "Device: PIC16F1827". U slučaju da ne uspe da ga prepozna, verovatno da ste program instalirali pe dosta vremena pa nemate najnoviji fajl sa podacima o novim PIC-evima. U tom slučaju potrebno je da skinete najnoviji fajl pod nazivom "PK2DeviceFile.dat" koji možete da nadjete ovde:

http://ww1.microchip.com/downl...iceDoc/PK2DFUpdate-1-62-14.zip

i zamenite ga u PICKit2 direktorijumu.
Zatim u softveru PK2 u meniju odaberite "Tools" -> "Target VDD Source" -> "Auto-Detect".



Sada u meniju programa odaberite opcije "File" pa "Import HEX", izaberite fajl "primer_1.HEX" koji se nalazi u direktorijumu u koji ste snimili izvorni fajl, kliknite na dugme "Write" i sačekajte par sekundi da se završi programiranje PIC-a. Ako je sve u redu, statusni prozor će biti ispunjen zelenom bojom sa tekstom: "Programming Successful", a LED D1 počeće da treperi frekvencom od 1 Hz. Sada možete da odspojite PK2 od razvojnog sistema.

Ako imate neki drugi programator, imate dve opcije:
1. Da izvadite PIC iz podnožja razvojnog sistema, ubacite u vaš programator i nakon programiranja ga vratite u razvojni sistem.
2. Ako vaš programator ima ICSP (ili ste ga sami dodali), možete da probate programiranje u kolu priključenjem na ISCP konektor, ali morate da odspojite J1 pre priključenja programatora kako ne bi došlo do "sudara" Vdd napona sa programatora sa onim iz razvojnog sistema. A možete i da odspojite Vdd sa vašeg programatora, a da ostavite J1 kratkospojen.

[Ovu poruku je menjao rsinisa dana 29.12.2012. u 14:23 GMT+1]
[ rsinisa @ 29.12.2012. 13:20 ] @
Za one koji bi da probaju C, drugar sa foruma goran_68 pokrenuo je tutorijal koji će manje-više da prati paralelno ovaj kurs BASIC-a, a možete da ga pratite na ovom linku

http://www.elitesecurity.org/t459971-TUTORIJAL-xc-picF
[ rsinisa @ 29.12.2012. 14:05 ] @
Primetili ste u prvom primeru da su sve naredbe pomerene udesno za 4 mesta, dok se labela nalazi uz levu ivicu. Potpuno je ispravno da i naredbe budu napisane uz levu ivicu, ali ja koristim takav način kako bi lako optički razdvojio labele ili linije sa komentarom od samog programa.

Primer 2
======
U ovom primeru koristi se postavka 1

Ovim primerom uključivaćemo i isključivati svih 8 LED odjednom koje su priključene na port B, umesto samo jedne. Pretpostavljam da ste i sami dobili ideju kako da se to uradi - isto kao u prethodnom primeru, samo ponovimo iste komande za svaki pin pojedinačno. Ne zaboravite da pre samog programa napišete linije u kojima su definisane konfiguracije i frekvenca oscilatora.

Code:

    osccon=%01101000
    anselb=0

pocetak:
    high portb.0        ;uključi LED na pinu 0 porta B (D1)
    high portb.1        ;uključi LED na pinu 1 porta B (D2)
    high portb.2        ;uključi LED na pinu 2 porta B (D3)
    high portb.3        ;uključi LED na pinu 3 porta B (D4)
    high portb.4        ;uključi LED na pinu 4 porta B (D5)
    high portb.5        ;uključi LED na pinu 5 porta B (D6)
    high portb.6        ;uključi LED na pinu 6 porta B (D7)
    high portb.7        ;uključi LED na pinu 7 porta B (D8)
    pause 500           ;napravi pauzu od 500 milisekundi
    low portb.0         ;isključi LED na pinu 0 porta B
    low portb.1         ;isključi LED na pinu 1 porta B
    low portb.2         ;isključi LED na pinu 2 porta B
    low portb.3         ;isključi LED na pinu 3 porta B
    low portb.4         ;isključi LED na pinu 4 porta B
    low portb.5         ;isključi LED na pinu 5 porta B
    low portb.6         ;isključi LED na pinu 6 porta B
    low portb.7         ;isključi LED na pinu 7 porta B
    pause 500           ;napravi pauzu od 500 milisekundi
    goto pocetak        ;idi na labelu pocetak

end                     ;oznaka kompajleru da je ovde kraj našeg programa



Vidimo da posle podešavanja registra OSCCON imamo novu liniju koja takodje služi za podešavanje hardvera. Oba porta imaju mogućnost rada sa analognim modulima koji su ugradjeni u PIC i povezani sa portovima. Proizvodjač je podesio da se pri uključenju PIC-a aktiviraju analogne funkcije I/O portova, a nama su ovde, za sada, potrebne digitalne pa moramo sami da isključimo analogne. Registri zaduženi za to su ANSELA za port A i ANSELB za port B, a pošto mi za sada radimo samo sa B portom, izmenili smo samo ANSELB. Kada je neki bit tog registra postavljen na 1, tada odgovarajući pin ima analognu funkciju što znači da moramo sve bitove da postavimo na 0 kako bi svi pinovi imali digitalnu funkciju. Mogli smo da napišemo i binarni oblik %00000000 kako bi smo videli vrednost za svaki pojedinačni bit, ali pošto su ionako svi bitovi 0, dekadni oblik je sasvim prikladan.

Naredbe koje slede su nam već poznate s tim što se menja argument uz naredbe 'high' i 'low'; prvo uključimo svih 8 LED jednu po jednu, bit po bit, pa napravimo pauzu od 500 milisekundi, zatim isključimo svih 8 LED, ponovo napravimo pauzu od 500 milisekundi pa se naredbom 'goto' vratimo na labelu 'pocetak' čime se program vraća na početak i tako vrti u krug.
Kao što se primetili, bitovi su obeleženi brojevima od 0 do 7, a ne od 1 do 8 kako bi bilo logičnije na prvi pogled. To je uradjeno zbog binarnog brojnog sistema koji smo već obradili.

Snimite ovaj program pod nazivom "primer_2" i iskompajlirajte ga; nakon kompajliranja vidimo da ovaj program zauzima 123 vorda programske memorije. Isprogramirajte PIC na razvojnom sistemu sa dobijenim "primer_2.HEX" fajlom i pogledajte šta se dešava.

[Ovu poruku je menjao rsinisa dana 30.12.2012. u 09:39 GMT+1]
[ rsinisa @ 29.12.2012. 14:18 ] @
Naredbe 'high' i 'low' iako deluju kao odlične za ovakve primene, ipak nisu idealne i ne treba ih često koristiti. O čemu se radi? Pinovi mikrokontrolera imaju mogućnost da budu ulazni ili izlazni (I/O pinovi), što znači da mogu ili da provere koje je logičko stanje na njima (ulazna funkcija), ili da postave na pinove neko logičko stanje (izlazna funkcija) kao što je bio slučaj u ova dva primera. Funkciju pina odredjujemo postavljanjem odgovarajućeg stanja u registar specijalne namene kojih ima 2 za 18-to pinske PIC-eve i zovu se TRISA za port A i TRISB za port B - ako je neki bit tog registra postavljen na logičko 1 onda je odgovarajući pin ulazni, a ako je postavljen na logičko 0 onda je odgovarajući pin izlazni. Ovo se jednostavno pamti ako uvedemo kao asocijaciju engleske reči INPUT (ulaz) i OUTPUT (izlaz); vidimo da reč INPUT počinje slovom I koje asocira na broj 1, dok reč OUTPUT počinje slovom O koje asocira na broj 0.

Naredbe 'high' i 'low' pre postavljanja odgovarajućeg stanja postavljaju potreban pin kao izlazni, i to svaki put kada se naredba izvrši, ali to je potpuno nepotrebno jer se stanje svih registara, pa i TRISA i TRISB, pamti sve dok ne nestane napajanje, ili dok se ne izmeni njihov sadržaj (namerno ili slučajno), što znači da je program nepotrebno duži, a samim tim i sporiji. To u ovim prethodnim primerima i nije toliko važno jer progam ionako čeka dva puta po pola sekunde, ali u praksi ćete se sretati sa situacijama gde svaka mikrosekunda uštede može mnogo da vam znači.

Pa čemu onda ove dve naredbe? U praksi se najčešće jedan pin koristi samo kao ulazni ili samo kao izlazni, ali ima i situacija kada se jedan isti pin u jednom uredjaju koristi u jednom momentu kao ulazni, a u drugom kao izlazni. U tim situacijama, ako u nekom trenutku nismo sigurni da li je pin postavljen kao ulazni ili izlazni možemo da ih upotrebimo, ali je moja preporuka da programer ne koristi ove naredbe i da sam vodi računa o TRIS registrima. Kako se to radi, videćemo u sledećim primerima.
[ rsinisa @ 30.12.2012. 08:23 ] @
U primeru 2 potkrala se jedna greška pa sam ispravio tekst i program; oni koju su već pročitali taj tekst treba ponovo da ga pogledaju.
[ rsinisa @ 30.12.2012. 09:04 ] @
Još jedan tutorijal koji će da prati ove primere, ovoga puta u asembleru, pokrenuo je drugar elektrostudio, a možete da ga pratite na ovom linku:

http://www.elitesecurity.org/t459992-tutorijal-MPASM-PICF
[ rsinisa @ 02.01.2013. 05:49 ] @
Primer 3
======
U ovom primeru koristi se postavka 1.

Vratićemo se prvom primeru, koji uključuje i isključuje jednu LED, ali ovoga puta ćemo to da uradimo malo drugačije.

Code:

    osccon=%01101000 ;interni oscilator na 4MHz
    anselb=0         ;ceo port B digitalni
    
    trisb.0=0        ;postavi pin 0 porta B kao izlazni

pocetak:
    portb.0=1        ;uključi LED povezanu na pin 0 porta B
    pause 500        ;napravi pauzu od 500 milisekundi
    portb.0=0        ;isključi LED povezanu na pin 0 porta B
    pause 500        ;napravi pauzu od 500 milisekundi
    goto pocetak     ;idi na labelu pocetak

end


Prva PBP naredba 'trisb.0=0' postavlja nulti bit TRISB registra na logičku 0 čime, kao što smo objasnili, postavlja pin 0 porta B kao izlazni (postavljanje odredjenog I/O pina kao ulaznog ili izlaznog naziva se još i odredjivanje smera tog pina). Posle labele 'pocetak' sledi naredba 'portb.0=1' koja postavlja nulti bit B porta na logičko 1 i time uključuje LED, pa zatim posle već dobro poznate pauze od pola sekunde, naredba 'portb.0=0' postavlja taj isti pin na logičko 0, i posle još jedne pauze od pola sekunde naredba 'goto pocetak' vraća program na naredbu posle labele 'pocetak'. Kao što vidimo, naredba 'trisb.0=0' se više nikada ne izvršava jer za tim nema potrebe. Na ovaj način program se brže izvršava, a zahvaljujući nekorišćenju naredbi 'high' i 'low' program je nešto kraći - ovaj program zauzima 63 vorda programske memorije umesto 65 kao u primeru 1.

Treba još imati na umu da se prilikom priključenja PIC-a na napajanje svi bitovi TRISA i TRISB registra postavljaju na 1, što znači da su svi pinovi oba porta postavljeni kao ulazi, dok PORTA i PORTB zauzimaju proizvoljno, nepoznato stanje.
[ rsinisa @ 05.01.2013. 10:24 ] @
Primer 4
======
U ovom primeru koristi se postavka 1.

Sada ćemo da izmenimo primer 2 koji uključuje i isključuje svih 8 LED odjednom na isti način kao što smo izmenili malo pre primer 1, izbeći ćemo naredbe 'high' i 'low' i koristićemo direktno izmene na TRISB registru, pa da vidimo koliku ćemo uštedu da ostvarimo kada je u pitanju programska memorija.

Code:

inic:
    osccon=%01101000        ;interni oscilator na 4MHz
    anselb=0                ;ceo port B digitalni

    trisb.0=0               ;postavi pin 0 porta B kao izlazni
    trisb.1=0               ;postavi pin 1 porta B kao izlazni
    trisb.2=0               ;postavi pin 2 porta B kao izlazni
    trisb.3=0               ;postavi pin 3 porta B kao izlazni
    trisb.4=0               ;postavi pin 4 porta B kao izlazni
    trisb.5=0               ;postavi pin 5 porta B kao izlazni
    trisb.6=0               ;postavi pin 6 porta B kao izlazni
    trisb.7=0               ;postavi pin 7 porta B kao izlazni

pocetak:
    portb.0=1               ;uključi LED povezanu na pin 0 porta B
    portb.1=1               ;uključi LED povezanu na pin 1 porta B
    portb.2=1               ;uključi LED povezanu na pin 2 porta B
    portb.3=1               ;uključi LED povezanu na pin 3 porta B
    portb.4=1               ;uključi LED povezanu na pin 4 porta B
    portb.5=1               ;uključi LED povezanu na pin 5 porta B
    portb.6=1               ;uključi LED povezanu na pin 6 porta B
    portb.7=1               ;uključi LED povezanu na pin 7 porta B
    pause 500               ;napravi pauzu od 500 milisekundi
    portb.0=0               ;isključi LED povezanu na pin 0 porta B
    portb.1=0               ;isključi LED povezanu na pin 1 porta B
    portb.2=0               ;isključi LED povezanu na pin 2 porta B
    portb.3=0               ;isključi LED povezanu na pin 3 porta B
    portb.4=0               ;isključi LED povezanu na pin 4 porta B
    portb.5=0               ;isključi LED povezanu na pin 5 porta B
    portb.6=0               ;isključi LED povezanu na pin 6 porta B
    portb.7=0               ;isključi LED povezanu na pin 7 porta B
    pause 500               ;napravi pauzu od 500 milisekundi
    goto pocetak            ;idi na labelu pocetak

end


Ovde nema naredbi koje već nismo koristili, samo smo proširili akciju na sve pinove B porta. Na početku, posle labele 'inic', nalazi se blok sa naredbama koje podešavaju oscilator i digitalnu funkciju B porta, i koje menjaju TRISB registar jedan po jedan bit, odn. koje postavljaju sve pinove B porta kao izlazne i taj deo se izvrši samo jednom pri uključenju, posle toga se više nikada ne izvršava. To podešavanje početnih vrednosti raznih registara koje se obavlja samo jednom na početku programa naziva se inicijalizacija i ubuduće ćemo se stalno sretati sa time. Labela 'inic' ovde nema nikakvu praktičnu vrednost jer ne postoji naredba skoka koja upućuje na nju, ali smo hteli da se jasno zna da je to inicijalni blok, a biće primera gde će nam ona trebati, pa je vreme da se navikavamo na to.

U poredjenju sa primerom 2 za koji je utrošeno 123 vorda, ovaj primer zauzima samo 84 što je značajna ušteda zahvaljujući drugačije napisanom programu, a koji radi potpuno istu stvar. Može li ovo još kraće? Može, a kako videćemo već u sledećem primeru.
[ rsinisa @ 09.01.2013. 05:01 ] @
Primer 5
======
U ovom primeru koristi se postavka 1.

Code:

inic:
    osccon=%01101000        ;interni oscilator na 4MHz
    anselb=0                ;ceo port B digitalni
    trisb=%00000000         ;svi bitovi B porta izlazni

pocetak:
    portb=%11111111         ;postavi sve bitove B porta na logičko 1, tj. uključi sve LED istovremeno
    pause 500               ;napravi pauzu od 500 milisekundi
    portb=%00000000         ;postavi sve bitove B porta na logičko 0, tj. isključi sve LED istovremeno
    pause 500               ;napravi pauzu od 500 milisekundi
    goto pocetak            ;idi na labelu pocetak

end


Obzirom da uključujemo svih 8 LED na portu B iskoristićemo mogućnost da postavimo stanje celog registra odjednom umesto pojedinačnih bitova, kako na TRISB registru, tako i na PORTB registru i time značajno skratimo program. U naredbi 'trisb=%00000000' ne koristimo više tačku koja je označavala da radimo sa jednim bitom, što znači da radimo sa celim registrom odjednom, sa svih 8 bitova. Broj %00000000 napisan je u binarnom obliku i mogao je da bude napisan i kao 0, ali se na ovaj način veoma lepo i jasno vidi vrednost za svaki pojedinačni bit - krajnja desna cifra predstavlja bit 0, a krajnja leva, uz znak %, predstavlja bit 7. Isto važi i za naredbu 'portb=%11111111'; mogla je da bude napisana sa brojem u decimalnom obliku i tada bi glasila 'portb=255', ali se u binarnom obliku jasno vidi da su svi bitovi postavljeni na logičko 1, što znači da su sve LED uključene.

Time što smo odjednom postavili sve bitove PORTB i TRISB registara uštedeli smo čak 59 vorda u odnosu na program iz primera 2, a program i dalje radi potpuno istu stvar - program iz primera 2 sa 123 vorda sveo se na svega 64, što je ogromna ušteda, iz čega se vidi da nije dovoljno samo poznavati naredbe PBP-a, već i razmisliti malo koji pristup upotrebiti u odredjenoj situaciji, a za to će Vam trebati malo iskustva.

[Ovu poruku je menjao rsinisa dana 09.01.2013. u 08:23 GMT+1]
[ rsinisa @ 12.01.2013. 08:13 ] @
Registri specijalne namene
=================
Već ste primetili da je pre samog programa potrebno podesiti odredjene registre kako bi PIC funkcionisao onako kako nam je potrebno, tj. da bi podesili razne komponente ugradjene u PIC i njihove funkcije. Do sada smo to radili sa registrima OSCCON, ANSELB, TRISB i PORTB. Da, i PORTB spada u te registre (kao i PORTA) s tim da su njegovi bitovi povezani direktno na fizičke izvode na kućištu. Svi ti registri zovu se registri specijalne namene (skraćeno SFR od engleskog izraza "special function registers").

Spisak svih tih registara možete da nadjete u tabeli 3-3 tehničkih podataka počev od strane 23. Vidi se da ih ima mnogo, da su podeljeni u tzv. banke i da postoje čak 32 banke; takva podela je nasledstvo stare arhitekture ove familije PIC-eva koja ne može da adresira više od 128 bajtova odjednom kada se radi o pristupu RAM memoriji u koju su oni smešteni. Da bi se adresirao odredjeni SFR, potrebno je prethodno podesiti banku u kojoj se on nalazi, ali o tome ne treba da brinete jer sam PBP vodi računa o tome, vaše je samo da dodelite odgovarajuću vrednost željenom registru. Jedino ako ubacujete i asembler u PBP program onda morate sami da vodite računa o ispravnom podešavanju banke.

Na prvi pogled rad sa tolikim registrima deluje jako komplikovano, ali setite se šta radi dirigent orkestra - on ne radi ništa drugo sem što u odredjenom momentu izda komandu koji će instrumet da zasvira i tako izvede željenu kompoziciju. Tako je i sa ovim registrima, potrebno je samo da u odredjenom trenutku dodelite pravu vrednost nekom od SFR-ova i vaš uredjaj će da radi upravo onako kako ste zamislili.
[ rsinisa @ 15.01.2013. 21:00 ] @
Primer 6
======
U ovom primeru koristi se postavka 1.

Postoje situacije u kojima ne treba da menjamo stanje celog porta odjednom već pojedinačne bitove kako nebismo poremetili već postavljena stanja. Recimo da treba da trepere LED D5 i D6 dok su D1 i D2 uključene, a D3, D4, D7 i D8 isključene. Taj primer bi izgledao ovako:

Code:

inic:
    osccon=%01101000        ;interni oscilator na 4MHz
    anselb=0                ;ceo port B digitalni
    trisb=%00000000         ;svi bitovi B porta izlazni
    portb=%00000011         ;postavi početno stanje na port B, tj. uključi D1 i D2

pocetak:
    portb.4=1               ;uključi LED povezanu na pin 4 porta B (D5)
    portb.5=1               ;uključi LED povezanu na pin 5 porta B (D6)
    pause 500               ;napravi pauzu od 500 milisekundi
    portb.4=0               ;isključi LED povezanu na pin 4 porta B
    portb.5=0               ;isključi LED povezanu na pin 5 porta B
    pause 500               ;napravi pauzu od 500 milisekundi
    goto pocetak            ;idi na labelu pocetak

end


Medjutim, u ovom programu se krije jedna zamka koja se, doduše, ovde neće "aktivirati", ali kada bismo umesto LED D5 imali neko kapacitivno opterećenje, mogli bismo da imamo problem, kao što sam ga ja imao u jednom uredjaju koji sam pravio. O čemu se radi?

Ako se vrše dva uzastopna postavljanja pinova jednog porta, može da dodje do nepravilnog postavljanja novog stanja jer se svaki pristup portovima vrši u 3 koraka: čitaj-izmeni-upiši (na engleskom: read-modify-write) što konkretno znači da se kod upisa novog stanja na port zapravo prvo preuzme stanje direktno sa pinova u interni registar, zatim se izmeni sadržaj tog registra i na kraju se njegovo stanje prosledi na port. Ako se na jednom od pinova nalazi neko kapacitivno opterećenje ili je pin strujno preopterećen, velike su šanse da će druga izmena porta da poništi prvu jer strujno preopterećen pin ima manji napon koji se onda tumači kao logička 0 umesto 1.

Pojasnićemo to na našem primeru: zamislimo da je na RB4 priključen kapacitivni potrošač kome je potrebno neko vreme da se napuni i stabilizuje napon, a na RB5 neki drugi potrošač. Pojašnjenje za početnike: kod priključenja napona na kapacitivno opterećenje prvo se javlja protok struje koja puni kondenzator, dok je napon na njegovim izvodima 0 volti i zatim se povećava, tako da tek nakon izvesnog vremena dostigne nivo koji može da se "protumači" kao visok logički nivo.

Pogledajmo deo ovog primera:

Code:

    portb=%00000011         ;postavi početno stanje na port B, tj. uključi D1 i D2

pocetak:
    portb.4=1               ;uključi LED povezanu na pin 4 porta B (D5)
    portb.5=1               ;uključi LED povezanu na pin 5 porta B (D6)


Naredba "portb.4=1" treba da postavi bit 4 porta B na logičko 1, tj. na napon napajanja. Zbog principa čitaj-izmeni-upiši biće pročitano stanje sa pinova u interni registar koji će da sadrži vrednost %00000011 jer smo pre toga postavili to stanje na port B, a zatim će biti setovan četvrti bit, i to novo stanje vraćeno na port, tj. na port će biti poslato %00010011. Kod sledeće naredbe "portb.5=1", takodje će prvo da bude pročitano stanje sa pinova B porta, ali pošto je na pin 4 priključeno kapacitivno opterećenje, stanje na njemu će da bude i dalje logička nula (jer se kondenzator nije napunio) pa će umesto 00010011 biti pročitano 00000011, zatim će biti setovan peti bit i takvo stanje vraćeno na port pa će na kraju umesto 00110011 na pinovima biti 00100011. Ovo može da se prevazidje na nekoliko načina, a kako, videćemo u sledećim primerima.

[Ovu poruku je menjao rsinisa dana 15.01.2013. u 22:27 GMT+1]
[ rsinisa @ 19.01.2013. 05:51 ] @
Da bismo rešili problem koji nam pravi kapacitivno opterećenje, očigledno je da moramo da napravimo vremensku zadršku izmedju dva uzastopna menjanja pinova istog porta kako bi kondenzator imao vremena da se napuni. Jedan od načina je da reorganizujemo program kako ne bismo ubacivali dodatne instrukcije koje bi trošile programsku memoriju. Pretpostavimo da deo programa izgleda ovako:

Code:

    portb.4=1
    portb.5=1
    sekunda=sekunda + 1
    if sekunda=60 then
      sekunda=0
    endif


Vidimo da posle naredbe "portb.5=1" imamo nekoliko naredbi čije izmeštanje ne dovodi ni do kakvih promena koje bi nam remetile rad programa tako da možemo da ih premestimo čime bi se pojavila odredjena zadrška izmedju dva uzastopna postavljanja stanja B porta koja bi omogućila da se kondenzator napuni, pa bi program izgledao ovako (naredbu "if ... then ... endif" objasnićemo drugi put):

Code:

    portb.4=1
    sekunda=sekunda + 1
    if sekunda=60 then
      sekunda=0
    endif
    portb.5=1


Primer 7:
======
U ovom primeru koristi se postavka 1.

Medjutim, u našem programu iz primera 6 nemamo nikakve naredbe koje bi mogli da premestimo, a da ne poremetimo logiku i rad programa pa je potrebno da na neki drugi način ubacimo pauzu. Jedan od načina je naredba PAUSEUS, koja slično naredbi PAUSE pravi pauzu time što se zaustavlja izvršavanje programa, a čija sintaksa glasi ovako:

PAUSEUS period

gde 'period' označava vreme u mikrosekundama i može da se kreće od 1 do 65535

Code:

inic:
    osccon=%01101000        ;interni oscilator na 4MHz
    anselb=0                ;ceo port B digitalni
    trisb=%00000000         ;svi bitovi B porta izlazni
    portb=%00000011         ;postavi početno stanje na port B, tj. uključi D1 i D2

pocetak:
    portb.4=1               ;uključi LED povezanu na pin 4 porta B (D5)
    pauseus 24              ;napravi pauzu od 24 mikrosekunde
    portb.5=1               ;uključi LED povezanu na pin 5 porta B (D6)
    pause 500               ;napravi pauzu od 500 milisekundi
    portb.4=0               ;isključi LED povezanu na pin 4 porta B
    pauseus 24              ;napravi pauzu od 24 mikrosekunde
    portb.5=0               ;isključi LED povezanu na pin 5 porta B
    pause 500               ;napravi pauzu od 500 milisekundi
    goto pocetak            ;idi na labelu pocetak

end


Problem kod upotrebe ove naredbe je što ona sama zauzima odredjeni broj lokacija programske memorije, i što za ovaj PIC pri frekvenci od 4 MHz pauza ne može da bude manja od 24 us (mikrosekunde) što može da bude previše vremena za punjenje kondenzatora. Nije probem u tome što će kondenzator duže da se puni, njemu to ne smeta, kada se napuni punjenje će da se prekine samo pošto je to osobina kondenzatora, ali 24 us može da bude u nekim situacijama nepotrebno gubljenje vremena jer je moguće da se kondenzator već napunio. Zato ćemo u pomoć da pozovemo jednu asemblersku instrukciju kako bi napravili kraću zadršku.
[ rsinisa @ 27.01.2013. 00:54 ] @
Primer 8:
======
U ovom primeru koristi se postavka 1.

Tvorci PBP-a su omogućili ubacivanje asemblerskih naredbi u BASIC što i ne čudi jer je potpunu kontrolu nad MCU-om moguće ostvariti jedino pomoću asemblera. Postoje dve naredbe, jedna za ubacivanje samo jedne asemblerske naredbe, i druga za blok naredbi.

Sintaksa za prvu je:

@ asemblerska_naredba

Kada se znak @ upotrebi na početku linije, to znači da iza mora da sledi jedna asemblerska naredba. Ono što je bitno da zapamtite je da upotreba znaka @ postavlja banku na 0 i da ovu naredbu ne koristite za promenu banke, mada vam to za sada ne znači mnogo, ali trebaće kasnije. Iskoristićemo ovu naredbu da napravimo kratku pauzu u našem prethodnom primeru od svega jedne µs:

Code:

inic:
    osccon=%01101000        ;interni oscilator na 4MHz
    anselb=0                ;ceo port B digitalni
    trisb=%00000000         ;svi bitovi B porta izlazni
    portb=%00000011         ;postavi početno stanje na port B, tj. uključi D1 i D2

pocetak:
    portb.4=1               ;uključi LED povezanu na pin 4 porta B (D5)
@   nop                     ;napravi pauzu od 1 mikrosekunde
    portb.5=1               ;uključi LED povezanu na pin 5 porta B (D6)
    pause 500               ;napravi pauzu od 500 milisekundi
    portb.4=0               ;isključi LED povezanu na pin 4 porta B
@   nop                     ;napravi pauzu od 1 mikrosekunde
    portb.5=0               ;isključi LED povezanu na pin 5 porta B
    pause 500               ;napravi pauzu od 500 milisekundi
    goto pocetak            ;idi na labelu pocetak

end


Asemblerska naredba NOP je skraćenica od "No OPeration", u prevodu "nema operacije", tj. ova naredba ne radi baš ništa! Pa čemu onda služi uopšte? Korisna je upravo za ovakve stvari gde je potrebno napraviti neku pauzu koja neće da promeni baš ništa, ni jedan jedini bit bilo kog registra. Pošto PBP nema instrukciju koja ne radi ništa, u ovakvim situacijama primorani smo da upotrebimo ovu asemblersku instrukciju. Njeno izvršenje traje 1 mašinski ciklus što je u našem slučaju tačno 1 µs što bi moglo da bude prekratka pauza da se napuni kondenzator pa možemo da stavimo više ovih naredbi uzastopno.

Ako želimo da napravimo pauzu od 4 µs, treba da stavimo 4 ove naredbe i tada bi deo programa izgledao ovako:

Code:

pocetak:
    portb.4=1               ;uključi LED povezanu na pin 4 porta B (D5)
@   nop                     ;napravi pauzu od 1 mikrosekunde
@   nop                     ;napravi pauzu od 1 mikrosekunde
@   nop                     ;napravi pauzu od 1 mikrosekunde
@   nop                     ;napravi pauzu od 1 mikrosekunde
    portb.5=1               ;uključi LED povezanu na pin 5 porta B (D6)
    pause 500               ;napravi pauzu od 500 milisekundi

[ rsinisa @ 28.01.2013. 15:01 ] @
Primer 9:
======
U ovom primeru koristi se postavka 1.

Pisanje više asemblerskih naredbi korišćenjem znaka @ može da bude malo naporno i nepraktično, i zato postoje naredbe za blok asemblerskih komandi čija sintaksa glasi ovako:

ASM
asemblerske instrukcije
ENDASM


Ovo zapravo i nisu PBP naredbe već pseudonardbe pošto ne proizvode nikakav kod već obaveštavaju PBP kompajler da ono što sledi nisu njegove naredbe i ne treba da ih prevodi pa će sav kod izmedju njih samo preneti dalje asembleru. Maksimalna veličina teksta tog bloka, uključujući i komentare, ne može da bude veća od 8 KB pa ako je taj tekst veći, jednostavno ga podelite u više ASM ... ENDASM blokova.

Kao i znak @, ASM postavlja banku na 0 pa pre ENDASM morate da je vratite opet na 0 ako ste je menjali u tom bloku. Takodje ni reč ENDASM ne sme da se nadje nigde u tom bloku asemblerskih naredbi kao komentar jer će PBP to da shvati kao kraj bloka.

Sada naš program iz prethodnog primera može da izgleda ovako:

Code:

inic:
    osccon=%01101000        ;interni oscilator na 4MHz
    anselb=0                ;ceo port B digitalni
    trisb=%00000000         ;svi bitovi B porta izlazni
    portb=%00000011         ;postavi početno stanje na port B, tj. uključi D1 i D2

pocetak:
    portb.4=1               ;uključi LED povezanu na pin 4 porta B (D5)
asm
    nop                     ;napravi pauzu od 1 mikrosekunde
    nop                     ;napravi pauzu od 1 mikrosekunde
    nop                     ;napravi pauzu od 1 mikrosekunde
    nop                     ;napravi pauzu od 1 mikrosekunde
endasm
    portb.5=1               ;uključi LED povezanu na pin 5 porta B (D6)
    pause 500               ;napravi pauzu od 500 milisekundi
    portb.4=0               ;isključi LED povezanu na pin 4 porta B
asm
    nop                     ;napravi pauzu od 1 mikrosekunde
    nop                     ;napravi pauzu od 1 mikrosekunde
    nop                     ;napravi pauzu od 1 mikrosekunde
    nop                     ;napravi pauzu od 1 mikrosekunde
endasm
    portb.5=0               ;isključi LED povezanu na pin 5 porta B
    pause 500               ;napravi pauzu od 500 milisekundi
    goto pocetak            ;idi na labelu pocetak

end



Tako smo uz pomoć asemblerske naredbe rešili problem kratke vremenske zadrške za kapacitivna opterećenja; to rešenje možemo da primenimo i u drugim slučajevima kada nam je potrebna pauza kraća od minimalne koju nam omogučava PBP naredba PAUSEUS.

Ako u praksi naidjete na problem kapacitivnog opterećenja, odredjivanje potrebne zadrške može da se uradi samo praktično tj. sistemom probe. Moglo bi i uz malo matematike, ali je tu nekoliko nepoznanica koje prosečan korisnik ne može da zna niti da izmeri.
[ rsinisa @ 06.02.2013. 05:15 ] @
Primer 10:
======
U ovom primeru koristi se postavka 1.

Vidimo da smo se ovde "borili" softverskim metodama protiv jednog problema kojeg su konstruktori PIC kontrolera odlučili da reše na hardverskom nivou pa su dodali mogućnost čitanja stanja sa izlaza leča. Leč možemo da shvatimo kao memorijski element koji pamti jedan bit, i kod koga stanje na izlazu zavisi od stanja na ulazu.



Na slici je prikazan uprošćeni prikaz jednog pina PIC kontrolera sa koje se vidi da se ovde kao leč koristi D flip-flop (pravouganik ispod koga piše "Data Register"). Kada čitamo stanje sa porta, signal ide putanjom crvene boje obeležene brojem 1, tj, ide od pina (predstavljen precrtanim kvadratom ispod koga piše I/O pin) preko logičkog I kola kroz bafer (predstavljen trouglom) na sabirnicu podataka ("Data Bus").
Kada čitamo stanje iz leča, signal sada ide putanjom crvene boje obeležene brojem 2, tj. ide od izlaza leča (obeležen slovom "Q") preko bafera na sabirnicu podataka, a pošto je izlaz leča odvojen od pina baferom, vidimo da preopterećenje pina neće da dovede do promene stanja na Q izlazu tako da će uvek da bude pročitano upravo ono stanje koje je i upisano u leč, a ne aktuelno stanje na pinu.

Da bismo mogli da čitamo stanje leča, konstruktori su dodali SFR registre koji su označeni sa LATX, gde X pedstavlja naziv porta, tj. za PIC koji koristimo to su registri LATA i LATB tako da bi naš program iz primera 6 sada izgledao ovako:

Code:

inic:
    osccon=%01101000        ;interni oscilator na 4MHz
    anselb=0                ;ceo port B digitalni
    trisb=%00000000         ;svi bitovi B porta izlazni
    latb=%00000011          ;postavi početno stanje na port B, tj. uključi D1 i D2

pocetak:
    latb.4=1                ;uključi LED povezanu na pin 4 porta B (D5)
    latb.5=1                ;uključi LED povezanu na pin 5 porta B (D6)
    pause 500               ;napravi pauzu od 500 milisekundi
    latb.4=0                ;isključi LED povezanu na pin 4 porta B
    latb.5=0                ;isključi LED povezanu na pin 5 porta B
    pause 500               ;napravi pauzu od 500 milisekundi
    goto pocetak            ;idi na labelu pocetak

end


Sa slike se vidi da su upisi u port i u leč potpuno ista stvar, ali zbog principa čitaj-izmeni-upiši, koji funkcioniše i pri izmeni LATX registra, ne može da dodje do lažnog očitavanja ako je pin preopterećen pa nema potrebe za bilo kakvom zadrškom izmedju dve uzastopne izmene dva pina istog porta.

Pa dobro, ako postoje LATX registri, zašto smo potrošili nekoliko lekcija na obradu problema preopterećenog pina? Najpre zato što LATX registre nemaju svi PIC-evi; ako se budete ozbiljno bavili konstrukcijom uredjaja, koristićete razne PIC kontrolere i pre ili kasnije naići ćete na neki koji nema te registre pa treba da znate kako da se izborite sa potencijalnim problemom.

Medjutim, čitanje stanja direktno sa pina može da bude korisno u nekim situacijama jer možete da utvrdite da li se stanje na izlazu slaže sa postavljenim i na osnovu toga možete, recimo, da detektujete neki problem ili preopterećenje.
[ rsinisa @ 12.02.2013. 17:23 ] @
Promenljive (varijable)
===============
Da bi mogli da radimo obradu podataka, potrebne su nam promenljive koje će da čuvaju vrednosti kojima baratamo, a to su u stvari lokacije u RAM memoriji. Da bi mogli da ih koristimo moramo na početku programa da ih definišemo, tj. da im damo imena i odredimo tip podatka koji će da čuvaju, ne moramo da brinemo o tome koje konkretne RAM lokacije zauzimaju jer o tome vodi računa sam PBP.

PBP poznaje 4 tipa promenljivih, a to su: BIT, BYTE, WORD i LONG, s tim da poslednja može da se koristi samo kod PIC18 serije. Za BIT, BYTE i WORD ne postoji mogućnost rada sa negativnim i decimalnim brojevima, mada se to uz pomoć odredjenih tehnika može izvesti, dok je LONG u formi drugog komplementa što znači da može da čuva i negativne cele brojeve. Svaki od ovih tipova promenljivih može da se definiše kao skalar ili kao niz.

Definisanje skalara
-----------------------
Sintaksa za kreiranje skalarnih promenljivih je:

Ime_promenljive VAR tip {.modifikator}

Ime_promenljive mora da bude jedinstveno i ne može da bude rezervisana reč (kompletan spisak rezervisanih reči možete da nadjete u uputstvu za PBP, poglavlje 8.8.)

Lekciju o veličinama ovih tipova, tj. koliko bitova odn. bajtova zauzimaju smo već obradili pa pogledajte da se podsetite koje su moguće vrednosti jer je jako bitno da definišete odgovarajući tip podatka kako ne bi imali pogrešne rezultate.

Modifikator može da se upotrebi da malo bolje definiše promenljivu, a može da bude:

- adresa; omogućava odredjivanje tačne adrese RAM lokacije na kojoj se nalazi promenljiva.
- BANKX; omogućava da se promenljiva smesti u željenu banku.
- SYSTEM; podrazumevano ponašanje PBP-a je da interno doda donju crtu ispred naziva promenljive pri kreiranju asemblerskog koda (to je jedna od faza kompajliranja PBP programa). Ovaj modifikator sprečava to dodavanje tako da je promenljiva istog naziva i u PBP i u asmeblerskom kodu.

Primeri kreiranja skalarnih promenljivih:
Code:

moj_flag        var bit  ; promenljiva tipa bit
minuti          var byte ; promenljiva tipa bajt
sekunde         var word ; promenljiva tipa vord
stotinke        var byte bank0  ; promenljiva tipa bajt u banci 0
desetinke       var byte system ; promenljiva tipa bajt bez ubacivanja donje crte ispred imena
sekunda         var byte bank0 system ; kombinovano kao dve prethodne
karakter1       var byte $70  ; promenljiva tipa bajt koja se nalazi na adresi 0x70 (heksadekadno)


---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:


[Ovu poruku je menjao rsinisa dana 12.02.2013. u 21:46 GMT+1]
[ rsinisa @ 22.02.2013. 20:26 ] @
Definisanje nizova
----------------------
Nizovi nam služe da lakše baratamo većim količinama podataka. Niz je ograničen uređen skup promenljivih istog tipa, koje se nazivaju
komponente niza. Komponente niza često nazivamo i elementima ili članovima niza. Svakom elementu niza pridružen je indeks, uz pomoć koga je moguće pristupiti odgovarajućem elementu. Mogu da budu jednodimenzioni ili višedimenzioni, a PBP poznaje samo jednodimenzione.

Kreiraju se isto kao i skalari s tim da se u uglastoj zagradi navede broj elemenata tog niza, a važe svi modifikatori kao i za kreiranje skalara. Npr. ako hoćemo da kreiramo niz pod nazivom "vrednost" tipa bajt od 10 elemenata uradićemo to ovako:

Code:

vrednost var byte[10]


Ovime smo kreirali niz od 10 promenljivih sa vrednostima indeksa od 0 do 9, tj. moglo bi da se kaže da smo kreirali 10 promenljivih koja se zovu:
vrednost[0], vrednost[1], vrednost[2], vrednost[3], vrednost[4], vrednost[5], vrednost[6], vrednost[7], vrednost[8] i vrednost[9]

Zbog načina na koji se nizovi smeštaju u RAM memoriji, broj elemenata je ograničen u zavisnosti od tipa niza i samog PIC MCU-a:


Tip PIC18 Ostali PIC-evi
====================================================
Bit 256 256
----------------------------------------------------
Byte ograničeno količinom 96
ugradjenog RAM-a
----------------------------------------------------
Word ograničeno količinom 48
ugradjenog RAM-a
----------------------------------------------------
Long ograničeno količinom nije omogućeno
ugradjenog RAM-a
----------------------------------------------------


Za PIC kontrolere sa 12-to ili 14-to bitnim jezgrom (PIC10, PIC12 i PIC16) jedan niz mora da se nadje unutar jedne banke, ali ne treba da mislite o tome, kompajler će da generiše grešku ako to nije u stanju da uradi.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:

[ rsinisa @ 26.02.2013. 09:16 ] @
Upotreba skalarnih promenljivih
--------------------------------------
Njihova upotreba je veoma jednostavna, samo navedete ime u komandi ili nekom izrazu, pri čemu treba imati na umu da PBP zna o kakvom tipu je reč i na osnovu toga donosi "odluke" pa morate da upotrebite odgovarajući tip za konkretne potrebe. Ne koristite promenljivu većeg tipa nego što Vam je potrebno jer ćete pri ispravnom korišćenju dobiti kraći i brži program. Ako npr. očekujete da vrednost neke promenljive ne predje 255, obavezno upotrebite BYTE tip promenljive. Takodje, ako vam je za neku indikaciju dovoljna informacija 1 ili 0, upotrebite BIT tip.

Primeri upotrebe:
Code:

B_port      var byte
lokacija    var word


    B_port = portb        ; vrednost B porta smesti u promenljivu 'B_port'
    lokacija = 0          ; promenljivoj 'lokacija' dodeli vrednost 0



Koristeći modifikatore moguće je pristupiti manjim elementima neke promenljive. Za promenljivu tipa BIT nema modifikatora jer je to najmanji mogući tip.
Za promenljivu tipa bajt može da se koristi modifikator .BITX ili samo .X gde X predstavlja bit (od 0 do 7) kome želimo da pristupimo, a to smo već videli u prethodnim primerima.

Code:

znak        var bit
brojac      var byte


    brojac.bit3 = 1
    brojac.5 = 0
    znak = brojac.7


Za promenljivu tipa WORD može da se koristi modifikator .X da bi se pristupilo odredjenom bitu s tim da je opseg za X od 0 do 15. Moguće je pristupiti i odredjenom bajtu pomoću modifikatora .BYTEX gde X može da bude 0 ili 1; 0 za bajt niže vrednosti i 1 za bajt više vrednosti. Šta je sad pa to, bajt niže ili više vrednosti? Obzirom da je bajt osnovna memorijska jedinica i može, kao što znamo, da ima vrednost od 0 do 255, za WORD tip se koriste 2 bajta i potrebno je nekako smestiti broj preko 255 u ta dva bajta. Da bismo to razumeli, najbolje je da posmatramo WORD tip kao da imamo brojni sistem sa osnovom 256 pa takav broj može da se predstavi formulom BYTE1 * 2561 + BYTE0 * 2560. Npr. broj 520 se nalazi u 2 bajta pri čemu je vrednost bajta veće vrednosti 2, a bajta manje vrednosti je 8. Proverićemo to zamenom u formuli:

BYTE1 * 2561 + BYTE0 * 2560 = 2 * 2561 + 8 * 2560 = 512 + 8 = 520

Primeri:
Code:

znak        var bit
brojac_l    var byte
brojac_h    var byte
brojac      var word

    znak = brojac.15
    brojac_h = brojac.byte1
    brojac_l = 0
    brojac.byte0 = brojac_l


U prethodnoj verziji PBP kompajlera za WORD tip umesto BYTE0 mogao je da se koristi modifikator LOWBYTE, a umesto BYTE1 modifikator HIGHBYTE. Od verzije 3 ovi modifikatori se ne pominju u uputstvu, iako mogu da se koriste i još uvek spadaju u rezervisane reči, ali da biste smanjili mogućnost zabune, ne preporučujem njihovu upotrebu.


Na isti način za promenljivu tipa LONG mogu da se koriste modifikatori za bit i bajt, s tim da za bit vrednost može da bude od 0 do 31, a za bajt od 0 do 3. Pošto se LONG tip pravi od 4 bajta, imamo i novi modifikator za ovaj tip, .WORDX gde X može da bude 0 ili 1, opet 0 za WORD niže vrednosti i 1 za WORD više vrednosti.

Da bi sve bilo jasnije, pogledajte sledeću tabelu koju možete da nadjete u PBP uputstvu:


---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:


[Ovu poruku je menjao rsinisa dana 26.02.2013. u 12:03 GMT+1]
[ rsinisa @ 04.03.2013. 09:21 ] @
Upotreba nizova promenljivih
-----------------------------------
Niz možemo da posmatramo kao listu vrednosti; navodjenjem imena niza pristupamo listi, a navodjenjem indeksa pristupamo odredjenoj vrednosti u toj listi, tj. odredjenom elementu niza. Indeks se navodi u uglastoj zagradi, a može da bude broj, neka druga promenljiva ili neki izraz.

Code:

redbr     var byte
x         var byte
vrednost  var byte
moj_niz   var byte[8]

    moj_niz[0] = 5
    vrednost = moj_niz[redbr]
    moj_niz[x / 2] = 24


Da ponovimo još jednom da indeks počinje od 0 i ide do broja elemenata umanjeno za 1. U ovom primeru indeks ide od 0 do 7 za niz 'moj_niz'. Veoma je važno da ne navedete indeks koji ne postoji jer PBP neće da generiše grešku u tom slučaju i uzeće neku vrednost koja se nalazi van niza pa ćete imati pogrešan rezultat.

Vrednosti elementima niza mogu biti dodeljene individualno jedan po jedan, kroz neku petlju, ili upotrebom naredbe ARRAYWRITE:

Code:

arraywrite moj_niz, [25, 187, 0, 254, 11, 200, 38, 99]


Iako PBP ne može da radi sa višedimenzionim nizovima, možemo da ih emuliramo koristeći više promenljivih.

Recimo da nam je potreban niz od 4 reda i dve kolone 'moj_niz[4, 2]' koji ćemo da definišemo kao jednodimenzioni od 8 elemenata:

Code:

x         var byte
y         var byte
moj_niz   var byte[8]

    x = 1
    y = 2
    moj_niz[(x * 4) + y] = 100


Modifikatori koji se koriste za skalarne promenljive ne mogu da se koriste za nizove pa, da bi pristupili nekom manjem elementu jedne promenljive iz niza, moramo da upotrebimo neku privremenu promenljivu. Recimo da hoćemo viši bajt jednog elementa niza da postavimo na 0:

Code:

temp_vord  var word
niz_vord   var word[8]

    temp_vord = niz_vord[3]
    temp_vord.byte1 = 0
    niz_vord[3] = temp_vord


---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:

[Ovu poruku je menjao rsinisa dana 04.03.2013. u 22:38 GMT+1]
[ rsinisa @ 05.03.2013. 09:58 ] @
Konstante
=======
Pored promenljivih, PBP nam omogućava da možemo da definišemo i konstante, tj. fiksne vrednosti. Ta mogućnost nam je korisna ako na više mesta u programu koristimo istu vrednost koja je podložna promenama ili nam služi za neka podešavanja. Konstanta ne zauzima nikakvu memoriju MCU-a, njena vrednost se jednostavno zameni u postupku kompajliranja.

Za definisanje naziva konstanti važe ista pravila kao i za nazive labela; može da sadrži cifre, slova i donju crtu, ali ne može da počne cifrom. Dužina je praktično neograničena, ali PBP uzima u obzir samo 31 karakter ako je naziv duži. Sasvim je svejedno da li je konstanta pisana velikim ili malim slovima, to znači da se konstante 'VREDNOST' i 'VredNOSt' tretiraju kao da su iste.

Konstante su interno definisane kao 16-tobitni neoznačeni broj, mada možete da navedete i negativan broj, ali će on biti pretvoren u pozitivan drugi komplement. Npr. broj -500 će biti tretiran kao 65036.
Za definisanje se koristi reč CON.

Primer upotrebe:

Code:

zadrska   con 300

    pause zadrska



Aliasi
====
Alias je u stvari drugo, alternativno ime za promenljive, delove promenljivih i registre. Za definisanje naziva aliasa važe potpuno ista pravila kao i za nazive konstanti.

Primer:
Code:

zadrska    var word
podaci     var byte[4]

pauza      var zadrska
pauza_low  var zadrska.byte0
podatak2   var podaci[1]

LED1       var portb.0
data_pin   var porta.2
clk_pin    var porta.3


Sa aliasima program može da bude razumljivi jer je naredba 'high LED1' mnogo jasnija nego 'high portb.0', a izmene lakše ako, npr. odlučite da u nekom trenutku data_pin premestite sa jednog pina na drugi.

U starijim verzijama se za definisanje aliasa koristila reč SYMBOL koja i dalje može da se upotrebljava, ali se to ne preporučuje.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:
[ rsinisa @ 11.03.2013. 05:04 ] @
Primer 11:
=======
U ovom primeru koristi se postavka 1.

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

Code:

pauza       con 500       ;definišemo konstantu
d1          var portb.0   ;definišemo alias za led D1
 
    osccon=%01101000      ;interni oscilator na 4MHz
    anselb=0              ;ceo port B digitalni
    
    trisb.0=0             ;postavi pin 0 porta B kao izlazni

pocetak:
    d1=1                  ;uključi LED povezanu na pin 0 porta B
    pause pauza           ;napravi pauzu od 500 milisekundi
    d1=0                  ;isključi LED povezanu na pin 0 porta B
    pause pauza           ;napravi pauzu od 500 milisekundi
    goto pocetak          ;idi na labelu pocetak

end


Vidimo da je program potpuno iste dužine kao i onaj iz primera 3, tj. 63 vorda, 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.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:
[ rsinisa @ 14.03.2013. 09:38 ] @
Primer 12:
=======
U ovom primeru koristi se postavka 1.

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.

Code:

pauza       con 500       ;definišemo konstantu za pauzu
d1          var portb.0   ;definišemo alias za led D1
d2          var portb.1   ;definišemo alias za led D2
d3          var portb.2   ;definišemo alias za led D3
d4          var portb.3   ;definišemo alias za led D4
d5          var portb.4   ;definišemo alias za led D5
d6          var portb.5   ;definišemo alias za led D6
d7          var portb.6   ;definišemo alias za led D7
d8          var portb.7   ;definišemo alias za led D8
 
    osccon=%01101000      ;interni oscilator na 4MHz
    anselb=0              ;ceo port B digitalni
    
    portb=0               ;isključimo sve LED
    trisb=0               ;postavi ceo port B kao izlazni

    do                    ;početak petlje
      d1=1                ;uključi LED povezanu na pin 0 porta B
      pause pauza         ;napravi pauzu
      d1=0                ;isključi LED povezanu na pin 0 porta B
      d2=1                ;uključi LED povezanu na pin 1 porta B
      pause pauza         ;napravi pauzu
      d2=0                ;isključi LED povezanu na pin 1 porta B
      d3=1                ;uključi LED povezanu na pin 2 porta B
      pause pauza         ;napravi pauzu
      d3=0                ;isključi LED povezanu na pin 2 porta B
      d4=1                ;uključi LED povezanu na pin 3 porta B
      pause pauza         ;napravi pauzu
      d4=0                ;isključi LED povezanu na pin 3 porta B
      d5=1                ;uključi LED povezanu na pin 4 porta B
      pause pauza         ;napravi pauzu
      d5=0                ;isključi LED povezanu na pin 4 porta B
      d6=1                ;uključi LED povezanu na pin 5 porta B
      pause pauza         ;napravi pauzu
      d6=0                ;isključi LED povezanu na pin 5 porta B
      d7=1                ;uključi LED povezanu na pin 6 porta B
      pause pauza         ;napravi pauzu
      d7=0                ;isključi LED povezanu na pin 6 porta B
      d8=1                ;uključi LED povezanu na pin 7 porta B
      pause pauza         ;napravi pauzu
      d8=0                ;isključi LED povezanu na pin 7 porta B
    loop                  ;kraj petlje

end



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.

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

DO {UNTIL uslov} {WHILE uslov} 
naredba...
LOOP {UNTIL uslov} {WHILE uslov}


Ova naredba se koristi za ponavljanje bloka naredbi koje se nalaze izmedju DO i LOOP. Ono što je napisano u vitičastim zagradama je opciono, tj. upotrebljava se po potrebi. Mi smo ovde upotrebili samo osnovnu varijantu bez ikakvih uslova i u tom slučaju se ceo blok naredbi izvršava u tzv. petlji i to beskonačno, sve do isključenja napajanja.

Ako je potrebno da se izvršavanje prekine ako je ispunjen neki uslov, koriste se opcije "UNTIL uslov" i "WHILE uslov" pri čemu se kod UNTIL izvršavanje prekida kada uslov postane tačan, a kod WHILE kada uslov postane netačan.
Ako se ispitivanje koristi u liniji gde se nalazi "DO", ispitivanje se vrši pre ulaska u petlju i ako uslov za ulazak u petlju nije zadovoljen, program se preusmerava na prvu naredbu posle LOOP.
Ako se ispitivanje koristi u liniji gde se nalazi "LOOP", ispitivanje se vrši nakon prolaska kroz petlju što znači da će se blok naredbi izvršiti bar jednom, čak i ako uslov nije ispunjen.

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

Takodje vidimo i da smo sve naredbe izmedju DO i LOOP 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:
Code:

    i = 1  
    DO  
      SEROUT 0,N2400,["No:",#i,13,10] 
      i = i + 1  
    LOOP UNTIL i > 10  
 
 
    i = 1  
    DO WHILE i <= 10  
      SEROUT 0,N2400,["No:",#i,13,10] 
      i = i + 1  
    LOOP  
 
 
    i = 1  
    DO  
      SEROUT 0,N2400,["No:",#i,13,10] 
      i = i + 1  
      IF PORTB.0 = 0 THEN EXIT 
    LOOP WHILE i <= 10  
 


U ranijim verzijama PBP-a koristile su se dve naredbe za formiranje ovakvih petlji, REPEAT ... UNTIL i WHILE ... WEND koje su podržane i u ovoj verziji radi kompatibilnosti, ali je preporuka da se upotrebljava isključivo DO ... LOOP.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:

[Ovu poruku je menjao rsinisa dana 14.03.2013. u 14:49 GMT+1]
[ rsinisa @ 26.03.2013. 11:18 ] @
Primer 13:
=======
U ovom primeru koristi se postavka 1.


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

Code:

pauza       con 500       ;definišemo konstantu za pauzu
d1          var portb.0   ;definišemo alias za led D1
d2          var portb.1   ;definišemo alias za led D2
d3          var portb.2   ;definišemo alias za led D3
d4          var portb.3   ;definišemo alias za led D4
d5          var portb.4   ;definišemo alias za led D5
d6          var portb.5   ;definišemo alias za led D6
d7          var portb.6   ;definišemo alias za led D7
d8          var portb.7   ;definišemo alias za led D8

i           var byte      ;promenljiva za brojač

    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000      ;interni oscilator na 4MHz
    anselb=0              ;ceo port B digitalni
    
    portb=0               ;isključimo sve LED
    trisb=0               ;postavi ceo port B kao izlazni
    i=0                   ;početna vrednost za promenljivu "i"


    do                    ;početak petlje
      d1=1                ;uključi LED povezanu na pin 0 porta B
      pause pauza         ;napravi pauzu
      d1=0                ;isključi LED povezanu na pin 0 porta B
      d2=1                ;uključi LED povezanu na pin 1 porta B
      pause pauza         ;napravi pauzu
      d2=0                ;isključi LED povezanu na pin 1 porta B
      d3=1                ;uključi LED povezanu na pin 2 porta B
      pause pauza         ;napravi pauzu
      d3=0                ;isključi LED povezanu na pin 2 porta B
      d4=1                ;uključi LED povezanu na pin 3 porta B
      pause pauza         ;napravi pauzu
      d4=0                ;isključi LED povezanu na pin 3 porta B
      d5=1                ;uključi LED povezanu na pin 4 porta B
      pause pauza         ;napravi pauzu
      d5=0                ;isključi LED povezanu na pin 4 porta B
      d6=1                ;uključi LED povezanu na pin 5 porta B
      pause pauza         ;napravi pauzu
      d6=0                ;isključi LED povezanu na pin 5 porta B
      d7=1                ;uključi LED povezanu na pin 6 porta B
      pause pauza         ;napravi pauzu
      d7=0                ;isključi LED povezanu na pin 6 porta B
      d8=1                ;uključi LED povezanu na pin 7 porta B
      pause pauza         ;napravi pauzu
      d8=0                ;isključi LED povezanu na pin 7 porta B

      i=i+1               ;uvećaj brojač za 1
    loop until i=4        ;izvršavaj petlju dok "i" ne bude 4

end


Posle definisanja promenljive "i" tipa bajt, koju ćemo da koristimo kao brojač prolazaka kroz petlju, imamo novu naredbu INCLUDE posle koje sledi naziv fajla. Ta naredba jednostavno na tom mestu ubaci sadržaj navedenog fajla, kao da smo mi ukucali taj tekst. Sintaksa za nju glasi:

INCLUDE "naziv_fajla"

U fajl pod nazivom "1827_cfg1.pbp" smo stavili konfiguraciju koju smo koristili do sada i koju do sada nismo navodili u primerima već smo morali na početku programa da je ukucamo prepisujući je iz poruke u kojoj se nalazi konfiguracija. Sada tu konfiguraciju ne morate više da kucate u programu, sada je izdvojena u poseban fajl koji je priključen uz ovu poruku i da biste mogli da ga koristite, stavite ga u isti direktorijum u kome su vam primeri.

Naredba "i=0" dodeljuje početnu vrednost promenljivoj "i". Puna sintaksa za tu naredbu glasi:

{LET} promenljiva = vrednost

pri čemu je naredba LET opciona, tj. ne mora da se koristi. Vrednost može da bude broj, druga promenljiva ili izraz. Npr:

Code:
LET p1 = 26
LET p1 = p2
p1 = p1 * 2
p1 = p3 * 4
p1 = p2 * p3 + 10


Pre naredbe LOOP imamo izraz "i=i+1" koji uvećava staro stanje promenljive "i" za 1 i to novo stanje opet dodeljuje promenljivoj "i"; time postižemo brojanje prolazaka kroz DO ... LOOP petlju.

Posle naredbe LOOP dodali smo i uslov za izlazak koji u ovom slučaju prekida izvršavanje petlje kada vrednost za i postane 4, tj. nakon 4 ciklusa program se zaustavlja.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:

[Ovu poruku je menjao rsinisa dana 26.03.2013. u 12:32 GMT+1]
[ rsinisa @ 05.04.2013. 09:57 ] @
Primer 14:
=======
U ovom primeru koristi se postavka 1.

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.

Code:

pauza       con 500       ;definišemo konstantu za pauzu

    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000      ;interni oscilator na 4MHz
    anselb=0              ;ceo port B digitalni
    
    latb=1                ;uključimo LED D1
    trisb=0               ;postavi ceo port B kao izlazni


    do                    ;početak petlje
      pause pauza         ;napravi pauzu
      latb=latb * 2       ;dupliraj vrednost za LATB
      if latb=0 then      ;ako je vrednost B leča = 0
        latb=1            ;postavi ga na 1
      endif               ;kraj IF ispitivanja
    loop                  ;kraj petlje

end




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 "DO ... LOOP" 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.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:


[Ovu poruku je menjao rsinisa dana 06.04.2013. u 14:24 GMT+1]
[ rsinisa @ 08.04.2013. 11:12 ] @
IF ... THEN naredba
=============

IF uslov {AND/OR uslov...} THEN labela

IF uslov {AND/OR uslov...} THEN naredba...

IF uslov {AND/OR uslov...} THEN
naredba...
{ELSEIF uslov {AND/OR uslov...} THEN
naredba...}
{ELSE
naredba...}
ENDIF


Ova naredba vrši poredjenje jednog ili više uslova, a uslov može da bude promenljiva, konstanta ili izraz. Ona uporedjuje da li je uslov tačan (istinit) ili ne; ako je tačan, izvršava se naredba (ili blok naredbi) iza THEN. Ako je vrednost uslova 0, smatra se netačnim, a sve ostale vrednosti se smatraju tačnim. Uz pomoć operatora AND i OR moguće je ispitivati više uslova i potrebno je koristiti zagrade kako bi se odredio redosled testiranja.

IF ... THEN naredba može da se koristi u jednoj liniji ili kao višelinijski blok. Ako se koristi u jednoj liniji tada iza THEN mora da se nadje jedna naredba ili više razdvojenih dvotačkom, a ako je ta naredba GOTO, onda je dovoljno umesto GOTO navesti samo labelu na koju treba izvršiti skok.

Primeri:
Code:

    if porta.5=0 then portb.0=1  ; ako je RA5=0 postavi RB0 na 1
    if portb.7=1 then podesi     ; ako je RB7=1 idi na labelu podesi


U višelinijskom obliku iza THEN se navodi blok naredbi i u tom slučaju iza THEN ne sme da stoji ni jedna naredba već se one pišu ispod nje. Ceo blok se završava sa ENDIF naredbom.

Primer:
Code:

    if porta.5=1 then
      a=x * 2 + 1
      d1=1
      pause pauza
    endif


Moguće je izvršiti i naredbe u slučaju da uslov nije ispunjen pomoću naredbi ELSE i ELSEIF. Prva omogućava izvršavanje jedne ili više naredbi u slučaju da uslov nije ispunjen, a druga omogućava novo ispitivanje, kao da samo napisali novu IF naredbu, takodje ako uslov nije ispunjen.

Primeri:
Code:

    if x=1 then    ; ako je x=1
      portb.0=0    ; postavi RB0 na 0
    else           ; u protivnom
      portb.0=1    ; postavi RB0 na 1
    endif          ; kraj IF bloka


    if x=20 then   ; ako je x=20   
      d1=1         ; postavi d1 na 1
    elseif x=40    ; u protivnom da li je x=40
      d2=1         ; ako jeste, postavi d2 na 1
    else           ; ako nije
      d1=0         ; onda postavi d1 na 0
    endif          ; kraj if bloka


---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:
[ rsinisa @ 09.04.2013. 07:05 ] @
Primer 15:
=======
U ovom primeru koristi se postavka 1.

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?

Code:

pauza       con 500       ;definišemo konstantu za pauzu

    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000      ;interni oscilator na 4MHz
    anselb=0              ;ceo port B digitalni
    
    latb=1                ;uključimo LED D1
    trisb=0               ;postavi ceo port B kao izlazni


    do                    ;početak petlje
      pause pauza         ;napravi pauzu
      latb=latb + latb    ;dupliraj vrednost za LATB
      if latb=0 then      ;ako je vrednost B leča = 0
        latb=1            ;postavi ga na 1
      endif               ;kraj IF ispitivanja
    loop                  ;kraj petlje

end


Ovaj program zauzima samo 73 vorda, čak 29 manje od prethodnog primera. Razlog za to je što ovaj PIC, kao i ostali iz ove serije, od aritmetičkih operacija u jezgru nema implementirano ništa sem sabiranja i oduzimanja pa je množenje realizovano kao potprogram koji se sastoji iz dvadesetak asemblerskih instrukcija.

Ako imate mali broj množenja, a bitno Vam je da utrošak programske memorije bude što manji, vidite da li možete da ga zamenite nekim sabiranjem. Pošto se ova operacija realizuje kao potprogram, kod svakog sledećeg množenja potprogramu se prenose samo argumenti tako da se kod velikog broja množenja vrlo verovatno ne isplati menjati ih sabiranjem. U svakom slučaju, probajte na nekoliko načina.

A ako Vam utrošak memorije ne igra ulogu, jednostavno koristite množenje ako Vam je tako lakše i brže.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:


[Ovu poruku je menjao rsinisa dana 09.04.2013. u 09:51 GMT+1]
[ rsinisa @ 15.04.2013. 09:57 ] @
Primer 16:
=======
U ovom primeru koristi se postavka 1.

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

Code:

pauza       con 500       ;definišemo konstantu za pauzu

    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000      ;interni oscilator na 4MHz
    anselb=0              ;ceo port B digitalni
    
    latb=128              ;uključimo LED D8
    trisb=0               ;postavi ceo port B kao izlazni


    do                    ;početak petlje
      pause pauza         ;napravi pauzu
      latb=latb / 2       ;prepolovi vrednost za LATB
      if latb=0 then      ;ako je vrednost B leča = 0
        latb=128          ;postavi ga na 128
      endif               ;kraj IF ispitivanja
    loop                  ;kraj petlje

end


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.

Vidimo da ovaj primer troši manje programske memorije od primera 14 što znači da je deljenje realizovano kao kraći potprogram od množenja.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:

[Ovu poruku je menjao rsinisa dana 15.04.2013. u 20:00 GMT+1]
[ rsinisa @ 25.04.2013. 07:30 ] @
Primer 17:
=======
U ovom primeru koristi se postavka 1.

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.

Code:

pauza       con 500       ;definišemo konstantu za pauzu

    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000      ;interni oscilator na 4MHz
    anselb=0              ;ceo port B digitalni
    
    latb=128              ;uključimo LED D8
    trisb=0               ;postavi ceo port B kao izlazni


    do                    ;početak petlje
      pause pauza         ;napravi pauzu
      latb=latb >> 1      ;pomeri bitove udesno za jedno mesto
      if latb=0 then      ;ako je vrednost B leča = 0
        latb=128          ;postavi ga na 128
      endif               ;kraj IF ispitivanja
    loop                  ;kraj petlje

end


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.

Spisak svih operatora možete da vidite u PBP uputstvu u tabelama na stranama 68 i 69.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:
[ rsinisa @ 05.05.2013. 22:19 ] @
Primer 18:
=======
U ovom primeru koristi se postavka 1.

Prethodni primer može da se napiše tako da potroši još 6 vorda manje 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.

Code:

pauza       con 500       ;definišemo konstantu za pauzu

    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000      ;interni oscilator na 4MHz
    anselb=0              ;ceo port B digitalni
    
    latb=128              ;uključimo LED D8
    trisb=0               ;postavi ceo port B kao izlazni


    do                    ;početak petlje
      pause pauza         ;napravi pauzu
asm
      bcf STATUS, C       ;resetuj CARRY bit
      rrf LATB, 1         ;rotiraj udesno LATB registar
endasm
      if latb=0 then      ;ako je vrednost B leča = 0
        latb=128          ;postavi ga na 128
      endif               ;kraj IF ispitivanja
    loop                  ;kraj petlje

end


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 PBP-u (kao i svi ostali SFR registri i njihovi bitovi) i njihove nazive 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:



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:



---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi.

[ rsinisa @ 16.05.2013. 10:44 ] @
Naredba LOOKUP
==========
Ova naredba će nam trebati za sledeće primere, a sintaksa glasi:

LOOKUP index, [konstanta {,konstanta ...}], promenljiva

Ova naredba se koristi da uzme vrednost iz liste (ili tabele, drugačije rečeno) 8-bitnih konstanti. Ako je vrednost za indeks jednaka nuli, u promenljivu se upisuje prva konstanta iz liste, ako je vrednost za indeks 1, u promenljivu se upisuje druga konstanta iz liste i tako dalje. Ako je vrednost za indeks jednaka broju elemenata u listi ili veća od njega, promenljiva neće da promeni svoju vrednost. Lista konstanti može da bude kombinacija brojeva i stringova.

Da ukratko objasnimo šta je string. Najkraće rečeno to je niz znakova, a u znakove se ubrajaju slova, brojevi, znakovi interpukcije, specijalni simboli i sve ono što može da se prikaže na ekranu ili odštampa kao neki tekst. Stringovi se u PBP-u stavljaju izmedju znakova navoda tako da je "123" string, a 123 je broj. Još neki primeri stringova: "asdfgh", "0123ABcde", "PBP=PicBasic PRO". Važno je napomenuti da svaki element stringa ima neku brojčanu vrednost, a ona je jednaka vrednosti njegovog ASCII koda.

Za naredbu LOOKUP u listi mogu da se koriste nizovi sa konstanim indeksom, ali ne i sa promenljivim indeksom. Jedna lista može da sadrži maksimalno 255 konstanti (za PIC18 seriju do 1024 konstanti).

Naredba LOOKUP2
==========
Sintaksa je ista kao i za naredbu LOOKUP:

LOOKUP2 index, [konstanta {,konstanta ...}], promenljiva

Njena funkcija je ista kao za naredbu LOOKUP uz par razlika, a to su: lista može da sadrži kombinaciju 8-mo i 16-bitnih brojevnih konstanti, stringova i promenljivih. Izrazi ne mogu da se koriste u listi, ali mogu da se koriste kao indeks. Maksimalan broj elemenata je 85 (1024 za PIC18 seriju).

Ova naredba generiše oko 3 puta veći kod u odnosu na LOOKUP naredbu pa je koristite samo ako vam nisu dovoljne 8-bitne vrednosti u listi.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:

[Ovu poruku je menjao rsinisa dana 16.05.2013. u 12:22 GMT+1]
[ rsinisa @ 20.05.2013. 14:14 ] @
Primer 19:
=======
U ovom primeru koristi se postavka 1.

U prethodnim primerima pravili smo efekat trčećeg svetla koristeći matematičke operacije. Medjutim, 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 PBP-u je implementirana naredba LOOKUP koju smo upotrebili u ovom primeru.

Code:

brojac      var byte      ;definišemo promenljivu tipa bajt
pauza       con 500       ;definišemo konstantu za pauzu

    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000      ;interni oscilator na 4MHz
    anselb=0              ;ceo port B digitalni
    latb=0                ;isključimo sve LED
    trisb=0               ;postavi ceo port B kao izlazni

pocetak:
    brojac=0              ;resetuj vrednost brojača
tabela:
    lookup brojac, [128, 192, 224, 240, 248, 252,_
    254, 255, 127, 63, 31, 15, 7, 3, 1], latb  ;uzmi podatak iz tabele
    pause pauza           ;napravi pauzu
    brojac = brojac + 1   ;uvećaj brojač
    if brojac > 14 then pocetak
                          ;ako je brojač veći od 14, idi resetuj ga
    goto tabela           ;ako nije, idi na labelu 'tabela'
end


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 predje 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 PBP-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.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:
[ rsinisa @ 24.05.2013. 11:56 ] @
Primer 20:
=======
U ovom primeru koristi se postavka 1.

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.

Code:

brojac      var byte      ;definišemo promenljivu tipa bajt
pauza       con 500       ;definišemo konstantu za pauzu

    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000      ;interni oscilator na 4MHz
    anselb=0              ;ceo port B digitalni
    latb=0                ;isključimo sve LED
    trisb=0               ;postavi ceo port B kao izlazni

pocetak:
    for brojac=0 to 14    ;postavi uslove za brojačku petlju
      lookup brojac, [128, 192, 224, 240, 248, 252,_
      254, 255, 127, 63, 31, 15, 7, 3, 1], latb  ;uzmi podatak iz tabele
      pause pauza         ;napravi pauzu
    next brojac           ;uvećaj brojač i vrati se ako treba
    goto pocetak          ;ako ne, idi na labelu 'pocetak'
end


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.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:

[Ovu poruku je menjao rsinisa dana 24.05.2013. u 13:28 GMT+1]
[ rsinisa @ 24.05.2013. 13:43 ] @
Naredba EXIT
=========

EXIT

Ova naredba se koristi za prevremeni izlazak iz petlji pre ispunjenja uslova za regularan izlazak, a to su:

DO ... LOOP
FOR ... NEXT
IF ... THEN
WHILE ... WEND
REPEAT ... UNTIL

Kada naidje na ovu naredbu, program nastavlja izvršenje prve naredbe iza one koja označava kraj bloka odn. petlje. Iako EXIT može da se koristi i za dve zadnje navedene petlje, u lekciji za DO ... LOOP rekli smo da se njihova upotreba ne preporučuje.

Primeri:

Code:

DO
  naredba
  naredba
  IF x=255 then EXIT
LOOP
naredba



FOR i=0 to 100
  naredba
  naredba
  IF PORTA.5=1 then EXIT
NEXT i
naredba


---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:
[ rsinisa @ 27.05.2013. 06:49 ] @
Primer 21:
=======
U ovom primeru koristi se postavka 1.

Dobra strana korišćenja tabele pri izradi trčećeg svetla je što se veoma lako pravi kombinacija koja ide u suprotnom smeru; potrebno je samo uzimati podatke od zadnjeg elementa ka prvom. Da bismo to postigli, idealna nam je FOR ... NEXT naredba sa umanjenjem brojača.

Code:

brojac      var byte             ;definišemo promenljivu tipa bajt
pauza       con 500              ;definišemo konstantu za pauzu

    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000             ;interni oscilator na 4MHz
    anselb=0                     ;ceo port B digitalni
    latb=0                       ;isključimo sve LED
    trisb=0                      ;postavi ceo port B kao izlazni

pocetak:
    for brojac=14 to 0 step -1   ;postavi uslove za brojačku petlju
                                 ;tako da broji unazad od 14 do 0
      lookup brojac, [128, 192, 224, 240, 248, 252,_
      254, 255, 127, 63, 31, 15, 7, 3, 1], latb  ;uzmi podatak iz tabele
      pause pauza                ;napravi pauzu
    next brojac                  ;uvećaj petlju i vrati se ako treba
    goto pocetak                 ;ako ne, idi na labelu 'pocetak'
end


Razlika u odnosu na primer 20 je što smo u FOR petlji stavili "step -1" čime se postiže umanjenje za 1 svaki put kada program naidje na NEXT naredbu i time LOOKUP uzima iz liste elemente od poslednjeg prema prvom.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:


[Ovu poruku je menjao rsinisa dana 27.05.2013. u 09:39 GMT+1]
[ rsinisa @ 03.06.2013. 10:05 ] @
Primer 22:
=======
U ovom primeru koristi se postavka 1.

Ovaj program pravi efekat trčećeg svetla sa 4 različite kombinacije, od kojih se svaka ponavlja po 4 puta. Svaka kombinacija ima 8 stanja, za razliku od prethodna 2 primera koji su imali po 15 stanja.

Code:

i           var byte      ;brojač za for petlju
brojac      var byte      ;brojač prolazaka za jednu kombinaciju
pauza       con 300       ;konstanta za pauzu


    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000               ;interni oscilator na 4MHz
    anselb=0                       ;ceo port B digitalni
    latb=0                         ;isključimo sve LED
    trisb=0                        ;postavi ceo port B kao izlazni

pocetak:
    brojac=0                       ;resetuj brojač
    do                             ;početak prve kombinacije
      for i=0 to 7                 ;postavi uslove za brojačku petlju
        lookup brojac, [1,2,4,8,16,32,64,128], latb  ;uzmi podatak
        pause pauza                ;napravi pauzu
      next i                       ;uvećaj petlju i vrati se ako treba
      brojac=brojac + 1            ;uvećaj brojač ponavljanja kombinacije
    until brojac = 4               ;radi kombinaciju 4 puta

    brojac=0                       ;resetuj brojač
    do                             ;početak druge kombinacije
      for i=0 to 7                 ;postavi uslove za brojačku petlju
        lookup brojac, [1,3,7,15,31,63,127,255], latb  ;uzmi podatak
        pause pauza                ;napravi pauzu
      next i                       ;uvećaj petlju i vrati se ako treba
      brojac=brojac + 1            ;uvećaj brojač ponavljanja kombinacije
    until brojac = 4               ;radi kombinaciju 4 puta

    brojac=0                       ;resetuj brojač
    do                             ;početak treće kombinacije
      for i=0 to 7                 ;postavi uslove za brojačku petlju
        lookup brojac, [127,191,223,239,247,251,253,254], latb  ;uzmi podatak
        pause pauza                ;napravi pauzu
      next i                       ;uvećaj petlju i vrati se ako treba
      brojac=brojac + 1            ;uvećaj brojač ponavljanja kombinacije
    until brojac = 4               ;radi kombinaciju 4 puta

    brojac=0                       ;resetuj brojač
    do                             ;početak četvrte kombinacije
      for i=0 to 7                 ;postavi uslove za brojačku petlju
        lookup brojac, [192,96,48,24,12,6,3,129], latb  ;uzmi podatak
        pause pauza                ;napravi pauzu
      next i                       ;uvećaj petlju i vrati se ako treba
      brojac=brojac + 1            ;uvećaj brojač ponavljanja kombinacije
    until brojac = 4               ;radi kombinaciju 4 puta

    goto pocetak

end


Vidimo da je program praktično isti kao primer 20 s tim da smo za svaku kombinaciju napravili posebnu FOR petlju i da smo za 4 ponavljanja svake kombinacije upotrebili DO ... LOOP petlju.

Program zauzima 229 vorda, a u sledećem primeru videćemo kako možemo da napravimo isti efekat uz uštedu programske memorije.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:
[ rsinisa @ 06.06.2013. 07:56 ] @
Primer 23:
=======
U ovom primeru koristi se postavka 1.

Ako pogledamo prethodni primer, vidimo da se 4 puta ponavlja isti blok koji se razlikuju jedino u podacima za LOOKUP naredbu pa je logično pretpostaviti da program može da se preradi tako da zauzima manje programske memorije. Jedan od načina je ovaj:

Code:

i           var byte      ;brojač za FOR petlju
brojac      var byte      ;brojač prolazaka za jednu kombinaciju
pomeraj     var byte      ;pomeraj za LOOP
pauza       con 300       ;konstanta za pauzu


    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000                   ;interni oscilator na 4MHz
    anselb=0                           ;ceo port B digitalni
    latb=0                             ;isključimo sve LED
    trisb=0                            ;postavi ceo port B kao izlazni

    do                                 ;početak beskonačne petlje
      pomeraj=0                        ;resetujemo "pomeraj"
      do                               ;petlja za izbor početnog elementa
        brojac=0                       ;resetujemo "brojac"
        do                             ;petlja za 4 ponavljanja
          for i=pomeraj to pomeraj + 7 ;postavi uslove za brojačku petlju
            lookup i, [1,2,4,8,16,32,64,128,_
            1,3,7,15,31,63,127,255,_
            127,191,223,239,247,251,253,254,_
            192,96,48,24,12,6,3,129], latb  ;uzmi podatak
            pause pauza                ;napravi pauzu
          next i                       ;uvećaj "i" i vrati se ako treba
          brojac=brojac + 1            ;ako ne, uvećaj "brojac"
        loop until brojac = 4          ;vrati se ako "brojac" nije 4
        pomeraj=pomeraj + 8            ;pomeri se na sledećih 8 u LOOP petlji
      loop until pomeraj=32            ;vrati se ako "pomeraj" nije 32
    loop

end


Program je veoma sličan jednom bloku iz prethodnog primera, s tim da smo u jednu LOOKUP listu ubacili sve kombinacije što znači da je potrebno da na neki način moramo da prozovemo jednu po jednu, tj. blok od 8 brojeva iz liste za svaku kombinaciju ponaosob. Da bi to uradili, uveli smo promenljivu "pomeraj" koja nam služi kao pokazivač, tj. da odredimo redni broj podatka od koga čitamo LOOKUP listu.

Nakon poznatog inicijalnog bloka nailazimo na prvu DO naredbu koja je u stvari tzv. "mrtva" petlja, tj. vidimo da odgovorajući LOOP nema nikakav uslov što znači da se ta prva petlja izvršava beskonačno, time i naš program.
Nakon toga sledi inicijalizacija promenljive "pomeraj", tj. postavljamo je na 0 jer ćemo LOOKUP listu da čitamo od prvog podatka.

Sledeća DO naredba izvršava jednom sve 4 kombinacije, a završava se kada "pomeraj" bude 32, tj. kada pokazivač na listu predje broj stavki u LOOKUP listi. Nakon nje sledi inicijalizacija promenljive "brojac" koja broji koliko puta je odradjena jedna kombinacija.

Zatim ide još jedna DO naredba koja se završava sa proverom da li je "brojac" došao do 4, tj. ta petlja radi jednu kombinaciju zadati broj puta, u ovom primeru je to 4.

Nakon toga ide poznata FOR petlja kod koje ovoga puta nisu zadate fiksne vrednosti za početak i kraj već petlja počinje od vrednosti koju ima promenljiva "pomeraj", a završava sa "pomeraj" uvećanom za 7, što čini 8 vrednosti koliko nam i treba za jednu kombinaciju. Ostatak programa nam je već dobro poznat.

U ovom primeru imamo 3 DO ... LOOP petlje i jednu FOR petlju koje se nalaze jedna unutar druge koje na ovaj način čine tzv. ugnježdene petlje i baš zbog takve situacije dobro je uvlačiti liniju svake petlje za nekoliko karaktera (2 u našem slučaju) kako bi lakše pratili šta se dešava u kojoj petlji i kako bi lakše pronašli eventualnu grešku.

Ovom optimizacijom smo uštedeli čak 70 vorda programske memorije.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:
[ rsinisa @ 13.06.2013. 09:35 ] @
Primer 24:
=======
U ovom primeru koristi se postavka 1.

Zbog specifičnosti FOR naredbe moguće je dodatno optimizovati program tako što ćemo umesto matematičkog izraza za krajnju vrednost (u našem slučaju "pomeraj + 7") da stavimo promenljivu koju smo izračunali neposredno pre FOR petlje.

Code:

i           var byte      ;brojač za FOR petlju
brojac      var byte      ;brojač prolazaka za jednu kombinaciju
pomeraj     var byte      ;pomeraj za LOOP
pomeraj2    var byte      ;vrednost za kraj FOR petlje
pauza       con 300       ;konstanta za pauzu


    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000                   ;interni oscilator na 4MHz
    anselb=0                           ;ceo port B digitalni
    latb=0                             ;isključimo sve LED
    trisb=0                            ;postavi ceo port B kao izlazni

    do                                 ;početak beskonačne petlje
      pomeraj=0                        ;resetujemo "pomeraj"
      do                               ;petlja za izbor početnog elementa
        brojac=0                       ;resetujemo "brojac"
        do                             ;petlja za 4 ponavljanja
          pomeraj2=pomeraj + 7         ;izračunaj vrednost za kraj FOR petlje
          for i=pomeraj to pomeraj2    ;postavi uslove za brojačku petlju
            lookup i, [1,2,4,8,16,32,64,128,_
            1,3,7,15,31,63,127,255,_
            127,191,223,239,247,251,253,254,_
            192,96,48,24,12,6,3,129], latb  ;uzmi podatak
            pause pauza                ;napravi pauzu
          next i                       ;uvećaj "i" i vrati se ako treba
          brojac=brojac + 1            ;ako ne, uvećaj "brojac"
        loop until brojac = 4          ;vrati se ako "brojac" nije 4
        pomeraj=pomeraj + 8            ;pomeri se na sledećih 8 u LOOP petlji
      loop until pomeraj=32            ;vrati se ako "pomeraj" nije 32
    loop

end


Na ovaj način uštedeli smo još 26 vorda što ukupno čini čak 96 u odnosu na primer 22 što uopšte nije malo za ovakav tip mikrokontrolera.

Dosadašnji primeri nam nisu omogućavali nikakvu kontrolu dogadjaja tj. mogućnost našeg uticaja na rad programa, a bez toga se skoro ni jedan program ne može zamisliti pa ćemo od sledećeg primera da se pozabavimo kontrolom dešavanja u toku izvršavanja programa.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:
[ rsinisa @ 17.06.2013. 13:55 ] @
Primer 25:
=======
U ovom primeru koristi se postavka 1.

Malo je programa kojima u toku rada nije potreban neki spoljni uticaj, bilo od strane korisnika ili od nekog senzora, davača i sl. U ovom primeru videćemo kako da kontrolišemo LED D1 pritiskom na taster TA1.

Code:

led1          var portb.0          ;definišemo alias za led D1
led2          var portb.1          ;definišemo alias za led D2
taster1       var porta.4          ;definišemo alias za taster TA1

    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000               ;interni oscilator na 4MHz
    ansela=0                       ;ceo port A digitalni
    anselb=0                       ;ceo port B digitalni
    latb=0                         ;isključimo sve LED
    trisa=255                      ;postavi ceo port A kao ulazni
    trisb=0                        ;postavi ceo port B kao izlazni

    do                             ;početak petlje
      if taster1=1 then led1=0     ;ako taster nije pritisnit, isključi D1
      if taster1=0 then led1=1     ;ako je taster pritisnut, uključi D1
      led2=1                       ;uključi D2
    loop                           ;kraj petlje
      
end


Kao što vidimo iz šeme, taster TA1 povezan je na RA4 pa smo tako i definisali alias za njega. Program bi trebalo da je potpuno jasan jer nemamo ni jednu novu komandu, novo je podešavanje ANSELA i TRISA registara; ANSEL moramo da postavimo na 0 kako bi isključili sve analogne funkcije A porta i uključili digitalnu funkciju na svim pinovima. Medjutim, kada je u pitanju TRISA registar, ako pogledamo tabelu 3-8 u tehničkim podacima za ovaj PIC videćemo da je po uključenju stanje svih bitova tog registra postavljeno na 1, tj. njegovo stanje je 255, isto kao što smo mi postavili u programu. U principu to nismo morali, ali je ipak preporuka da to uradimo jer ako izostavimo inicijalno podešavanje verovatno ćemo posle nekog vremena, kada pogledamo ponovo program, da se pitamo koje su početne vrednosti registara koje nismo podesili pa ćemo morati da posegnemo za dokumentacijom.

Objasnićemo samo ulogu otpornika R24 koji je, kako se vidi iz šeme, jednim krajem povezan na +5V, a drugim na taster i RA4. Obzirom da su svi pinovi A porta postavljeni kao ulazi, pa i RA4, stanja na njima su nedefinisana jer oni u električnom smislu nisu nigde spojeni tj. "plivaju", a kada je ulaz odspojen, stanje na njemu može da bude 0 ili 1, ili da se stalno menja zbog faktora kao što su smetnje koje ulaze kroz napajanje, ili indukcije kroz vodove na štampanoj ploči. Zato je neophodno da na ulazu imamo stabilno logičko stanje koje se obezbedjuje otpornikom; kada je taj otpornik jednim krajem spojen na plus tada taj otpornik nazivamo PULL-UP (što znači "povući na gore"), a kada je spojen na masu nazivamo ga PULL-DOWN (u prevodu "povući na dole"). Uobičajeno je da se u ovakvim situacijama koristi pull-up otpornik, a i u samom PIC-u postoje takvi otpornici, fabrički ugradjeni, koji mogu da se uključe ili isključe, ima ih na svim pinovma B porta i samo na pinu 5 porta A, pa smo morali da dodamo spoljne na ostale pinove A porta.
Da bi se detektovala promena stanja, taster moramo da povežemo na suprotan polaritet - kada taster nije pritisnut stanje na pinu je 1, a kada je pritisnut stanje na pinu je 0 jer je taster spojen direktno na masu, a zbog otpornika je ograničena struja koja prolazi izmedju plusa i mase pa nema kratkog spoja. Vrednost otpornika može da bude od 1K pa do oko 100K u zavisnosti od upotrebljenih komponenti, a vrednost otpornika u samom PIC-u je oko 22K. Na našem razvojnom sistemu pull-up otpornici (R24, R25 i R26)imaju vrednost od 4,7K.

Da se na kratko vratimo programu. Prva IF naredba ispituje da li je vrednost na pinu RA4 jednako 1, i ako jeste onda isključuje LED1, a druga radi obrnuto. Kroz prethodno objašenjenje videli smo da će na RA4 da bude logičko 1 kada taster nije pritisnut, a 0 kada je taster pritisnut.
Naredba kojom uključujemo LED2 je tu radi kontrole i uporedjenja sa sledećim primerom i vidimo da je LED2 stalno uključena.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:
[ rsinisa @ 20.06.2013. 13:39 ] @
Primer 26:
=======
U ovom primeru koristi se postavka 1.

Ovaj program radi istu stvar kao i prethodni samo na malo drugačiji način.

Code:

led1          var portb.0          ;definišemo alias za led D1
led2          var portb.1          ;definišemo alias za led D2
taster1       var porta.4          ;definišemo alias za taster TA1

    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000               ;interni oscilator na 4MHz
    ansela=0                       ;ceo port A digitalni
    anselb=0                       ;ceo port B digitalni
    latb=0                         ;isključimo sve LED
    trisa=255                      ;postavi ceo port A kao ulazni
    trisb=0                        ;postavi ceo port B kao izlazni

    do                             ;početak glavne petlje
      do while taster1=1           ;vrti se u petlji sve dok je TA1 otpušten
        led1=0                     ;isključi LED D1
      loop                         ;kraj petlje

      do while taster1=0           ;vrti se u petlji sve dok je TA1 pritisnut
        led1=1                     ;uključi LED D1
      loop                         ;kraj petlje
      led2=1                       ;uključi LED D2
    loop                           ;kraj petlje
      
end    


Umesto IF naredbi koje ispituju stanje tastera postavili smo DO ... LOOP petlje za svako od stanja tastera. Bitno je da uočite da se LED2 uključuje tek nakon što se taster pritisne i otpusti, a to je zato što se program prvo vrti u prvoj petlji sve dok je taster otpušten, pa kad se pritisne prelazi u drugu petlju i ostaje u njoj sve dok je taster pritisnut i tek nakon otpuštanja izlazi iz petlje i stiže do naredbe kojom se uključuje LED2.

Namera je bila da se ovim primerom prikaže da jedan jednostavan problem može da se reši na više načina, ali i da je potrebno odabrati pravi način u zavisnosti od potreba. U ovom primeru program se praktično zaustavlja od daljeg izvršavanja sve dok se ne ispune odredjeni uslovi dok se u prethodnom samo na momenat ispita stanje tastera i program nastavlja dalje. Zato treba paziti na izbor načina da se ne upadne u zamku ovog tipa.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:
[ rsinisa @ 01.07.2013. 08:15 ] @
Primer 27:
=======
U ovom primeru koristi se postavka 1.

Pritiskom na taster TA1 uključujemo LED D1, a pritiskom na TA2 je isključujemo.

Code:

led1          var portb.0          ;definišemo alias za led D1
led2          var portb.1          ;definišemo alias za led D2
taster1       var porta.4          ;definišemo alias za taster TA1
taster2       var porta.5          ;definišemo alias za taster TA2

    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000               ;interni oscilator na 4MHz
    ansela=0                       ;ceo port A digitalni
    anselb=0                       ;ceo port B digitalni
    latb=0                         ;isključimo sve LED
    trisa=255                      ;postavi ceo port A kao ulazni
    trisb=0                        ;postavi ceo port B kao izlazni
    wpua=%00100000                 ;uključi PULL-UP na RA5
    option_reg=%01111111           ;uključi globalno PULL-UP otpornike

    do                             ;početak petlje
      if taster1=0 then led1=1     ;ako je TA1 pritisnut, uključi D1
      if taster2=0 then led1=0     ;ako je TA2 pritisnut, isključi D1
    loop                           ;kraj petlje
      
end


Na šemi razvojnog sistema vidi se da za taster TA1 postoji pull-up otpornik, dok za TA2 ne postoji, a ovaj program ipak radi kako treba. To je zato što, kao što smo napomenuli u tekstu uz primer 25, su u sam PIC ugradjeni pull-up otpornici vrednosti od oko 22 Koma; B port ih ima na svim pinovima, dok na portu A postoji samo jedan i to na RA5, a taster TA2 je upravo povezan na taj pin.

Da bi aktivirali te otpornike potrebno je da ih uključimo podešavanjem odgovarajućih SFR registara, a to su WPUA za otpornik na portu A, i WPUB za otpornike na portu B, koji omogućavaju da kontrolišemo svaki otpornik pojedinačno - kada je bit setovan, odgovarajući otpornik je uključen i to je podrazumevano stanje nakon uključenja PIC-a. Detalje za ove registre možete da vidite u tehničkoj dokumentaciji na stranama 121 i 127 respektivno.

Medjutim, postoji još jedan bit koji globalno omogućava uključenje ovih otpornika, a to je bit 7 registra OPTION koji se u tehničkim podacima pojavljuje još i pod imenom OPTION_REG (radi se o istom registru) i to drugo ime se koristi u PBP-u. Kada je taj bit setovan, svi otpornici su isključeni i to je podrazumevano stanje po uključenju. Ostali bitovi ovog registra nam za sada nisu potrebni, a ako želite da saznate više o njemu, pročitajte detalje na strani 175. Ova dupla kontrola može da Vam se učini besmislenom, ali je zgodno u nekim situacijama da promenom samo jednog bita isključite sve pull-up otpornike.

Medjutim, čak i kada su svi registri podešeni za uključenje pull-up otpornika, oni će biti automatski isključeni za svaki pin portova koji je podešen kao izlazni.

Vidimo da smo u inicijalnom bloku programa dodali podešavanje WPUA i OPTION_REG registra kako bi uključili pull-up na RA5 pri čemu registar WPUA nismo morali da podešavamo jer smo rekli da je po uključenju ionako setovan odgovarajući (u ovom slučaju i jedini) bit. Ali, i to smo već rekli, dobra je praksa podesiti sve registre koje koristimo kako bi tačno znali njihova stanja.

Ostali deo programa bi trebalo da Vam je jasan i nisu potrebna dodatna objašnjenja.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:
[ rsinisa @ 24.07.2013. 00:13 ] @
Primer 28:
=======
U ovom primeru koristi se postavka 1.

Pretpostavimo da nam treba uredjaj kojim ćemo, na primer, da brojimo vozila koja prodju nekom ulicom i za to upotrebimo sistem kod koga se pritiskom na taster brojač vozila uveća za 1 pri svakom pritisku. Obzirom da još nismo radili sa displejima, upotrebićemo LATB registar kao brojač jer imamo ujedno i vizuelnu indikaciju na LE diodama, doduše u binarnom obliku, ali tu lekciju smo odavno naučili i nije nam problem da ga pretvorimo u dekadni.

Code:

taster1       var porta.4          ;definišemo alias za taster TA1
taster2       var porta.5          ;definišemo alias za taster TA2

    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000               ;interni oscilator na 4MHz
    ansela=0                       ;ceo port A digitalni
    anselb=0                       ;ceo port B digitalni
    latb=0                         ;isključimo sve LED
    trisa=255                      ;postavi ceo port A kao ulazni
    trisb=0                        ;postavi ceo port B kao izlazni
    wpua=%00100000                 ;uključi PULL-UP na RA5
    option_reg=%01111111           ;uključi globalno PULL-UP otpornike

    do                             ;početak petlje
      if taster1=0 then            ;ako je TA1 pritisnut,
        latb=latb + 1              ;uvećaj stanje LATB za 1
      endif
      if taster2=0 then latb=0     ;ako je TA2 pritisnut, isključi sve LED
    loop                           ;kraj petlje
      
end


Medjutim, umesto da se pri svakom pritisku na TA1 binarna kombinacija na LE diodama promeni za 1, primećujemo da svetle sve LED dok držimo pritisnut taster TA1, a kada ga otpustimo na LED ostane neka proizvoljna kombinacija koja ne predstavlja broj uvećan za 1. Gde smo pogrešili?

Ovo je klasičan početnički problem i zato ukazujemo na njega kroz primer koji ne radi ono što smo zamislili. Hajde da analiziramo program, deo izmedju DO i LOOP.

Prva IF naredba ispituje da li je pritisnut taster TA1, i ako jeste uveća se registar LATB za 1. Nakon toga se u drugoj IF naredbi ispituje da li je pritisnut taster 2, i ako jeste resetuje se LATB, a zatim se program vraća na prvu IF naredbu. I gde je tu problem? Obe IF naredbe se izvrše za svega par mikrosekundi, tačno vreme zavisi od toga da li je neki taster pritisnut, ali je to vreme svakako kratko, reda 10-ak us. Ako držimo pritisnut TA1 vidimo (iz asmeblerskog programa) da se na svakih 11 mikrosekundi LATB uveća za 1 što praktično znači da se za pritisak od jedne sekunde LATB uveća za neverovatnih 90909 ! Obzirom da je broj njegovih kombinacija 256, vidimo da se za to vreme sve kombinacije "provrte" čak 355 puta, a ako se uzme u obzir da oko može da vidi do 25 promena u sekundi, jasno nam je zašto nam se čini da su sve LED upaljenje dok držimo taster TA1 pritisnut.

Rešenje ovog problema je da uvećamo LATB u trenutku kada prvi put detektujemo pritisak na taster, a da zanemarimo njegovo stanje sve dok ga ne otpustimo i ponovo pritisnemo. Kako da to uradimo, videćemo u nekoliko narednih primera.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:
[ rsinisa @ 25.07.2013. 20:05 ] @
Primer 29:
=======
U ovom primeru koristi se postavka 1.

Problem iz prošlog primera može da se reši na ovaj način:

Code:

taster1       var porta.4          ;definišemo alias za taster TA1
taster2       var porta.5          ;definišemo alias za taster TA2

    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000               ;interni oscilator na 4MHz
    ansela=0                       ;ceo port A digitalni
    anselb=0                       ;ceo port B digitalni
    latb=0                         ;isključimo sve LED
    trisa=255                      ;postavi ceo port A kao ulazni
    trisb=0                        ;postavi ceo port B kao izlazni
    wpua=%00100000                 ;uključi PULL-UP na RA5
    option_reg=%01111111           ;uključi globalno PULL-UP otpornike

    do                             ;početak petlje
cekaj0:
      if taster2=0 then latb=0     ;ako je TA2 pritisnut, isključi sve LED
      if taster1=1 then cekaj0     ;ako TA1 nije pritisnut idi na labelu 'cekaj0'
      latb=latb + 1                ;uvećaj stanje LATB za 1
cekaj1:
      if taster1=0 then cekaj1     ;ako je TA1 još uvek pritisnut, idi na labelu 'cekaj1'
    loop                           ;kraj petlje
      
end


Analiziraćemo opet deo programa izmedju DO i LOOP.

Prvi IF proverava da li je pritisnut taster TA2 i ako jeste, resetuje LATB registar.
Drugi IF proverava da li je taster TA1 otpušten i ako jeste, vraća se na labelu 'cekaj0'. Ako je TA1 pritisnut, uvećava se LATB za 1, a zatim se sa sledećom IF naredbom proverava da li je taster još uvek pritisnut. Ako jeste, vraća se na labelu 'cekaj1', odnosno na isti IF, tj. ova IF naredba ne dozvoljava da se LATB ponovo uveća sve dok se TA1 ne otpusti kako nebismo imali lažna brojanja kao u prethodnom primeru i time smo rešili problem pogrešnog brojanja. Medjutim, napravili smo sebi novi problem jer se, sve dok je TA1 pritisnut, program vrti u petlji od jedne IF naredbe i dalji napredak je nemoguć, program je praktično "prikovan" na jednom mestu, što nam nikako ne odgovara, sem u nekom krajnje jednostavnom programu.

Ali, ovde se javlja još jedan problem - ako ste probali program videli ste da se vrlo često jednim pritiskom na taster stanje LATB registra uveća za više od jedan tj. registruje se veći broj pritisaka nego što ih je zaista bilo. Ovaj problem ne potiče od programa već od tastera, tj. od jedne osobine njegovih kontakata koja se zove poskakivanje, odn. "bouncing" na engleskom. O ovom problemu i kako ga rešiti biće reči u sledećoj lekciji.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:
[ rsinisa @ 29.07.2013. 09:09 ] @
Poskakivanje kontakata
=================
Kod svih mehaničkih prekidačkih elemenata (prekidači, tasteri, releji, mikroprekidači, sklopke) zbog same konstrukcije i činjenice da su kontakti od metala te da imaju odredjenu masu i elastičnost, dešava se da se u momentu spajanja ili odspajanja kontakata ne ostvari odmah spoj već da kontakti neko vreme poskakuju i time ostvaruju nekoliko otvaranja i zatvaranja strujnog kruga.

Vreme i broj poskakivanja zavisi od nekoliko faktora kao što su konstrukcija, brzina pomeranja kontakta i jačina pritiska, zaprljanost kontakata i sl. Čak i kad su faktori isti, vreme i broj poskakivanja će biti različiti. Kod kvalitetnijih elemenata broj poskakivanja može da bude jednocifren (pa čak i da ga nema), a vreme smirivanja može da se kreće od par mikrosekundi (ponekad i ispod jedne mikrosekunde) pa sve do reda 1 ms, dok kod lošijih to zna da potraje i preko 150 ms. Takodje je sasvim uobičajeno da nije isto vreme smirivanja kod otvaranja i kod zatvaranja kontakta jednog istog prekidačkog elementa i ono može znatno da se razlikuje.

Na sledeće 2 slike vidi se poskakivanje kod zatvaranja i kod otvaranja kontakata.





Ako se ovi prekidački elementi koriste za uključenje sijalica, motora, grejnih tela i sličnih tromih sistema, ovo poskakivanje ne igra nikakvu ulogu i ne remeti normalan rad tih uredjaja. Ali ako te elemente priključimo na neki mikrokontroler ili elektronsko kolo koje je dovoljno brzo da to poskakivanje registruje kao više uzastopnih zatvaranja i otvaranja , onda imamo problem koji moramo da rešimo, inače ćemo da imamo, kao što smo videli u prethodnom primeru, netačne podatke.

Eliminacija poskakivanja ("debouncing" na engleskom) može da se uradi hardverski i softverski i svaki način ima nekoliko tipičnih rešenja. Najčešća hardverska rešenja su RC filter i filter sa RS flip-flopom. Sledeće dve slike predstavljaju ta dva rešenja s tim da druga varijanta može da se koristi samo ako imamo element sa otvorenim i zatvorenim kontaktom.





Medjutim, mi ćemo ovde da se bavimo softverskim rešenjima jer baratamo jednim moćnim "oružjem" koje je u stanju da radi brzo i softverski sve to postigne čime se ostvaruje ušteda u prostoru i materijalu što može da bude ekonomski veoma korisno.

Zbog samog načina izrade tasteri koji se koriste na našem razvojom sistemu imaju veoma mali broj poskakivanja (tipično od 1 do 5) i vreme smirivanja koje je najčešće ispod 1 ms što je odlično vreme, ali ako uzmemo u obzir da jedna mašinska instrukcija u našim primerima traje svega jednu mikrosekundu, svesni smo, kao što se pokazalo u prethodnom primeru, da imamo problem koji ne možemo da zanemarimo.

Postoji veliki broj softverskih rešenja koja se primenjuju u praksi jer ni jedno rešenje nije univerzalno, svako ima dobre i loše strane, a koje će biti upotrebljeno zavisi od konkretne potrebe u uredjaju. Pozabavićemo se nekima od njih.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:
[ rsinisa @ 19.08.2013. 09:38 ] @
U ovom primeru koristi se postavka 1.

Najjednostavniji način rešavanja problema poskakivanja kontakata dat je u ovom primeru:

Code:

taster1       var porta.4          ;definišemo alias za taster TA1
taster2       var porta.5          ;definišemo alias za taster TA2

    include "1827_cfg1.pbp"
    DEFINE OSC 4 

inic:
    osccon=%01101000               ;interni oscilator na 4MHz
    ansela=0                       ;ceo port A digitalni
    anselb=0                       ;ceo port B digitalni
    latb=0                         ;isključimo sve LED
    trisa=255                      ;postavi ceo port A kao ulazni
    trisb=0                        ;postavi ceo port B kao izlazni
    wpua=%00100000                 ;uključi PULL-UP na RA5
    option_reg=%01111111           ;uključi globalno PULL-UP otpornike

    do                             ;početak petlje
cekaj0:
      if taster2=0 then latb=0     ;ako je TA2 pritisnut, isključi sve LED
      if taster1=1 then cekaj0     ;ako TA1 nije pritisnut idi na labelu 'cekaj0'
      pause 20                     ;sačekaj 20 ms
      if taster1=1 then cekaj0     ;ako TA1 nije pritisnut idi na labelu 'cekaj0'
      latb=latb + 1                ;uvećaj stanje LATB za 1
cekaj1:
      if taster1=0 then cekaj1     ;ako je TA1 još uvek pritisnut, idi na labelu 'cekaj1'
      pause 20                     ;sačekaj 20 ms
      if taster1=0 then cekaj1     ;ako je TA1 još uvek pritisnut, idi na labelu 'cekaj1'
    loop                           ;kraj petlje
      
end


Ovo rešenje nije baš najbolje, ali ga početnici često koriste jer se lako implementira i za njih je lako razumljivo. Iako nije savršeno, ovo rešenje je uglavnom zadovoljavajuće u nekim situacijama, mada u uslovima povećanih smetnji može da dovede do pogrešnog očitavanja i ne preporučuje se kada je neophodna apsolutna sigurnost.

Kako radi ovo rešenje? Veoma jednostavno: uradi se testiranje tastera i ako je pritisnut, napravi se potrebna pauza (u našem slučaju je to 20 ms) i zatim se ponovo testira stanje tastera. Ako test kaže da je i dalje pritisnut, podrazumeva se da je taster zaista pritisnut i radi se ono što je potrebno u tom slučaju.

U našem primeru provera sa pauzom se vrši i prilikom pritiskanja i prilikom otpuštanja tastera što je najispravnije, ali je u većini slučajeva dovoljno samo pri pritiskanju. Upišite ovaj program u PIC i proverite ima li sada lažnog brojanja.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi:
[ rsinisa @ 08.09.2013. 05:26 ] @
Prethodni primer ima nekoliko mana od kojih je prva koju pominjemo veoma ozbiljna. Ista je kao i ona koju smo imali u prethodna dva primera, a to je da program ne može da napreduje dalje dok se ne pritisne taster što bi značilo da sav ostali kod mora da dodje ispred testiranja tastera što u praksi nije uopšte praktično, a često je i nemoguće napraviti neki kompleksniji program na taj način.

Druga mana rešenja u prošlom primeru je što se pravi pauza od 20 ms pri svakoj proveri tastera i za to vreme program jednostavno čeka, gubi ponekad dragoceno vreme, i ne može da radi ništa drugo. Ako malo razmislimo, videćemo da je potpuno nepotrebno čekanje ako taster nije pritisnut jer u tom slučaju nema poskakivana kontakata i ne treba čekati na njihovo smirivanje. Zbog toga ćemo da proverimo da li je taster pritisnut i tek tada pravimo pauzu.

Medjutim, tu dolazi do izražaja treća mana, a to je upravo pauza koja se pravi čim se detektuje da je taster pritisnut. U realnim uslovima vrlo je moguće da je neka smetnja, koja je na neki način ušla u sistem, prouzrokovala lažnu detekciju i program će krenuti u čekanje. Smetnje su uglavnom veoma kratke, mnogo kraće od tih 20 ms, i nakon pauze neće biti detektovan pritisak tastera pa smo opet uzalud izgubili to vreme koje početnicima može da izgleda smešno malo, ali u realnosti nam ponekad to mnogo znači.

Sve te probleme rešićemo primerom koji sledi.

---------------------------------------------------------------------------
Sva pitanja vezana za tutorijal možete da postavite u ovoj temi: