PIC16F84 uputstvo za rukovanje

February 28, 2017 | Author: 3fun | Category: N/A
Share Embed Donate


Short Description

Početniku u svetu mikrokontrolera najteže je napraviti onaj prvi korak. Nadam se da će mu ovo uputstvo &#...

Description

PIC16F84 UPUTSTVO ZA RUKOVANJE

Staza za plažu 6 kaca na Moravici u Sokobanji 1

1. Predgovor Zašto baš PIC16F84? Taj mikrokontroler je zastareo, veliki, spor, skup... Međutim da li je baš sve tako. Star? Pa šta. Nijedan moj kompjuter nije (u trenutku kupovine) bio mlađi od 4 godina. Prvi put sam na internet izašao mašinom sa 100MHz i 16Mb. Ukoliko i dalje može poslužiti, godine mu nisu bitne. Čak zato ima i jednu prednost: ima ga na svakom ćošku! Njegova veličina za početnike može predstavljati samo pogodnost. Početniku je daleko lakše lemljenje osamnaestopinskog DIP nego šezdesetčetvoropinskog TQFP kućišta, naravno na jednoslojnoj štampanoj pločici. Brzina mikrokontrolera pri učenju ne igra nikakvu ulogu. Štaviše, na više mesta u programima datim u uputstvu namerno se moralo izazivati kašnjenje. Cena mikrokontrolera! Jeste skup. Danas se mogu kupiti mnogo moćniji mikrokontroleri po manjoj ceni. Ali ukoliko se uzme u obzir i cena odgovarajućeg programatora (pogotovu mogućnost samogradnje), PIC16F84 je i dalje najjeftiniji mikrokontroler. Početniku u svetu mikrokontrolera najteže je napraviti onaj prvi korak. Nadam se da će mu ovo uputstvo će pomoći u tom putu. A posle? Lako će se sa stečenim znanjem naučiti i mnogo komplikovaniji i savremeniji mikrokontroleri. Iako se hardverske mogućnosti mikrokontrolera neprekidno usavršavaju, softver uglavnom ostaje isti. Za lakše razumevanje ovog uputstva poželjan je pristup internetu i potrebna su određena predznanja: ●

Osnovno poznavanje elektronskih kola (anoda i katoda LED, povezivanje LED displeja, funkcija taster prekidača, obeležavanje izvoda integrisanih kola, pojam pina, funkcija diode u logičkim kolima, naponski nivoi logičke 0 i 1, visokoimpedansno stanje, Šmitov okidač)



Osnovno poznavanje binarnih sistema (bit, bajt, binarno, decimalno, heksadecimalno, BCD i označavanje negativnih brojeva)



Osnovne logičke operacije (Bulova algebra)



Pojam multipleksa



Princip serijskog prenosa podataka

Nemojte dozvoliti da Vas ovaj spisak obeshrabri. Veliki deo ovoga je objašnjen u uputstvu. Gradivo u uputstvu izloženo je od poznatih ka nepoznatim i od lakših ka težim lekcijama. Za dosta specifičnosti dati su primeri programa u kojima se upotrebljavaju. Trudio sam se da gradivo što interesantnije izložim. Nadam se da sam uspeo. 2

2. Dobar stil programiranja Pre nego što uđete u finese programiranja, mislim da bi trebalo objasniti stilove programiranja. ●

Ukoliko stavite ; (tačku-zarez) bilo gde u Vašem programu, kompajler će ignorisati sve karaktere iza njega sve dok ne dođe do znaka za novi red. Ovo znači da možete staviti komentar unutar programa kako bi Vas podsetio šta se uopšte u njemu radi. Ovo je dobra praksa, čak i za najjednostavnije programe. Možda sada u potpunosti razumete šta program radi, ali za par meseci, samo ćete se češkati po glavi. Zbog toga, komentarišite što više. Nema ograničenja.



Možete pridružiti imena konstantama i registrima (više o ovome kasnije). Dosta je lakše čitati na srpskom u šta upisujete, ili šta označava broj, nego da pokušavate da se setite šta znače svi ti brojevi. Zbog toga, koristite opisna imena kao npr. ZBIR. Primetili ste da sam napisao ime velikim slovima. Ono se tako ističe.



Napravite zaglavlje programa koristeći tačku-zarez. Primer je dat ispod. ;********************************************************* ; Autor : Pera Ždera Datum : 12.4.2008. ; Verzija : 0.5 Naslov : Test ; ; Opis hardvera : ; - RC oscilator 200KHz. ; - Svi tasteri su povezani od pinova ka masi. ; T1 na RB0, T2 na RB1. Uključeni su interni Pull-up otpornici. ; - Sve LED od +5V ka pinovima. LED1 na RA0, LED2 na RA2. ; ; Opis softvera : ; - Stanje LED1 menja se prilikom svakog interapta sa T1 ; - Stanje LED2 menja se tajmerom na svakih 0,5S jedino ; ukoliko je istovremeno pritisnut T2 ; ; Dodatni fajlovi : p16F84.inc ;********************************************************* Uočili ste da je napravljena neka vrsta kocke. Ovako izgleda preglednije.



Izdvojite instrukcije od početka reda i labela sa par razmaka ili „Tab“ dugmetom. Na taj način asembler prepoznaje da li je reč o instrukciji ili labeli, a program izgleda preglednije.



Najzad, isprobajte i dokumentujte Vaš program i na papiru. Možete koristiti grafike, algoritme ili šta god želite. To će vam pomoći u pisanju programa, korak po korak, kao i u njegovoj kasnijoj analizi.

A sada prelazimo na pravu stvar. 3

3. Registri Registar je RAM memorijska lokacija unutar mikrokontrolera u koju se može upisivati, sa koje se može čitati, ili obavljati obe ove funkcije. Najlakše je da svaki od njih zamislite kao kutiju u koju može stati do 255 klikera (različitih stanja). Sledeća skica prikazuje raspored registara unutar PIC16F84 mikrokontrolera. Slika prikazuje adrese na kojima je smeštema RAM memorija (u obliku osmobitnih registara) unutar mikrokontrolera, što će Vam pomoći pri razumevanju njihovog adresiranja. Adresa 0x00

BANK0 INDF(1)

BANK1 INDF(1)

0x01

TMR0

OPTION_REG

0x81

0x02

PCL

PCL

0x82

0x03

STATUS

STATUS

0x83

0x04

FSR

FSR

0x84

0x05

PORTA

TRISA

0x85

0x06

PORTB

TRISB

0x86

0x07

/

/

0x87

0x08

EEDATA

EECON1

0x09

EEADR

0x0A

PCLATH

PCLATH

0x8A

0x0B

INTCON

INTCON

0x8B

EECON2

(1)

Adresa 0x80

0x88 0x89

0x0C

0x8C

.

.

. . .

68 Registra opšte namene (statička RAM memorija)

. Mapirani u BANK0

. .

.

.

0x4F

0xCF

0x50

0xD0

.

.

.

/

/

.

.

.

0x7F

0xFF

/ - Neimplementovana memorijska lokacija (čita se kao 0) - Nije fizički registar

(1)

4

Primećujete da su registri podeljeni u dve grupe, označene sa BANK0 i BANK1. BANK1 se uglavnom koristi za konfigurisanje trenutnog hardverskog stanja mikrokontrolera. Uglavnom mu je (za jednostavnije programe) dovoljno pristupiti samo prilikom početne inicijalizacije mikrokontrolera. Kako se najbitniji registri (PORTA i PORTB) nalaze u BANK0, program će uglavnom biti u njoj. Sledeću specifičnost predstavljaju prvih 12 registara u bankama (0x00 – 0x0B). Njima se direktno upravlja radom mikrokontrolera što ih čini povlašćenim (eng. Special Function Registers - registri specijalne namene), dok je obična RAM memorija (eng. General Purpose Registers - registri opšte namene) dostupna u registrima od 0x0C do 0x4F, a istovremeno joj se može pristupiti i preko 0x8C do 0xCF adresa. Sigurno ste već videli rampe za prolaznike po supermarketima ili autobuskim stanicama. One propuštaju prolaznike samo u jednom smeru. Unutar mikrokontrolera TRIS (TRISA i TRISB) registri izvršavaju ovu funkciju. Oni se nalaze na adresama 0x85 i 0x86, respektivno. Da biste programirali željeni pin tako da bude ulazni ili izlazni (propušta prolaznike unutra ili napolje), pošaljete 1 ili 0 na njegov bit u odgovarajućem TRIS registru. Pri tome možete koristiti bilo koji (binarni, decimalni ili heksadecimalni) format brojeva, međutim binarnim se slikovitije predstavlja stanje željenog pina. Ukoliko niste vični pretvaranju binarnih u decimalne ili heksadecimalne brojeve i obratno, koristite bilo koji napredniji kalkulator. Svi RA (RA0 do RA4) i RB (RB0 do RB7) pinovi mikrokontrolera imaju dvojaku fuknciju. Oni mogu biti ulazni ili izlazni. Da li će biti ulazni ili izlazni podešava se u odgovarajućem TRIS registru. Na primer ukoliko se u TRISB nalazi sledeća binarna vrednost: b'00101111' pinovi će biti konfigurisani kao na slici. Primećujete da bit 7 (eng. MSB – Most Single Bit - bit najveće težine ) odgovara pinu RB7 i da se on prilikom binarnog označavanja nalazi sa leve strane. Nasuprot njemu bit 0, bit najmanje težine (eng LSB – Low Single Bit) odgovara pinu RB0. Potpuno ista situacija je i sa TRISA registrom, sa tom razlikom što su njemu gornji bitovi neiskorišćeni (jer nemaju pripadajućih pinova). Na gornjoj slici pinovi su konfigurisani po sledećem: pin

RB7

RB6

RB5

RB4

RB3

RB2

RB1

RB0

bit broj (MSB)7

6

5

4

3

2

1

0(LSB)

stanje

0

0

1

0

1

1

1

1

Ulaz / Izlaz

I

I

U

I

U

U

U

U

Kako se TRISB nalazi u banci 1 (BANK1) potrebno je prebaciti se tamo. Da bi se prebacili iz banke u banku koristi se bit 5 STATUS registra. Za prebacivanje iz banke 0 u banku 1 potrebno ga je setovati, a za vraćanje u banku 0, resetovati. STATUS registar se nalazi na adresi 0x03 (0x03 ili h'03' označava brojeve u heksadecimalnom formatu. Binarni format se piše kao b'00000011', a decimalni kao .03 ili d'03'). 5

Čemu konfigurisanje pinova? Ukoliko je odgovarajući pin konfigurisan (preko svog TRIS registra) kao izlazni, na njega se iz mikrokontrolera mogu poslati naponski nivoi od 0V i +5V, odnosno na njemu će se u svakom trenutku nalaziti jedan od ovih napona. Pri tome se naponski nivo od 0V predstavlja kao logička 0, a napon od +5V kao logička 1. Ukoliko je pak pin konfigurisan kao ulazni, mikrokontroler će u svakom trenutku moći da očita gore pomenute vrednosti napona na pinu, i u zavisnosti od logičkog nivoa na pinu preduzme odgovarajuću akciju. Pinove koji se ne upotrebljavaju u električnoj šemi potrebno je konfigurisati kao izlazne. U protivnom varijacije napona na njima prouzrokuju povećanu potrošnju i grejanje mikrokontrolera, a eventualno i njegovu neispravnost. Da biste postavili jedan od izlaznih pinova na visoki logički nivo, jednostavno treba poslati “1” na njemu odgovarajući bit u PORTA ili PORTB registru. Format zapisa je isti kao i za TRIS registre. Slično tome, da biste pročitali da li se neki pin (ranije konfigurisan kao ulazni) nalazi na logičkoj 0 ili 1, treba da proverite da li je odgovarajući bit u PORTA ili PORTB registru u setovanom ili resetovanom stanju. Pre nego što proučite primer asemblerskog kôda, treba objasniti funkciju još jednog registra: W. W (eng. Working - radni) registar je registar opšte namene u koji možete smestiti bilo koju brojčanu vrednost (u opsegu od .0 do .255) sa kojom želite raditi. Nakon što ste pridružili određenu vrednost registru W, možete mu pridružiti neku drugu vrednost (oprez – time biste automatski obrisali prethodnu) ili zapamćenu vrednost iz njega premestiti na neku drugu memorijsku lokaciju (registar). Za razliku od ostalih registara on nema svoju adresu, već je integrisan u sklopu samog mikrokontrolera. U opisima instrukcija se mogu sresti oznake f, k, b i d. Pri tome je sa f (eng. file) označena adresa jednog od registra iz tabele sa početka ovog poglavlja, k označava konstantnu vrednost, b je redni broj bita u registru a d označava odredište (eng. destination) rezultata operacije. Ilustrovaćemo sve do sada naučeno. Nemojte još uvek isprobavati ni kompajlirati kôd - to ćete uraditi kada dođete do prvog celovitog programa. Za sada pokušajte da prepoznate način na koji se konfigurišu portovi, i pripremite se da naučite par asemblerskih instrukcija. Za pisanje kôda možete koristriti bilo koji tekst editor koji snima čist .txt fajl bez ikakvih formatiranja. Na primer odličan Notepad++ (ugradio sam mu prepoznavanje i naglašavanje asemblerskih instrukcija), Code Edit Pro (sam naglašava instrukcije), Windowsov Notepad ili Linuxov Leafpad. U jednom od narednih poglavlja, upoznaćete se sa MPLAB razvojnim okruženjem, i njegovim editorom. Najpre je potrebno prebaciti program iz banke 0 u banku 1. Ovo se radi setujući bit 5 STATUS registra, čija je adresa 0x03. bsf 0x03,5 BSF f,b znači “setuj bit b u registru f” (eng. Bit Set f). Ovde je f=0x03 što je adresa STATUS registra (pogledajte raniju tabelu) i b=5 što označava redni broj bita u STATUS registru. Dakle ovim je rečeno “setuj bit 5 na adresi 0x03”. 6

Sada se, dakle, program nalazi u banci 1. movlw b'00101111' Ovom instrukcijom smešta se binarni broj b'00101111' u W registar. Ovo isto mogli ste da uradite sa heksadecimalnim brojem i tada bi instrukcija izgledala ovako: movlw 0x2F Obe instrukcije rade potpuno istu stvar. MOVLW k znači “ubaci vrednost koja sledi direktno u registar W” (eng. Move Literal to W). Sada treba premestiti ovu vrednost u TRISB registar, da bi se konfigurisali pinovi PORTB registra. movwf 0x86 Instrukcija MOVWF f znači: “premesti vrednost registra W u f registar” (eng. Move W to f). U ovom slučaju adresa f je adresa registra TRISB (vidite u tabeli). Bitno je primetiti da ovo nije premeštanje u svom bukvalnom značenju, jer je W registar nakon instrukcije ostao nepromenjen. Pre bi joj odgovarao prevod kopiraj (eng. copy). TRISB registar sada sadrži željenu vrednost, čime su konfigurisani ulazno/izlazni (skraćeno U/I) pinovi. Sada je potrebno prebaciti program u banku 0, kako bi se dalje moglo manipulisati signalima na U/I pinovima. bcf 0x03,5 Ova instrukcija je suprotna od BSF. BCF f,b znači “resetuj bit b u registru f” (eng. Bit Clear f). Brojevi koji slede su adresa registra (f), u ovom slučaju STATUS registra i broj bita (b), u ovom slučaju bit 5. Dakle ovim je u stvari resetovan bit 5 STATUS registra. Posledica poslednje instrukcije je da se program ponovo nalazi u BANK0. Primećujete da je adresa STATUS registra ista, iako bi u BANK1 trebala biti 0x83. Nemoj da vas to buni. Svim registrima u BANK1 može se pristupati preko adresa registra u BANK0, jedino je bitno pravilno podesiti u kojoj se banci nalazi program. Ipak, ne preterujte sa ovim. Razumljivije je čitati program sa normalnim adresama. Za registre koji su zajednički za obe banke, ovo je potpuno svejedno. Ceo prethodni kôd zapisan u jednom bloku izgleda ovako: bsf movlw movwf bcf

0x03,5 b'00101111' 0x86 0x03,5

; Idi u BANK1 ; Stavi b'00101111' u W ; Prebaci b'00101111' u TRISB ; Vrati se u BANK0

Nakon što snimite fajl, promenite mu txt ekstenziju u asm. Za ovo će vam u Windowsu trebati Total Commander, a u Linuxu npr. Gnome Commander. Proučite prethodni primer nekoliko puta, sve dok ne budete u stanju da ga u potpunosti razumete. Za sada ste naučili 4 instrukcije. Još samo 31! 7

4. Izlazi U prethodnom poglavlju ste naučili kako da konfigurišete U/I pinove porta tako da budu ulazni ili izlazni. U ovom poglavlju ćete naučiti kako da pošaljete odgovarajući logički nivo na portove. U primeru koji sledi cilj će Vam biti da omogućite treptanje jedne LED (eng. Light Emitting Diode), i u njemu ćete videti jedan potpuni program. Nemojte još uvek isprobavati, kompajlirati ni programirati Vaš PIC listinzima koji slede, jer su oni dati samo kao ilustracija. Najpre treba podesiti drugi bit PORTA registra tako da bude izlazni: bsf movlw movwf bcf

0x03,5 ; Idi u banku 1 b'00000000' ; Stavi 00000 u W 0x85 ; Prebaci 00000 u TRISA – svi pinovi su izlazni 0x03,5 ; Vrati se u BANK0

Ovo bi trebalo da Vam bude poznato iz prethodnog primera. Jedina razlika je u tome što ste sada podesili sve pinove PORTA registra kao izlazne, šaljući 0x00 u TRISA registar. Zatim treba uključiti LED. Zato treba na jedan od pinova (onaj na kome je povezana LED) poslati logičku 1. Evo kako se to radi. (Obratite pažnju na komentare kôda): ; Upiši .4 u W registar.

movlw

b'00000100'

movwf

0x05 ; Prebaci sadržaj iz W (.4) u PORTA, čija adresa je ; 0x05. To postavlja logičku 1 samo na pinu RA2.

; Pošto je LED uključena, treba je isključiti. ; Upiši .0 u W registar.

movlw

b'00000000'

movwf

0x05 ; Prebaci sadržaj iz W (.0) u PORTA, čija adresa je 0x05

Ovim ste postigli da jednom uključite, i zatim isključite LED. Ono što želite da postignete jeste da LED neprekidno treperi. To se može implementirati vraćajući izvršenje programa na početak. Postavite “labelu” (oznaku) na početak programa, i zatim recite programu da nastavi svoje izvršavanje sa tako označene pozicije. Labela se postavlja veoma jednostavno: upišite ime, recimo Poc, i zatim prepišite sledeći kôd: Poc

; Upiši .4 u W registar.

movlw

b'00000100'

movwf

0x05 ; Prebaci sadržaj iz W (.4) u PORTA, čija adresa je ; 0x05. To postavlja logičku 1 samo na pinu RA2.

8

; Pošto je LED uključena, treba je isključiti. ; Upiši .0 u W registar.

movlw

b'00000000'

movwf

0x05 ; Prebaci sadržaj iz W (.0) u PORTA, čija adresa je 0x05 ; To postavlja logičku 0 na sve pinove (RA0 do RA4)

goto

Poc

; Nastavi dalje izvršavanje programa od labele Poc

Kao što primećujete, najpre je ispred instrukcije na početku reda stavljena labela “Poc”. Na samom kraju programa je “goto Poc” instrukcijom nastavljeno dalje izvršavanje programa od labele. Instrukcija GOTO k znači “idi na” (eng. Go-idi, Tona) adresu (k) ili labelu. Program će sada neprekidno uključivati i isključivati LED od trenutka dovođenja napona napajanja, a prestaće po njegovom nestanku. Pogledajte još jednom isti program:

Poc

bsf movlw movwf bcf movlw movwf movlw movwf goto

0x03,5 b'00000000' 0x85 0x03,5 b'00000100' 0x05 b'00000000' 0x05 Poc

Komentari su namerno izostavljeni i sve što možete videti jesu nizovi instrukcija i brojeva. Ovo može da bude krajnje zbunjujuće ukoliko kasnije pokušavate da ispravite eventualno otkrivenu grešku u programu, ali već i tokom prvobitnog pisanja programa, kada treba zapamtiti sve te pojedinačne adrese. Čak i kada biste dodali komentare, program bi i dalje delovao nejasno. Zbog toga treba svim brojevima dati imena. Ovo može da se uradi naredbom “equ”, koja jednostavno znači “jednako nečemu drugom” (eng. Equal – jednak). Važno je da primetite da ovo nije instrukcija za PIC već tzv. direktiva koja ima uticaj na sam asembler (više o njemu kasnije). Program koji sadrži “equ” direktivu će, dakle, nakon asembliranja u mašinski kôd PIC-a, biti identičan programu bez “equ” direktive. Ovom direktivom samo zamenjujete željeni broj imenom. Postupite ovako: izbacite sve komentare ali imenujte registre u Vašem programu, a zatim ocenite čitljivost takvog programa. STATUS

equ

0x03 ; Ovo pridružuje naziv STATUS broju 0x03, koji ; predstavlja adresu STATUS registra

TRISA

equ

0x85 ; Ovo pridružuje naziv TRISA broju 0x85, koji ; predstavlja adresu TRISA registra

9

PORTA

equ

0x05 ; Ovo pridružuje naziv PORTA broju 0x05, koji ; predstavlja adresu PORTA registra

RP0

equ

0x05 ; Ovo pridružuje reč RP0 broju 0x05, koji predstavlja ; redni broj bita unutar STATUS registra.

Imena moraju biti definisana pre nego što budu upotrebljena, i zbog toga ih uvek definišite na početku svakog programa. Nakon imenovanja registara, unesite njihova imena i u aktivni deo programa. Ukoliko sada prepišete program bez komentara, ali sa imenovanim registrima, moći ćete da uporedite preglednost i čitljivost takvog listinga sa prethodnim: STATUS TRISA PORTA RP0

Poc

equ equ equ equ

0x03 0x85 0x05 0x05

bsf movlw movwf bcf

STATUS,RP0 b'00000000' TRISA STATUS,RP0

movlw movwf movlw movwf goto

b'00000100' PORTA b'00000000' PORTA Poc

Sigurno ste primetili da imenovani registri čine praćenje programa znatno lakšim, čak i bez ikakvih komentara. Takođe možete primetiti da se imenovani registri razlikuju od labele po tome što su im sva slova velika. Na taj način ne možete doći u situaciju da kasnije razmišljate da li je neka takva oznaka labela ili imenovani registar. Možda vam deluje čudno što PORTA registar i RP0 bit STATUS registra imaju istu vrednost (0x05). Međutim, razlika je očigledna. PORTA predstavlja adresu registra, a RP0 bit 5 STATUS registra. Asembler ne pravi razliku između njih jer im je vrednost ista (čak se mogu i zameniti), ali vodi računa o njihovom redosledu unutar instrukcije. Takođe možete videti da su instrukcije odvojene od početka reda. To je obavezno, da ih asembler ne bi preveo kao labele.

10

5. Prazne petlje U prethodnom programu postoji mala greška. Skoro svaka instrukcija zahteva jedan instrukcijki ciklus da bi se izvršila. Instrukcijski ciklus je 4 puta veći od takta oscilatora. Ukoliko kao oscilator za takt za PIC16F84 koristite kvarcni kristal od 4MHz trajanje svake instrukcije će biti 4MHz/4ciklusa, ili 1μS. Kako se koristi samo 5 instrukcija, LED će se uključiti i isključiti u samo 6μS. Zbog čega 6 a ne 5? Zbog toga što instrukcije koje menjaju stanje programskog brojača (eng. Program Counter – više o njemu kasnije) poput GOTO za svoje izvršenje troše 2 instrukcijska ciklusa. Kako je to treptanje previše brzo da biste ga uopšte mogli primetiti, zbog sporosti oka delovaće Vam kao da LED svetli konstantno, ali sa pola snage. Dakle potrebno je napraviti adekvatno kašnjenje između trenutka uključenja i isključenja LED. Uobičajeni princip po kome se implementira kašnjenje jeste da mikrokontroleru zadate da odbrojava od prethodno postavljenog broja do nule, i da u trenutku dostizanja nule prekine odbrojavanje. Nulta vrednost, dakle, predstavlja kraj i izlazak iz petlje, nakon čega PIC nastavlja sa izvršavanjem daljeg programa. Najpre treba definisati konstantnu vrednost koja će predstavljati inicijalnu vrednost brojača. Nazovite je BROJAC. Zatim treba odlučiti kolika će biti stvarna vrednost ovog broja. Najveći broj koji se može zadati je d'255' odnosno 0xFF. Međutim, kao što je napomenuto u prethodnom poglavlju, naredba equ pridružuje imena običnim brojevima, ne praveći razliku između adresa registra i bitova. Zato ćete, ukoliko probate njom pridružiti vrednost 0xFF, dobiti grešku pri kompajliranju programa. Ovo se dešava jer memorijska adresa 0xFF nije implementovana u PIC16F84, i zbog toga joj ne možete pristupiti. Pa kako onda pridružiti željeni broj? Za to je potrebno da sa strane sagledate situaciju. Ukoliko imenu BROJAC pridružite, na primer adresu 0x0C, ona će ukazivati na adresu registra opšte namene (RAM memoriju koju možete slobodno koristiti). Prilikom dobijanja napona napajanja, svi neiskorišćeni registri u mikrokontroleru (osim registara specijalne namene) postavljaju se na vrednost 0xFF. Zato će BROJAC imati vrednost 0xFF. Ali, kako onda podesiti BROJAC na drugu vrednost? Sve što trebate uraditi je da ubacite željenu vrednost u taj registar. Na primer, ukoliko želite da BROJAC sadrži vrednost 0x85, ne možete napisati BROJAC equ 0x85, jer će onda BROJAC sadržati adresu TRISA registra. Zato trebate uraditi sledeće: movlw movwf

0x85 0x0C

; Najpre stavite broj 0x85 u W registar, ; a onda ga prebacite u 0x0C registar

Sada možete slobodno napisati BROJAC equ 0x0C. Vrednost unutar imenovanog registra BROJAC koji se nalazi na adresi 0x0C će biti 0x85. Korišćenje neinicijalizovanih (0xFF) vrednosti može dovesti do zabune prilikom kasnije analize programa. Verovatno ćete se pitati kako ste mogli smanjiti vrednost u registru bez njegove prethodne inicijalizacije. U primerima u ovom uputstvu one su korišćene isključivo zbog štednje prostora. Ukoliko ih Vi budete koristili u svojim programima obavezno to naglasite odgovarajućim komentarima. 11

Znači, najpre je potrebno imenovati registar: BROJAC

equ

0x0C

Dalje se treba smanjivati vrednost registra BROJAC sve dok ne dostigne vrednost 0x00. Unutar PIC postoji instrukcija kojom se može ovo uraditi, uz malu pomoć instrukcije goto i labele. Ta instrukcija ima sledeći oblik: decfsz

BROJAC,1

Instrukcija DECFSZ f,d (eng. Decrement f, Skip if zero) znači “Smanji vrednost registra f (u ovom slučaju BROJAC odnosno 0x0C) i stavi dobijenu vrednost u W ako je d=0, odnosno u registar f ako je d=1. Ukoliko je rezultat nakon smanjenja jednak 0 preskoči sledeću instrukciju”. Kako se odredište rezultata koristi u dosta instrukcija, a kao što ste već naučili lakše je pamtiti imena umesto brojeva, moguće je i bitu odredišta dati ime, na sledeći način: W F

equ .0 equ .1

Mnogo reči, za jednu instrukciju. Pogledajte njenu primenu u praksi. BROJAC Pet

equ 0x0C decfsz BROJAC,F goto Pet Nastavi odavde

Ovde je najpre (inicijalno) postavljena konstanta BROJAC na 0xFF. U sledećem redu definisana je labela nazvana Pet, i zadana je decfsz instrukcija. Decfsz BROJAC,F smanjuje vrednost registra BROJAC za 1, i rezultat vraća u registar BROJAC. Ona istovremeno proverava da li je nova vrednost registra BROJAC jednaka 0. Ukoliko nije, program se nastavlja od sledeće linije. U sledećoj liniji imamo instrukciju goto, koja vraća izvršenje programa na decfsz instrukciju. To se ponavlja sve dok vrednost registra BROJAC ne bude jednaka nuli. Onda program preskače sledeću instrukciju (u ovom primeru goto) i nastavlja od mesta gde je napisano “Nastavi odavde”. Kao što vidite, ovim se program “vrti” u jednom mestu tačno određeno vreme (kao brojanje u žmurkama), pre nego što nastavi dalje. To se naziva “prazna petlja”. Kako bi se jednom petljom postiglo maksimalno kašnjenje od 3μS * 256 = 768μS, biće Vam potrebne bar dve petlje (jedna unutar druge) ukupnog kašnjenja od 3μS * 256 * 256 = 0,2S da biste mogli primetiti kako LED treperi. U prošlom poglavlju to nije naglašeno, ali svakom programu potrebno je definisati početak (adresu unutar PIC16F84 sa koje počinje snimanje kôda) i kraj (posle koga nema više instrukcija). Početak programa se definiše sledećom direktivom ORG 0x00 Sada ubacite ove petlje u program, i dovršite ga praveći pravi program sa komentarima: 12

; ****** Imenovanje registra ****** STATUS equ 0x03 ; Adresa STATUS registra TRISA equ 0x85 ; Adresa TRISA registra PORTA equ 0x05 ; Adresa PORTA registra BROJAC1 equ 0x0C ; Prvi brojač za praznu petlju. Inicijalno 0xFF BROJAC2 equ 0x0D ; Drugi brojač za praznu petlju. Inicijalno 0xFF RP0 equ 0x05 ; Oznaka bita 5 STATUS registra F equ .1 ; Oznaka odredišta rezultata instrukcije ; ****** Podešavanje porta ****** org 0x00 bsf STATUS,RP0 movlw b'00000000' movwf TRISA movwf TRISB bcf STATUS,RP0

; Prebacuje program u banku 1 ; Postavlja sve pinove ; kao izlazne ; ; Vraća program u banku 0

; ****** Uključi LED ****** Poc

movlw movwf

b'00000100' ; Uključuje LED stavljajući vrednost PORTA ; b'00000100' u W, a zatim i u PORTA

; ****** Prva petlja aktivna pri uključenoj LED oko 0,2S ****** Pet1 decfsz goto decfsz goto

BROJAC1,F Pet1 BROJAC2,F Pet1

; Smanji BROJAC1 za 1 ; Ukoliko je BROJAC1 jednak 0, nastavi dalje ; Smanji BROJAC2 za 1 ; Ukoliko je BROJAC2 jednak 0, nastavi dalje, ; u suprotnom vrati se na početak petlje. ; Ovaj brojač broji nadole od 255 do 0, 255 puta ; To je tzv. petlja unutar petlje.

; ****** Kašnjenje završeno. Sada isključi LED ****** movlw movwf

b'00000000' ; Isključi LED stavljajući 0 u W registar, PORTA ; a zatim u PORTA

; ****** Druga petlja aktivna pri isključenoj LED oko 0,2S ****** Pet2 decfsz goto decfsz goto

BROJAC1,F Pet2 BROJAC2,F Pet2

; Druga petlja drži LED isključenom ; dovoljno dugo da bi se to moglo primetiti ; ;

; ****** Sada se program vraća na početak ****** goto Poc ; Vraćanje na početak programa ; ****** Kraj programa ****** end

; Direktiva za označavanje kraja programa. 13

Naravno, želećete da isprobate program da bi videli da li zaista radi. Evo električne šeme koju trebate napraviti za test ovog programa. Takt mikrokontrolera određen je upotrebljenim RC oscilatornim kolom (otpornik od 10kΩ i kondenzator od 33pF). Iako za dati primer nije potrebno konfigurisati pinove oba porta, to je poželjno ukoliko su pinovi na PORTB nepovezani. Bolje je utrošiti instrukciju više nego rizikovati nepouzdan rad ili oštećenje mikrokontrolera. Isto tako LED je moguće povezati direktno na pin (bez otpornika), pošto PIC16F84 ima interno ograničenje izlazne struje na max. 25mA. Međutim to nije poželjno. Cena otpornika je zanemarljiva u odnosu na cenu mikrokontrolera. U praksi se češće sreće inverzna logika za povezivanje LED tako što se anoda LED poveže na +5V, a katoda (preko otpornika) na pin. Pri tome će LED svetleti po dovođenju logičke 0 na pin. Ovo je moguće jer pin pri logičkoj 0 može upijati struju do 25mA, a i poželjno zbog manjeg grejanja i potrošnje mikrokontrolera. Čestitamo. Upravo ste napravili svoj prvi program, i napravili kolo kojim se LED uključuje i isključuje. Za sada ste sledeći ova uputstva naučili 7 od ukupno 35 instrukcija, i već kontrolišete ulazno izlazni port. U sledećem poglavlju naučićete kako da svoj kôd kompajlirate i snimite u PIC.

14

6. MPLAB Asembler U ovom poglavlju upoznaćete se sa MPLAB razvojnim okruženjem, i specijalnim funkcijama njegovog editora. Sa sajta http://www.microchip.com/ trebate skinuti programski paket MPLAB. On ima integrisan editor (umesto Windows Notepada), asembler, simulator i drajvere za svoje programatore. Na žalost nas sa dial-up vezom, sam paket teži oko 65Mb. Funkcija editora bi trebalo da vam je jasna. Generisanje čistog .asm fajla. Asembler služi da tekstualne instrukcije iz .asm fajla pretvori u mašinski kôd koji PIC razume. U protivnom, umesto instrukcije movlw 0x01 trebali bi pisati binarni mašinski kôd 110000 00000001. Verovatno Vam je već dosadilo da iznova i iznova pišete STATUS equ 0x03 i ostala standardna imena. MPLAB asembler ima mogućnost učitavanja fajla koji sadrži sva ova imena. Još bolje, u sebi ima i predefinisane obrasce (eng. standard code template) za upis asemblerskog programa sa zaglavljem, uobičajenim direktivama, posebnim delom za interapte (više o njima kasnije)... MPLAB ima jedan poznat bag koji se ogleda u nemogućnosti rada sa putanjom do foldera dužom od 51 karaktera. Zato direktno u C: napravite folder „Moji programi“. U njega kopirajte sledeći fajl: P16f84.inc

- sadrži sve standardne labele

Ovaj fajl trebalo bi da se nalazi u folderu C:\Program Files\Microchip\MPASM Suite\P16f84.inc Onda u Vašem tekst editoru napravite sledeće zaglavlje, ;********************************************************** ; Autor : ; Datum : ; Verzija : ; Naslov : ; ; Opis hardvera : ; Opis softvera : ; Potrebni fajlovi : p16F84.inc ; ;********************************************************** list

p=16F84

; Definiše upotrebljeni mikrokontroler

#include



; Ubacuje nazive registra u program

15

__CONFIG

ORG

_CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC ; Podešava konfiguracione bitove. ; Više o njima kasnije.

0x00

; Definiše start programa

; Prostor za vaše programe. end

; Kraj programa

i snimite ga u folder „C:\Moji programi“ sa nazivom „Zagl.asm”. Unutar foldera „C:\Moji programi“ napravite folder „Proba“. Ovo zaglavlje možete koristiti za svaki novi program koji pravite, međutim uvek ga možete promeniti, tako da odgovara Vašim specifičnim potrebama. Ukoliko zavirite u strukturu p16F84.inc fajla (F3 iz Total Commandera), možete primeriti da su u njemu imenovani svi registri, pa čak i bitovi pojedinih registra. Ukoliko Vam njegova trenutna struktura iz bilo kog razloga ne odgovara, i ovaj fajl možete editovati po sopstvenim potrebama. U tom slučaju uvek ga čuvajte zajedno sa .asm programom. Sada uključite MPLAB IDE. Ne obazirite se na prozore koje je otvorio, već sledite sledeću proceduru: Project, Project Wizard, Next, izaberite PIC16F84, Next Izaberite (ukoliko već nije) Microchip MPASM Toolsuite. Kliknite na „MPASM Assebmler (Mpasmwin.exe)“, i proverite da li se nalazi u folderu C:\Program Files\Microchip\MPASM Suite. Ukoliko ga nema, locirajte ga ručno klikom na Browse. Ostala dva fajla Vam (za sada) nisu bitna. Next, Upišite ime projekta (npr. Proba) i izaberite putanju do ranije napravljenog foldera C:\Moji programi\Proba Next, Uđite u C:\Moji programi. Kliknite naizmenicno na P16f84.inc, Zagl.asm, i na Add, tako da se oba fajla pojave u desnom prozoru. Kliknite na slova A pored njih dok se ne promene u C (Copy). Na taj način se odabrani fajlovi kopiraju u trenutni projekat (u folderu Proba), tako da originali ostaju nepromenjeni za idući put. Ostale moguće opcije su U (User) – relativna putanja do fajlova, S (System) – apsolutna putanja i A (Auto) – MPLAB sam odlučuje. Next i kliknite na Finish. U novootvorenom prozoru „Proba.mcw“ duplo kliknite na Zagl.asm. Otvara se prozor editora u kome možete pisati Vaš program. Možda vam ovaj postupak trenutno izgleda komplikovano, ali u praksi je potrebno ponoviti ga 2 do 3 puta da bi postao to što i jeste. Obična rutina.

16

Sa svim ovim podešavanjima kompletan program bi trebao izgledati otprilike ovako: ;********************************************************** ; Autor Pera Detlić ; Datum 23.3.2008 ; Verzija 7,8 ; Naslov Treptanje LED ; ; Opis hardvera : - RC oscilator, LED od pina RA2 ka masi ; Opis softvera : - Ovim programom omogućeno je treptanje LED ; ; Potrebni fajlovi : p16F84.inc ;********************************************************** ; ****** Inicijalizacija asemblera ****** list #include __CONFIG

p=16F84 ; Definiše upotrebljeni mikrokontroler ; Ubacuje nazive registra u program _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC ; Podešava konfiguracione bitove.

; ****** Imenovanje registra ****** BROJAC1 BROJAC2

equ equ

0x0C ; Prvi brojač za praznu petlju. Inicijalno 0xFF 0x0D ; Drugi brojač za praznu petlju. Inicijalno 0xFF

; ****** Podešavanje porta ****** org bsf movlw movwf movwf bcf

0x00 STATUS,RP0 b'00000000' TRISA TRISB STATUS,RP0

; Prebacuje program u BANK1 ; Postavlja sve pinove ; kao izlazne ; Vraća program u BANK0

; ****** Uključi LED ****** Poc

movlw movwf

b'00000100' PORTA

; Uključi LED stavljajući b'00100' ; u W registar, a zatim i u PORTA

; ****** Prve petlja aktivna pri uključenoj LED oko 0,2S ****** Pet1 decfsz goto decfsz goto

BROJAC1,F Pet1 BROJAC2,F Pet1

; Smanji BROJAC1 ; Ukoliko je BROJAC1 jednak 0, nastavi dalje ; Smanji BROJAC2 ; Ukoliko je BROJAC2 jednak 0, nastavi dalje, ; u suprotnom vrati se na početak petlje. ; Ovaj brojač broji nadole od 255 do 0, 255 puta ; To je tzv. petlja unutar petlje.

17

; ****** Kašnjenje završeno. Sada isključi LED ****** movlw movwf

b'00000000' PORTA

; Isključi LED stavljajući 0 u W registar, ; a zatim u PORTA

; ****** Druga petlja aktivna pri isključenoj LED oko 0,2S ****** Pet2 decfsz goto decfsz goto

BROJAC1,F Pet2 BROJAC2,F Pet2

; Druga petlja drži LED isključenom ; dovoljno dugo da bi se to moglo primetiti ; ;

; ****** Vraćanje programa na početak ****** goto

Poc

; Vraćanje na početak programa

; ****** Kraj programa ****** end

; Kraj programa.

Kao što ste i sami pretpostavili direktiva #include ubacuje fajl p16F84.inc ispred vašeg asemblerskog programa. Sam asembler će pri konverziji instrukcija u mašinski kôd uzeti iz fajla nazive samo onih imenovanih registra koji se koriste u programu. Na taj način program je pregledniji, Vama je skraćeno vreme pisanja programa (za imenovanje registra), a program nije ništa duži nego inače. Sada možete kompajlirati program. Za kompajliranje pritisnite taster F10 na tastaturi. U novootvorenom prozoru „Output“ videćete kratak opis uspešnosti operacije. Možete slobodno ignorisati Message [302]. Ona Vas podseća da upotrebljeni registri (npr. TRISA) nisu u BANK0. Ukoliko Vas ova poruka nervira, možete pre prve instrukcije napisati "ERRORLEVEL -302". U „Output“ prozoru najbitnija je zadnja poruka. Ona mora biti „BUILD SUCCEEDED“. U folderu „Proba“ sada se nalazi par fajlova. Bitni su vam jedino oni sa ekstenzijom .err, .lst i .hex. U fajlu sa .err ekstenzijom, možete videti spisak grešaka i upozorenja nastalih pri asembliranju programa. Fajl sa .lst ekstenzijom predstavlja detaljan pregled svih upotrebljenih instrukcija, komentara... Iz njega možete videti u kom trenutku je tačno nastupila greška u asembliranju. Fajl sa .hex ekstenzijom predstavlja fajl spreman za snimanje u PIC. Postupak snimanja, naučićete u narednim poglavljima.

18

7. Programatori Za snimanje .hex fajla u PIC neophodan vam je programator kao hardverski deo i određeni softver u kompjuteru preko koga se vrši programiranje. Nemojte se zaleteti pa odmah kupiti najskuplji Microchipov programator. Funkcija programatora je programiranje PIC mikrokontrolera možda 5-6 puta dnevno. Da li će on biti na USB ili paralelnom portu uopšte Vam nije bitno. Ionako ćete uglavnom snimati manje od 1KB programa. Jedino bih preporučio izbegavanje programatora sa serijskim portom, zbog nejednakosti njegovih karakteristika na raznim matičnim pločama (uglavnom na laptopovima). Ukoliko imate iskustva u pravljenju elektronskih kola, možete napraviti jedan od programatora sa sajta http://www.icprog.com/. Na istom sajtu nalazi se i pripadajući softver za programiranje. Proguglajte malo. Možda naiđete i na nešto lakše. Ukoliko želite kupiti programator, možete pogledati sledeće sajtove: ●

AllPic programator

Oko 15 €



Programator i razvojni sistem u jednom

Oko 100 €

I opet pre kupovine pretražite internet. Vaš novac je u pitanju. Unutar mikrokontrolera nalaze se takozvani konfiguracioni bitovi. Njima se određuju hardverske specifičnosti mikrokontrolera. Iako su inicijalno ubačeni u __CONFIG diirektivu, neki programatori je ignorišu i postupaju po sopstvenim setovanjima. Za PIC16F84 konfiguracioni bitovi su: Watchdog Timer – dozvoljava odnosno zabranjuje upotrebu WDT u programu Power Up Timer Enable – prouzrokuje kašnjenje pri dovođenju napona napajanja da bi se oscilator mikrokontrolera stabilizovao Code Protection – onemogućava iščitavanje kôda iz PIC – kopiranje programa Oscillator – omogućuje izbor jednog od 4 standardna tipa oscilatora, odnosno RC – (eng. Resistor Condensator) 1 otpornik i 1 kondenzator LP – (eng. Low Power) Za kristalne oscilatore male potrošnje 32KHz-200KHz XT – Za klasične kristalne oscilatore 100KHz-4MHz HS – (eng. High Speed) Za kristalne oscilatore veće brzine 4MHz-10MHz Upotrebu Watchdog Timera naučićete kasnije. Za skoro sve primere u ovom uputstvu, on treba biti isključen – WDT OFF. Power Up Timer Enable bit je (osim kada imate kvalitetan oscilator i kada vam je potreban brz start mikrokontrolera) preporučljivo ostaviti uključenim – PWRTE ON. Code Protection je poželjno isključiti, kako biste mogli verifikovati program nakon programiranja. Međutim, ukoliko trebate prodati PIC sa Vašim programom na koji ste utrošili 3 meseca rada, obavezno ga uključite. U ovom uputstvu, neka bude isključen CP OFF. 19

Vrste oscilatora naučićete kasnije. Za sada je bitno da znate da ovde koristite RC (Resistor – Capacitor) oscilator. Dosta je toga o asembleru i hardveru. Vreme je za učenje novih instrukcija. U sledećem poglavlju naučićete upotrebu potprograma koji će Vam pomoći da program bude manji i jednostavniji.

20

8. Potprogrami Potprogram je deo kôda, ili program, koji možemo pozvati kao takav kad god je potreban. Potprogrami se koriste u slučajevima višestrukog izvršavanja jedne iste funkcije, kao na primer rutine sa praznom petljom za kašnjenje. Prednosti korišćenja potprograma su u lakoći menjanja vrednosti brojača jednom unutar potprograma, nego npr. deset puta kroz glavni program, i u smanjenju količine memorije koju program zauzima unutar PIC. Pogledajte strukturu jednostavnog potprograma: BROJAC

equ 0x0C

; Uzima inicijalnu vrednost 0xFF

Pet

decfsz goto return

BROJAC,F Pet

; Smanjuje i proverava ; sve do 0 ; Povratak iz potprograma

Prvo trebate labelom dati potprogramu ime, i u ovom slučaju izabrano je da to bude “Pet”. Onda se upisuje kôd koji se izvršava u okviru potprograma. U ovom slučaju, to je kašnjenje za program sa LED. Na kraju se potprogram završava RETURN instrukcijom. Da biste pozvali potprogram iz glavnog programa, jednostavno upišite CALL instrukciju i labelu početka potprograma. Kada glavni program dođe do dela sa instrukcijom CALL k (eng. Call Subroutine) “pozovi potprogram”, gde je k adresa ili labela potprograma, on skače na mesto na kojem se nalazi potprogram. Tamo nastavlja sa izvršavanjem komandi unutar potprograma sve do nailaska na instrukciju RETURN (eng. Return from Subroutine) “povratak iz potprograma”. Po nailasku na RETURN program nastavlja izvršavanje od instrukcije koja se nalazi iza CALL instrukcije. Možete pozvati potprogram koliko god puta želite, i zbog toga se korišćenjem potprograma smanjuje ukupna dužina programa. Ipak postoje dve stvari na koje morate obratiti pažnju. Prvo, u glavnom programu, svi registi moraju biti imenovani i inicijalizovani pre nego što se upotrebe. Oni se mogu imenovati u samom potprogramu, ili na početku glavnog programa. Najpraktičnije je imenovati ih na početku programa. Na taj način ćete znati da su su svi na istom mestu. Drugo, morate biti sigurni da će izvršavanje glavnog programa zaobići potprogram. Ukoliko stavite potprogram na kraj Vašeg programa i zaboravite da stavite instrukciju goto koja bi nastavila izvršavanje dalje od potprograma, program će nastaviti sa izvršavanjem i izvršiti i potprogram želeli Vi to ili ne. PIC ne pravi razliku između potprograma i glavnog programa. Ovde treba napomenuti i mogućnost istovremenog imenovanja više registara. To se izvodi „cblock“ i „endc“ direktivama. Ukoliko u programu imate dve promenljive, trebate ih pamtiti u dva registra opšte namene. Međutim, za veći broj registara, praktičnije je definisati ih unutar jednog bloka. Na taj način mikrokontroler preuzima obavezu određivanja adresa pojedinačnih registara (određujete mu samo prvu), i poboljšavate portabilnost programa za moćnije serije mikrokontrolera. Očigledno da ovo nije velika ušteda pri korišćenju samo dva registra. Međutim, pri više registara ovo može biti od pomoći. 21

Prepravite program za treperenje LED tako da koristi potprogram. ; ****** Inicijalizacija i imenovanje ****** list p=16F84 ; Definiše upotrebljeni mikrokontroler #include ; Ubacuje nazive registra u program __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC ; Podešava konfiguracione bitove. cblock 0x0C ; Početak slobodnih registara BROJAC1 ; Prvi brojač za petlju. Inicijalno 0xFF BROJAC2 ; Drugi brojač za petlju. Inicijalno 0xFF endc ; Kraj bloka registara ; ****** Podešavanje porta ****** org 0x00 bsf STATUS,RP0 movlw b'00000000' movwf TRISA movwf TRISB bcf STATUS,RP0 ; ****** Uključi LED ****** Poc movlw b'00000100' movwf PORTA

; Prebacuje program u BANK1 ; Postavlja sve pinove ; kao izlazne ; Vraća program u BANK0 ; Uključi LED stavljajući b'00100' ; u W registar, a zatim i u PORTA

; ****** Dodaj kašnjenje ****** call Pet ; ****** Kašnjenje završeno, sada isključi LED ****** movlw b'00000000' ; Isključi LED stavljajući b'00000' movwf PORTA ; u W registar, a zatim i u PORTA ; ****** Dodaj još jedno kašnjenje ****** call Pet ; ****** Sada se vrati na početak programa ****** goto Poc ; ****** Potprogram za kašnjenje od oko 0,2S ****** Pet decfsz BROJAC1,F ; Ove dve petlje služe za brojanje nadole od goto Pet ; 255 do 0, 255 puta, omogućavajući da decfsz BROJAC2,F ; se može primetiti kako LED treperi goto Pet return ; Povratak iz potprograma ; ****** Kraj programa ****** end

; Kraj programa.

Možete videti da je korišćenjem potprograma smanjena veličina programa. Svaki put kada je potrebno napraviti pauzu, bez obzira svetli li LED ili ne, pozove se potprogram. Na kraju potprograma program se vraća na red iza CALL instrukcije. 22

U primeru se najpre uključuje LED. Onda se poziva potprogram. Nakon povratka iz potprograma može se isključiti LED. Opet se poziva potprogram, i po povratku iz njega, izvršava se sledeća instrukcija, odnosno “goto Poc”. Bitno je napomenuti i to da je moguće pozivanje drugog potprograma unutar prvog. Na primer ovo je potpuno moguće: Pocetak

call Prog1 goto Pocetak

; Pozivanje prvog potprograma ; Neprekidno vraćanje na početak u mrtvoj petlji

Prog1

call Prog2 return

; Pozivanje drugog potprograma ; Povratak iz prvog potprograma

Prog2

return

; Povratak iz drugog potprograma

Ovako se može ići samo do osmog nivoa dubine na šta se mora obratiti pažnja. Za one koje interesuje, originalan program bio je dug 121 bajtova. Korišćenjem potprograma, smanjen je na 104 bajta. Ovo možda i ne izgleda mnogo, ali imajte u vidu da memorija PIC16F84 mikrokontrolera iznosi samo 1024 bajta. Svaki bajt je bitan. U sledećem poglavlju naučićete kako da PIC očita spoljne signale.

23

9. Ulazi Do sada ste samo pisali po portu A da bi se uključivala i isključivala LED. U ovom poglavlju naučićete upotrebu ulaznih pinova. Na taj način moguće je na pinove mikrokontrolera povezati spoljno elektronsko kolo, i programirati PIC da različito reaguje u zavisnosti od spoljnih signala. Kao što Vam je poznato, da bi konfigurisali U/I pinove treba prebaciti program iz banke 0 u banku 1. Najpre to uradite: bsf

STATUS,RP0

; Banka 1

Da bi se konfigurisao odgovarajući pin na portu A kao izlazni, treba poslati 0 na njemu odgovarajuće mesto u TRISA registru. Da bi se konfigurisao kao ulazni, treba poslati 1. movlw movwf bcf

b'00000001' ; Stavi b'00001' u W, a zatim u TRISA ; TRISA registar. Tako je pin RA0 ulazni. STATUS,RP0 ; Banka 0

Ovim je RA0 pin konfigurisan kao ulazni. Sada je potrebno proveriti da li je na njemu prisutan nivo logičke jedinice ili nule. Za ovo se koristi instrukcija BTFSC ili BTFSS. BTFSC f,b (eng. Bit Test f, Skip if Clear) instrukcija znači “Testiraj bit b registra f. Ako je bit jednak 0, preskoči sledeću instrukciju“. BTFSS f,b (eng. Bit Test f, Skip if Set) znači “Testiraj bit b registra f. Ako je bit jednak 1, preskoči sledeću instrukciju“. Koju instrukciju ćete koristiti zavisi od toga kako želite da program reaguje kada testirate željeni bit. Na primer, ukoliko čekate da se na ulaznom pinu javi nivo logičke 1, možete iskoristiti instrukciju BTFSS ovako: Početak programa Test

btfss PORTA,0 goto Test Nastavi odavde

Program će nastaviti izvršavanje od “Nastavi odavde” samo ukoliko je bit 0 PORTA registra setovan, odnosno ukoliko je na pinu RA0 prisutan nivo logičke 1 (+5V). Napišite sada program kojim će LED treptati jednom brzinom, a ukoliko se pritisne prekidač, ona će treptati duplo sporije. Možete probati da sami napišete ceo program, da biste videli da li ste shvatili postupak.

24

; ****** Inicijalizacija i imenovanje ****** list p=16F84 ; Definiše upotrebljeni mikrokontroler #include ; Ubacuje nazive registra u program __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC ; Podešava konfiguracione bitove. BROJAC1 equ 0x0C ; Prvi brojač petlje. Inicijalno 0xFF BROJAC2 equ 0x0D ; Drugi brojač petlje. Inicijalno 0xFF org 0x00 ; ****** Podešavanje porta ****** bsf STATUS,RP0 movlw b'00000001' movwf TRISA movlw b'00000000' movwf TRISB bcf STATUS,RP0

; Banka 1 ; Stavi b'00001' u TRISA. Tako je pin ; RA0 ulazni, a RA2 izlazni. ; Stavi b'00000000' u TRISB. Tako su ; svi pinovi izlazni. ; Banka 0

; ****** Uključenje LED ****** Poc movlw b'00000100' movwf PORTA

; Uključi LED stavljajući b'00100' u ; W registar, a zatim i u port A

; ****** Proveri da li je prekidač zatvoren ****** btfsc PORTA,0 ; Testiraj stanje bita 0 porta A. Ako je 0 ; preskoči prvu pauzu. Ako je 1 prođi kroz call Pet ; obe pauze, kao da se ništa ne događa ; ****** Dodavanje još jedne pauze ****** call Pet ; Ova pauza se uvek izvršava

25

; ****** Pauza završena. Sada isključi LED ****** movlw b'00000000' ; Isključi LED stavljajući b'00000' movwf PORTA ; u W registar, a zatim i u port A ; ****** Proveri da li je prekidač i dalje zatvoren ****** btfsc PORTA,0 ; Testiraj stanje RA0 pina. Ako je na logičkoj 0 ; preskoči prvu pauzu. Ako je na 1 prođi kroz call Pet ; obe pauze, kao da se ništa ne događa ; ****** Dodavanje još jedne pauze ****** call Pet ; Ova pauza se uvek izvršava ; ****** Pauza završena. Sada se vrati na početak ****** goto Poc ; Vrati se na početak ; ****** Potprogram za kašnjenje od oko 0,2S ****** Pet decfsz BROJAC1,F ; Ove dve petlje služe za brojanje nadole od goto Pet ; 255 do 0, 255 puta, omogućavajući da decfsz BROJAC2,F ; se može primetiti da LED treperi goto Pet return ; Povratak iz potprograma ; ****** Kraj programa ****** end

; Kraj programa.

Otpornik od 4k7Ω obavezan je da bi pin RA0 i pri otvorenom prekidaču bio u stabilnom logičkom stanju (logička 0). U protivnom, pin bi zbog svoje visoke ulazne impedanse postao previše osetljiv na spoljnje smetnje (npr. grmljavinu), ili bi pak neprestano bio u logičkoj 1 bez obzira na stanje prekidača. U praksi se umesto otpornika prema masi, češće sreće otpornik prema naponu napajanja. Više o potrebi za ovim (pull-up i pull-down) otpornicima naučićete u narednim poglavljima. Program najpre uključuje LED. Onda proverava da li je prekidač zatvoren. Ukoliko nije (na ulazu je logicka 0), program se izvršava kao da se ništa nije desilo, i prolazi kroz oba poziva za potprogram. Ukoliko jeste (na ulazu je nivo logičke 1), prvi poziv za potprogram se preskače, pa je pauza u tom slučaju ista kao kod ranije napisanih programa. Isto se dešava i nakon što se isključi LED. Možete kompajlirati i isprobati ovaj program. Ipak da Vas odmah upozorim. Kolo i program neće impresionirati nekog koga ne interesuje programiranje mikrokontrolera. Zato se nemojte uznemiravati kada svojoj porodici i prijateljima pokažete kako možete menjati brzinu treptanja LED prekidačem, a oni za to pokažu veoma malo interesovanja. Ukoliko ste iz početka pratili ova uputstva, onda biste možda voleli da znate da ste do sada naučili 10 od ukupno 35 instrukcija za PIC16F84! Sve su naučene uključivanjem i isključivanjem LED i testiranjem prekidača.

26

10. Simulator Simulacija je proces virtuelnog simuliranja izvršavanja instrukcija iako još ništa konkretno nije hardverski napravljeno. Jedan od najpopularnijih (i najjednostavnijih) simulatora je svakako PIC Simulator IDE. U njemu je dovoljno kliknuti na željeni pin mikrokontrolera da bi se logičko stanje na njemu promenilo. Nažalost, može se koristiti samo 30 dana pre isteka probnog perioda. Još jedan odličan simulator je Proteus. On pruža mogućnost integracije mikrokontrolera sa eksternim hardverom. Ni on nije besplatan. Besplatan je jedino Misim, ali nije dovoljno upotrebljiv. MPLAB IDE ima u sebi odličan a besplatan simulator. U ovom poglavlju biće opisane njegove specifičnosti. Da biste uključili simulator idite na Debugger, Select Tool, MPLAB SIM. U toolbaru će se pojaviti nekoliko novih ikonica. Kliknite na treću (Animate - dve strelice nadesno) i pratite izvršavanje programa u prozoru sa .asm fajlom. Vidite kako je došao do petlje i kako neprestano izvršava dve iste instrukcije. Na drugoj ikoni (Halt) pauzirate program. Na prvoj (Run - jedna strelica nadesno) se program izvršava maksimalnom brzinom, ali bez animiranosti njegovog izvršavanja. Četvrtom ikonom (Step Into) se kada je program u pauziranom stanju vrši prelaz na sledeću instrukciju, korak po korak. Petom (Step Over) se maksimalnom brzinom izvršava potprogram ili naredna instrukcija. Šestom ikonom (Step Out) nasilno se izlazi iz potprograma. Zadnjom ikonom se vrši reset programa, i tako njegovo izvršavanje može početi iz početka. Registri opšte namene pri tome zadržavaju svoje vrednosti. Da biste videli aktuelni sadržaj registara BROJAC1 i BROJAC2 možete zadržati miš iznad njih, ili ići na View, File Registers. U prozoru koji se otvorio možete videti da se registar na adresi 0x0C (koja je izabrana za BROJAC1) u koracima smanjuje do 0. Kada dostigne 0, smanjuje se BROJAC2 na adresi 0x0D. Verovatno će Vam lakši biti prikaz labela, a ne adresa. Promenite prikaz klikom na „Symbolic“ tab. Donji deo MPLAB prozora pruža Vam korisne informacije o trenutnom stanju banke, W registra i pojedinih bitova STATUS registra. Velika slova Z, DC i C pri dnu ekrana označavaju da su ti bitovi setovani. Upotrebu ovih bitova naučićete kasnije. Detaljnije praćenje promena registara, možete uključiti preko View, Watch opcije. Osenčite željeni registar, i prevucite ga u Watch prozor. Desnim klikom preko registra unutar Watch prozora i izborom opcije Properties dobijate mogućnost podešavanja željenog formata brojeva. Za BROJAC1 i BROJAC2 najpregledniji bi bio decimalni format. Duplim klikom na vrednosti pored registara, možete ih nasilno promeniti. Možda vam je animacija brzine izvršavanja programa previše spora? Povećajte je na Debugger, Settings, Animation / Realtime Updates pod Animate step time. Umesto 500mS stavite npr. 50. Brzina simuliranja ograničena je brzinom vašeg kompjutera. 27

Ukoliko Vas interesuje realna brzina (eng. Real Time) kojom bi program radio, možete je proveriti preko Debugger, Stopwatch (eng. stopwatch – štoperica) opcije. Dovoljno je izabrati brzinu oscilatora u Debugger, Setings, Osc / trace opciji. Za date vrednosti RC oscilatora (10kΩ i 33pF), ona je oko 3,5MHz. Nekada nema svrhe čekati da se završi određeni proces (npr. prazna petlja). MPLAB simulator Vam omogućava da u programu postavite tačke prekida (eng. Breakpoint) duplim klikom na željenu instrukciju. Crvena oznaka B pojavljuje se leve strane prozora editora. Čim simulator naiđe na taj deo, zaustaviće dalju simulaciju što će Vam omogućiti pregled stanja registara ili proračun vremena (preko štoperice) potrebnog za izvršavanje instrukcija. Upotreba štoperice može biti izuzetno korisna. Na primer da biste tačno odredili vreme za koje je LED aktivna, dovoljno je postaviti jednu tačku prekida na call instrukciju. Onda se program izvrši (Run - bez animiranja) do prve tačke prekida, i tu se resetuje štoperica i klikne na Step Over. Potprogram se izvršava maksimalnom brzinom (bez animiranja) i nakon što se završi iščita se proteklo vreme iz štoperice. Iako je prikaz svih izlaznih pinova portova veoma lako implementirati, ukoliko je potrebno simulirati program koji treba reagovati na signale sa ulaznih pinova (tipa pritisnut prekidač T1) stanje se iz osnova menja. Da bi to bilo moguće mora se definisati određeni stimulans (eng. Stimulus) po kome će se odvijati promene. Željeni scenario promena definišete sa Debugger, Stimulus Controller, New Scenario. Na primer, ukoliko je prekidač na RA0 pinu svo vreme pritisnut (a pin je definisan kao ulazni), potrebno je izabrati asinhroni (Asynch) tab, a zatim u jednom od redova ubaciti RA0 i Set High akciju. Da bi se menjalo ulazno stanje određenog pina potrebno je izabrati željeni pin (npr. isto RA0) i Toggle akciju. Pri njoj se klikom na Fire polje pored željenog pina menja njegovo logičko stanje, što možete pratiti u File Registers ili Watch prozoru. Ukoliko je potrebno da pin u određenom logičkom stanju bude tačno određeno vreme, možete izabrati Pulse High ili Pulse Low akciju. U tom slučaju trebate odrediti i željenu dužinu impulsa datu u vremenu ili broju instrukcijskih ciklusa. Početak impulsa se takođe određuje klikom na Fire polje pored željenog pina. U asinhronom tabu potrebno je u željenom trenutku fizički kliknuti na polje za pokretanje određenih opcija. U Register Injection tabu željeni trenutci promene stanja pinova (bitova) mogu se definisati eksternim fajlom, a u Register Trace tabu može se definisati eksterni fajl koji će snimati stanje određenih bitova po unapred zadatim kriterijumima. Clock Stimulus tabom definišu se logička stanja pinova koja će se javljati u tačno određenim trenutcima. Za složenija stanja, morao bi se koristiti Register Injection tab. Pin / Register Actions i Advanced Pin / Register tabovima definišu se složenije akcije koje će se odvijati po promeni ili dostizanju unapred zadatog stanja bita ili registra. Za početak, koristite jedino asinhroni tab. U sledećem poglavlju naučićete kako se programska memorija mikrokontrolera može efikasnije iskoristiti.

28

11. Efikasno korišćenje memorije Do sada ste programirali PIC da uključuje i isključuje LED. Onda ste upravljali njegovim radom dodavši mu prekidač, i menjajući brzinu treptanja diode. Jedini problem je u tome što je program bio dugačak, i bespotrebno je trošio memoriju. Da bi ga skratili trebate naučiti još par instrukcija. CLRW instrukcija postavlja vrednost 0x00 u W, a CLRF f u željeni registar. Tako umesto movlw b'00000000' movwf TRISB možete pisati clrw movwf TRISB ili clrf TRISB Hajde da vidimo kako ste do sada uključivali i isključivali LED. movlw movwf movlw movwf

b'00000100' PORTA b'00000000' PORTA

Najpre je ubačena vrednost 0x04 u W registar, zatim je prosleđena na PORTA da bi se uključila LED. Da bi se isključila obrisan je W registar, i ponovo je njegova vrednost prosleđena na PORTA. Između ovih rutina pozivan je potprogram za kašnjenje da bi se moglo primetiti da LED treperi. Znači dva puta su prebacivana 2 seta podataka (jednom u W registar, a onda u PORTA) i dva puta je pozivan potprogram (jednom nakon uključenja i jednom nakon isključenja LED). Kako se ovo može efektnije rešiti? Koristeći logičku operaciju zvanu XOR. XOR (eng. Exclusive Or) operacija izvršava logičku operaciju “ekskluzivno ili” na registru koji odredite, sa vrednošću koju mu date. Trebalo bi ovo malo bolje objasniti. XOR 0

0

0

0

1

1

1

0

1

1

1

0

00101110 XOR 10010110 = 10111000 Rezultat XOR operacije će biti logička 1 samo ukoliko su mu oba operanda različita. Ukoliko su ista (obe 0 ili obe 1), rezultat će biti logička 0.

XOR (kao i sve ostale logičke instrukcije) se može izvršiti jedino nad celim bajtovima, pri čemu se vodi računa o njihovom položaju. LSB bit rezultata sadržaće rezultat XOR operacije nad LSB bitovima prvog i drugog operanda.

29

Uočavate li da XOR operacijom nad bitom koji je stalno na logičkoj 1 i prethodnim stanjem bita menja stanje rezultata sa 0 na 1 i sa 1 na 0? I 00000000 XOR 00000001 = 00000001

II 00000001 XOR 00000001 = 00000000

Ta specifičnost XOR operacije može biti iskorišćena za naizmenično uključivanje i isključivanje LED. Još jedna interesantna osobina XOR operacije je da bilo koja vrednost dva puta XORovana istim brojem vraća originalnu vrednost. I 00101110 XOR 10010110 = 10111000

II 10111000 XOR 10010110 = 00101110

XOR operacija može se naći u instrukcijama PIC16F84 u dva oblika. 1. XORLW k gde se XOR operacija izvršava nad W i konstantnom vrednošću k. Vrednost k mora biti u opsegu od 0 do 255 (0x00 – 0xFF). Rezultat operacije će biti u W registru. 2. XORWF f,d gde se XOR operacija izvršava nad W i vrednosti unutar registra čija je adresa označena sa f. Sa „d“ je označeno gde će biti smešten rezultat XOR operacije. Ukoliko je d=0, rezultat će biti u W registru, a ukoliko je d=1, rezultat će biti smešten u f registru. Upotrebom ove instrukcije su za naizmenično uključenje i isključenje LED dovoljne samo dve linije kôda: movlw xorwf

b'00000100' PORTA,F

; b'00000100' u W ; Promeni stanje bita 2 u PORTA registru

Ovde je vrednost 0x04 (b'00100') XOR-ovana sa ranijim sadržajem porta A. Ukoliko je bit 2 u portu A bio 1, postaće 0, a ukoliko je bio 0 postaće 1. Čak nema ni potrebe za inicijalizacijom vrednosti u portu A. Zbog čega? Pa ukoliko je njegov bit 2 bio 0, promeniće se. Ukoliko je bio 1, opet će se promeniti. Međutim, nedostatak inicijalizacije porta A može uticati na stanje ostalih pinova, tako da je ona svakako preporučljiva. Iako je direktna manipulacija nad portovima sasvim moguća, direktno menjanje PORTA (ili PORTB) registra ne spada u dobru programersku praksu. Zbog čega? Zbog internog RMW (eng. Read Modify Write) ciklusa mikrokontrolera. RMW ciklus znači da mikrokontroler prilikom promene stanja nekog od bitova odgovarajučeg registra najpre očita ceo registar (svih 8 bitova), zatim izvrši željenu operaciju nad njim, i na kraju vrati rezultat u taj isti registar. 30

Zamislite da je korisnik rešio da izvuče LED na neko udaljenije mesto (kao što mnogi izvlače signalizaciju jeftine struje sa strujomera). Kablovi preko kojih je povezana LED ponašaju se usled svoje velike dužine i male daljine jedan od drugog kao kondenzator male kapacitivnosti. Zato je ukoliko želite brzo uključiti i isključiti LED moguće da ona neposredno nakon uključenja ne zasvetli zbog previše male otpornosti na njenim vodovima (dok se takav virtuelni kondenzator ne napuni). Ukoliko odmah po uključenju očitate stanje sa PORTB registra, videćete da LED i dalje nije uključena. PORTB (i PORTA) se pri očitavanju stanja ponašaju kao da su povezani kao ulazi, bez obzira na ranije konfigurisano stanje pinova. To može dovesti do očitavanja pogrešnog stanja, a samim tim i nepravilnog rada programa. PIC je hardverski konstruisan tako da je moguće čak i da se očitavanje stanja sa portova može završiti i pre ranije zadate promene njihovih stanja. Zbog toga je pouzdanije sve operacije izvršavati nad određenim registrom opšte namene (obično se taj registar naziva shaddow registar (eng. Shaddow – senka)), a tek onda kada je to neophodno kopirati rezultat iz njega u odgovarajući port. Više o shaddow registrima možete naučiti na http://www.piclist.com/tecHREF/readmodwrite.htm sajtu. Pogledajte sada novi asemblerski kôd. Prvi je originalni program za treperenje LED, a u drugom je dodat prekidač. U oba programa kao shaddow registar upotrebljen je W registar, jer se njegovo stanje ne menja u ostalim delovima programa. Da se menja, koristio bi se neki od registara opšte namene. Treptuća LED ; ****** Inicijalizacija i imenovanje ****** list p=16F84 ; Definiše upotrebljeni mikrokontroler #include ; Ubacuje nazive registra u program __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC ; Podešava konfiguracione bitove. BROJAC1 equ 0x0C ; Prvi brojač petlje. Inicijalno 0xFF BROJAC2 equ 0x0D ; Drugi brojač petlje. Inicijalno 0xFF org 0x00 ; ****** Inicijalizacija i podešavanje porta ****** bsf STATUS,RP0 ; Banka 1 clrf TRISA ; Postavlja sve pinove clrf TRISB ; kao izlazne. bcf STATUS,RP0 ; Banka 0 clrw ; W je inicijalizovan na 0x00 ; ****** Uključenje i isključenje LED ****** Poc xorlw b'00000100' ; Promeni stanje bita 2 u W registru movwf PORTA ; Kopiraj W u PORTA ; ****** Pauza ****** call Pet ; ****** Pauza završena. Vrati se na početak programa ****** goto Poc ; Vrati se na početak

31

; ****** Potprogram za kašnjenje od oko 0,2S ****** Pet decfsz BROJAC1,F ; Ove dve petlje služe za brojanje nadole od goto Pet ; 255 do 0, 255 puta, omogućavajući da se decfsz BROJAC2,F ; može primetiti kako LED treperi goto Pet return ; Povratak iz potprograma ; ****** Kraj programa ****** end

; Kraj programa

Treptuća LED sa prekidačem ; ****** Inicijalizacija i imenovanje ****** list p=16F84 ; Definiše upotrebljeni mikrokontroler #include ; Ubacuje nazive registra u program __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC ; Podešava konfiguracione bitove. BROJAC1 equ 0x0C ; Prvi brojač petlje. Inicijalno 0xFF BROJAC2 equ 0x0D ; Drugi brojač petlje. Inicijalno 0xFF org 0x00 ; ****** Podešavanje porta ****** bsf STATUS,RP0 movlw b'00000001' movwf TRISA clrf TRISB bcf STATUS,RP0 clrw

; Banka 1 ; Stavi b'00001' u TRISA. Tako je bit 0 ; porta A ulazni, a bit 2 izlazni. ; Svi pinovi na portu B su izlazni. ; Banka 0 ; W je inicijalizovan na 0x00

; ****** Uključenje i isključenje LED ****** Poc xorlw b'00000100' ; Promeni stanje bita 2 u W registru movwf PORTA ; Kopiraj W u port A ; ****** Proveri da li je prekidač zatvoren ****** btfsc PORTA,0 ; Uzmi vrednost sa pina RA0. Ukoliko je 0 ; preskoči prvu pauzu. Ukoliko je 1 prođi kroz call Pet ; obe pauze, kao da se ništa ne događa ; ****** Dodavanje još jedne pauze ****** call Pet ; Ova pauza se uvek izvršava ; ****** Pauza završena. Vrati se na početak programa ****** goto Poc ; Vrati se na početak

32

; ****** Potprogram za kašnjenje od oko 0,2S ****** Pet decfsz BROJAC1,F ; Ove dve petlje služe za brojanje nadole od goto Pet ; 255 do 0, 255 puta, omogućavajući da se decfsz BROJAC2,F ; može primetiti kako LED treperi goto Pet return ; Povratak iz potprograma ; ****** Kraj programa ****** end

; Kraj programa

Nadam se da ste uočili da je upotrebom novih instrukcija prilično smanjena veličina programa. Da biste lakše uočili ovu razliku, ispod su prikazni nazivi programa, izmene koje su izvršene, i njihove veličine. Program Treptuća LED Treptuća LED Treptuća LED LED sa prekidačem LED sa prekidačem

Izmena

Veličina (instrukcija)

Original Dodat potprogram Dodata ekskluzivno ili funkcija Original Dodata ekskluzivno ili funkcija

18 17 14 22 17

Vidite da ste ne samo naučili nove instrukcije, već ste i smanjili veličinu programa.

33

12. Logičke operacije Jednu logičku operaciju (XOR) ste već naučili. Sada ćete se upoznati sa još tri. AND „logičko I“ operacija daće na svom izlazu logičku 1 samo ukoliko su joj na oba ulaza dovedene logičke 1. Ovde je njena tablica istinitosti. 01101011 AND 10100101 = 00100001

AND 0

0

0

0

1

0

1

0

0

1

1

1

Rezultat AND operacije biće logička 1 samo ukoliko su oba operanda na logičkoj 1. Ukoliko bar jedan nije, rezultat će biti logička 0.

Kao i XOR i AND operacija se može naći u dva oblika. 1. ANDLW k koja izvršava AND operaciju nad registrom W i konstantnom vrednošću k. Rezultat operacije će biti u W registru. 2. ANDWF f,d koja izvršava AND operaciju nad vrednošću W i vrednošću f registra. Sa „d“ je označeno gde će biti smešten rezultat operacije. Ukoliko je d=0, rezultat će biti u W registru, a ukoliko je d=1, rezultat će biti u f registru. Sledi IOR operacija: 01101011 IOR 10100101 = 11101111

IOR 0

0

0

0

1

1

1

0

1

1

1

1

Rezultat IOR operacije biće logička 1 ukoliko je bar na jednom operandu prisutna logička 1. Ukoliko su oba na logičkoj 0, i rezultat će biti jednak logičkoj 0.

I ona se javlja u dva oblika. 1. IORLW k koja izvršava IOR operaciju nad registrom W i konstantnom vrednošću k. Rezultat operacije će biti u W registru. 2. IORWF f,d koja izvršava IOR operaciju nad vrednošću W registra i f registra. Ukoliko je d=0, rezultat će biti u W registru, a ukoliko je d=1, rezultat će biti u f registru. Zadnja logička operacija koju podržava PIC16F84 je komplement. COM 0

1

1

0

COM 01101011 = 10010100 Komplement, negacija ili invertovanje je logička operacija u kojoj svaki bit unutar bajta menja svoje stanje. 34

Za razliku od ostalih logičkih operacija komplemen se izvršava nad samo jednim bajtom. Zbog toga ova operacija ima samo jedan oblik instrukcije. COMF f,d instrukcijom se invertuju svi bitovi u registru f. Ukoliko je d=0 rezultat će biti u W, a ukoliko je 1 u f registru. Verovatno uočavate da ste ovu logičku operaciju mogli upotrebiti u ranijem programu umesto XOR. Jedina razlika je u tome što bi se onda invertovali svi bitovi PORTA registra, a ne samo onaj koji je potreban. Slično kao XOR operacija, duplo komplementovana vrednost vraća originalnu: I COM 01101011 = 10010100

II COM 10010100 = 01101011

Sve do sada naučene logičke operacije menjaju vrednost bita 2 STATUS registra u slučaju da je rezultat njihove operacije jednak nuli. Kako je bit 2 po tome specifičan on ima svoju posebnu oznaku „nulti bit“ (eng. Zero flag). Termin „flag“ koristi se za označavanje bitova koje mikrokontroler sam setuje ili resetuje u zavisnosti od svog trenutnog stanja (u ovom slučaju rezultata prethodne logičke instrukcije). Dakle ukoliko je rezultat XOR operacije sledeći: XOR =

00011010 00011010 00000000

Zero flag STATUS registra će biti setovan. Ovo se može iskoristiti za brzo poređenje vrednosti u registru tako što se u W registar postavite željeni oblik bitova a onda izvrši XOR operaciju nad njim i željenim registrom. Ukoliko je stanje unutar registra jednako stanju u W registru, Zero flag će biti setovan. Iako nema mnogo smisla Zero flag možete setovati čak i operacijom komplementovanja. COM =

11111111 00000000

U prilogu ovog uputstva možete videti uporedni prikaz instrukcija u kome je navedeno koje sve instrukcije menjaju stanje Zero flaga.

35

13. Rotacija RLF (Rotate Left f Through Carry) instrukcija rotira ulevo bitove unutar zadatog registra. Sintaksa instrukcije je sledeća: RLF f,d pri čemu je f registar nad čijim sadržajem se obavlja rotacija. Ukoliko je d=0, rezultat operacije će biti u W registru, a ukoliko je d=1, rezultat će biti u registru f. Šta radi ova instrukcija? Ukoliko npr. u registru 0x0C imate vrednost b'00011001' nakon instrukcije RLF 0x0C,F registar 0x0C će dobiti vrednost b'00110010'. Nakon još jedne iste instrukcije u registru će biti vrednost b'01100100'. Kao što vidite ova instrukcija rotira sadržaj registra ulevo. A šta kada 1 dođe do kraja – pitate se vi. Neće se izgubiti. Za vreme rotacije ulevo MSB se smešta se u tzv. “bit prekoračenja” (eng. Carry flag). On se nalazi na mestu bita 0 STATUS registra.

Dakle kada jedinica dođe do kraja, događa se sledeće:

rlf rlf rlf rlf rlf .

0x0C,F 0x0C,F 0x0C,F 0x0C,F 0x0C,F .

Carry flag 0 0 1 0 0

Bitovi 0x0C registra 76543210 01000000 10000000 00000000 00000001 00000010 .

Vidite da je Carry flag ovde iskorišćen kao osmi bit registra. Ukoliko vam je to potrebno možete ubaciti 0 ili 1 u Carry flag pre rotacije instrukcijama bsf STATUS,C i bcf STATUS,C (C je imenovani bit 0 STATUS registra). Tako će se vrednost iz Carry flaga pojaviti na bitu 0 nakon rlf instrukcije. Preporučljivo je ovo uraditi neposredno pre rotacije kako na bitu 0 nakon rotacije ne bi dobili nepoznatu vrednost. Ne utiče samo RLF instrukcija na Carry flag. Interensantno je da se rotacijom ulevo (sa prethodno resetovanim Carry flagom) broj unutar registra množi sa 2. C 0 0 1

76543210 01011001 10110010 01100100

= = =

89 178 356 (računajući i Carry flag)

Ukoliko vam je potrebno množenje sa 2 većih brojeva možete koristiti uzastopnu rotaciju dva ili više registra. Carry flag iz prvog registra preneće se na početak drugog. Kada već postoji instrukcija za rotaciju ulevo, logično bi bilo da postoji i instrukcija za rotaciju bitova udesno. Postoji! 36

RRF (Rotate Right f Through Carry) Sintaksa instrukcije je ista kao i kod RLF. Kako se rlf instrukcijom sadržaj u registru množi sa 2, rrf instrukcijom (i resetovanim Carry flagom) se sadržaj registra deli sa 2. LSB se premešta u Carry flag po sledećem:

rrf rrf rrf rrf

0x0C,F 0x0C,F 0x0C,F 0x0C,F

Carry flag 0 0 1 0

Bitovi 0x0Ch registra 76543210 00000010 00000001 00000000 10000000

Instrukcije RLF i RRF mogu se upotrebiti za simulaciju trčećeg svetla. U tom slučaju mogući algoritam bi bio: SPORTB equ rlf movf movwf

0x0C SPORTB,F SPORTB,W PORTB

; Rotacija u SHADDOW registru ; Kopiranje iz SHADDOW u W ; Kopiranje iz W u PORTB.

Instrukcija movf f,d. (eng. Move f) vrednost iz registra f prebacuje u W (pri d=0) ili u taj isti registar f (pri d=1). Zbog čega bi iko želeo da sadržaj registra upiše u taj isti registar? U praksi se ta mogućnost koristi jedino pri testiranju sadržaja registra na vrednost 0x00, jer movf instrukcija utiče na Zero flag. Sledećom šemom ilustrovana je upotreba logičkih i instrukcija rotacije:

37

Upotreba logičkih i instrukcija rotacije ; ****** Inicijalizacija i imenovanje ****** list p=16F84 ; Definiše upotrebljeni mikrokontroler #include ; Ubacuje nazive registra u program __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC ; Podešava konfiguracione bitove. DATA equ 0x0C ; Registar za privremene podatke org 0x00 ; ****** Podešavanje porta ****** bsf STATUS,RP0 movlw b'00000011' movwf TRISA clrf TRISB bcf STATUS,RP0

; Prebacuje program u BANK1 ; Stavi b'00011' u TRISA. Tako su bit 0 i ; bit 1 ulazni, a bit 2 izlazni. ; Svi pinovi na PORTB su izlazni. ; Vraća program u BANK0

; ****** Testiranje prekidača ****** Poc rlf PORTA,W ; Rotiraj sadržaj PORTA i stavi rezultat u W ; registar, Tako je bit 0 došao na mesto bita 1 xorwf PORTA,W ; Izvrši XOR nad PORTA i W registrom, ; i stavi rezultat u W (interesuje nas ; XOR nad bitom 1 ova dva registra). ; ****** Prebacivanje rezultata na izlaz ****** movwf DATA ; Premesti sadržaj iz W u DATA jer se rotacija ; ne može izvršiti direktno nad W registrom rlf DATA,W ; Rotiraj sadržaj. Tako je bit 1 došao na mesto ; bita 2 (na mesto izlaznog bita) i vrati rezultat ; u W registar. movwf PORTA ; Stavi rezultat u PORTA. Kako su bit 0 i bit 1 ; ulazni, neće reagovati, a na bitu 2 će se ; pojaviti rezultat XOR operacije nad ; postavljenim stanjem prekidača. goto Poc ; Povratak na početak. ; ****** Kraj ****** end

; Kraj programa.

Kompajlirajte program, programirajte PIC i isprobajte njegov rad. Iz komentara se može lako zaključiti šta program radi. Evo šta će se dogoditi u programu u slučaju da su oba prekidača zatvorena: PIC uzima vrednost iz PORTA. Kako su oba tastera pritisnuta ona je b'00011'. Ta vrednost se rotira, i postaje b'00110'. Rezultat se smešta u W registar. Dalje se izvršava ekskluzivno ili nad tom vrednošću i trenutnom vrednošću PORTA koji je i dalje b'00011'.

38

Sada se rezultat b'00101' prebacuje u privremeni registar DATA gde se rotira. Rotirana vrednost je b'01010', i ona se preko W registra smešta u PORTA. Kako su na PORTA bit 0 i bit 1 ulazni, vrednost koja će doći na njih biće ignorisana, a bit 3 nas ionako ne interesuje i njegova vrednost se može ignorisati. Kao što vidite na kraju svega bit 2 sadrži vrednost XOR operacije (u ovom slučaju 0). Kako je ovaj bit izlazni, LED neće svetleti. Možete proveriti rezultat funkcije pritiskanjem prekidača po tablici XOR operacije. Program je napisan tako da inicijalna vrednost Carry flaga nema uticaja na njegovo izvršavanje, pa njegovo brisanje ovde nije potebno. bitovi PORTA W posle rotacije PORTA W posle XOR PORTA posle rotacije

43210 00011 00110 00011 00101 01011

Kako je ovaj program dat kao ilustracija korišćenja instrukcija nema potrebe za ograničenjem setovanja bita 3 PORTA registra. U praksi taj pin ne bi bio povezan, ili bi se bit 3 „maskirao“. Prepravite sada program po sledećem: Umesto napišite

xorwf andwf

PORTA,W PORTA,W

; Izvrši XOR nad PORTA i W ; Izvrši AND nad PORTA i W

Program radi isto što i ranije, s tom razlikom što umesto XOR primenjuje AND operaciju. Pritiskanjem prekidača možete videti da će LED svetleti jedino ukoliko su oba prekidača (T1 i T2) zatvorena (na oba ulaza dovedena logička jedinica). Ukoliko u programu zamenite instrukciju ANDWF instrukcijom IORWF možete isprobati rad ove operacije. LED1 će svetleti ukoliko je uključen bar jedan prekidač. A ukoliko upotrebite COMF instrukciju, LED će svetleti suprotno od stanja prekidača T1 ignorišući stanje prekidača T2. Do sada ste naučili 22 od 35 instrukcija. Čestitamo. To je više od polovine.

39

14. Brojanje i sabiranje Već ste videli kako PIC16F84 može množiti i deliti sa dva u binarnom brojnom sistemu. Sada ćete naučiti kako može brojati unapred i unazad kao i sabirati. INCF (eng. Increment f) instrukcija služi za inkrementaciju. Njen oblik je: INCF f,d pri čemu d određuje gde će ići rezultat (u W ili F). Ovom instrukcijom se vrši povećanje sadržaja registra f za 1. Ukoliko je npr. vrednost registra opšte namene 0x0Ch bila 0x00, nakon instrukcije inc 0x0C,F njegova vrednost će postati 0x01, a nakon sledeće iste instrukcije 0x02. A šta će biti kada se dođe do 0xFF - pitate se vi. Odmah ćete videti.

incf 0x0C,F incf 0x0C,F incf 0x0C,F

Bitovi 76543210 11111110 11111111 00000000 00000001

STATUS Zero flag 0 0 1 0

Ukoliko vam je potrebna inkrementacija do većih vrednosti možete detektovati stanje Zero flaga, i onda pokrenuti sledeći registar za inkrementaciju. Ili za još veće brojeve možete kao u primeru sa praznom petljom staviti petlju unutar petlje. Instrukcija suprotna ovoj je DECF f,d (eng. Decrement f). Ova instrukcija smanjuje vrednost registra f za 1, odnosno dekrementuje ga. Sintaksa joj je ista kao kod INCF instrukcije. U slučaju da brojač dođe do 0 desiće se sledeće:

decf 0x0C,F decf 0x0C,F decf 0x0C,F

Bitovi 76543210 00000001 00000000 11111111 11111110

STATUS Zero flag 0 1 0 0

Dva specijalna oblika ovih instrukcija su: DECFSZ f,d koju ste već naučili u praznoj petlji i INCFSZ f,d (Increment f, Skip if zero) koja povećava sadržaj registra f za 1 po istom principu kao INCF instrukcija, i koja preskače sledeću instrukciju u slučaju da je rezultat operacije jednak 0. Poc

incfsz 0x0C,F goto Poc

; Povećaj vrednost u registru 0x0C za 1, ; i vrati se na početak. Ukoliko se nakon povećanja ; dobije 0, preskoči goto instrukciju i nastavi dalje.

Nastavi odavde Ove instrukcije za razliku od običnih INCF i DECF ne utiču na Zero flag.

40

ADD (eng. saberi) operacija sabira dva broja. Pogledajte kako se izvršava operacija sabiranja u binarnom brojnom sistemu: ADD 0

0

0

0

1

1

1

0

1

1

1

10

ADD =

C 1

11001101 10111000 10000101

.205 .184 .389

Prilikom sabiranja dve logičke 1 javlja se prenos u bit veće težine. Ukoliko ni MSB nije dovoljan za prenos, setovaće se Carry flag.

Kod ovakvih slučajeva bit prekoračenja smešta se u Carry flag. Ukoliko je potrebno sabirati brojeve čiji zbir može biti veći od 255, Carry flag mora se uzeti u obzir pri prenosu u bajt veće težine. U instrukcijama za PIC operacija sabiranja ima dva oblika: ADDLW k sabira sadržaj W registra i konstantne vrednosti k. Rezultat će se naći u W registru. ADDWF f,d sabira sadržaj W registra i registra f. Sa d se određuje gde će se naći rezultat. Aritmetičke operacije sabiranja (i oduzimanja) pored Carry i Zero flaga utiču još i na tzv. DC flag (eng. Digit Carry), odnosno bit 1 STATUS registra. On će biti setovan pri prekoračenju donjeg četvorobitnog dela bajta (tzv. nibla). Menja se po istom principu kao i Carry flag. C DC ADD = 1 1

1111 1111 0000 0001 0000 0000

ADD =

C DC 0000 1111 0000 0001 0 1 0001 0000

Deljenje bajta na niblove ima smisla ukoliko je potrebno jednim niblom prikazivati jednu cifru, a drugim drugu (npr u digitalnom časovniku za minute gornji nibl od 0 do 5, a donji od 0 do 9). Uvećanje samo gornjeg nibla rešava se sabiranjem sa b'00010000'.

41

15. Negativni brojevi i oduzimanje Kod negativnih brojeva uzeto je pravilo da bit najveće težine (eng. Most Signle Bit – kod osmobitnih brojeva bit 7) predstavlja znak minus. Ukoliko je MSB setovan, broj je negativan. Pošto mikrokontroler koristi jedino 0 i 1 za predstavljanje brojeva, postavlja se logično pitanje kako predstaviti negativne brojeve. Osnovna ideja je invertovanje svih bitova unutar bajta. (to bi bio obični, odnosno prvi komplement). Međutim, ovaj princip ima tu manu što se nula može predstaviti dvojako (00000000 i 11111111). Stoga je praktičniji način invertovanje svih bitova i dodavanje broja 1. +1 = 00000001 +0 = 00000000

-1 = 11111110+1 = 11111111 -0 = 11111111+1 = 00000000

Kao što vidite, ovako postoji samo jednostruko predstavljanje broja 0. Takav postupak naziva se drugi komplement ili komplement dvojke. Računanje drugog komplementa broja može se izvršiti sledećim algoritmom: comf BROJ,F incf BROJ,F

; Prvi komplement ; Dodaj broj 1

Ručno pretvaranje pozitivnih u negativne brojeve najlakše možete izvršiti računajući drugi komplement broja. Računanje će vam biti utoliko lakše ukoliko se prisetite običnog komplementovanja (ili invertovanja ako vam je tako lakše). Drugi komplement predstavlja običan komplement kome je dodat broj 1. COM 01011011 10010000 + 1 = 10100101

+.91 -.91

Kao što vidite, MSB ima ulogu znaka (0-pozitivan, 1-negativan). Za prikazivanje rezultata ostaje vam još 7 bitova, tako da se unutar osmobitnog bajta mogu naći pozitivni (0 do 127) i negativni (-1 do -128) brojevi. Ovakvi brojevi nazivaju se označenim, za razliku od običnih neoznačenih (0-255) brojeva. Zato je bitno unapred odrediti da li ćete raditi sa označenim ili neoznačenim brojevima. Granice označenih brojeva ne smeju se prekoračiti, jer PIC ne pravi razliku između označenih i neoznačenih brojeva, pa može doći do netačnog rezultata operacije. Operacija suprotna sabiranju je SUB (eng. Substract) „oduzmi“. Oduzimanje se unutar mikrokontrolera izvršava upravo sabiranjem prvog broja sa komplementom dvojke drugog broja. Za razliku od sabiranja, kod koga se Carry flag setuje pri prekoračenju, kod oduzimanja je primenjena negativna logika, tako da je Carry flag setovan ukoliko nema prekoračenja (tačnije pozajmice). Znači kod oduzimanja manjeg broja od većeg (i u slučaju da su brojevi jednaki), Carry flag će biti setovan. Njegovo stanje se tada treba ignorisati. Pogledajte to na sledećem primeru: 100-55. 42

+.100 +(-.55) = +.45

C

01100100

1

11001001 00101101

+.55 -.55

00110111 11001001

Kod oduzimanja većeg od manjeg broja, prilikom sabiranja sa komplementom dvojke nema prekoračenja, pa se Carry flag ne setuje. Pogledajte to na primeru: 56-87. +.56

C

00111000

+(-.87) = -.31

0

10101001 11100001

+.87 -.87

01010111 10101001

Testiranjem MSB možete utvrditi da li je označeni rezultat pozitivan ili negativan, a testiranjem Zero flaga da li je rezultat 0. Isto kao i sabiranje, i instrukcija za oduzimanje može se javiti u dva oblika. SUBLW k oduzima sadržaj W registra od konstantne vrednosti k. Rezultat će se naći u W registru. SUBWF f,d oduzima sadržaj W registra od registra f. Sa d se određuje gde će se naći rezultat. Ukoliko Vam je oduzimanje i testiranje Carry flaga naporno, uradite isto što i mikrokontroler. Saberite jedan broj sa drugim komplementom dvojke drugog broja. Ukoliko se rotacijom izvršava množenje ili deljenje sa 2 nad označenim brojevima, obavezno se mora obratiti pažnja na MSB, jer on označava pripadnost pozitivnim, odnosno negativnim brojevima. U praksi se retko kada sreće potreba za primenom označenih brojeva. Skoro sve operacije izvršavaju se nad neoznačenim brojevima. Označeni brojevi mogli bi imati primenu u funkciji mikrokontrolera kao termometra, kada je potrebno izmeriti i prikazati temperature iznad i ispod nule.

43

16. Dekapling, debouncing, šmitov okidač, pull up otpornici... Imate PIC16F84 mikrokontroler. Unutar njega sve je digitalno. On razume jedino logičku 0 i logičku 1, odnosno naponske nivoe od 0V i +5V. Međutim, ponekad se dogodi da mu se umesto ovih napona dovedu naponi koji odstupaju od onih preporučenih u njegovim specifikacijama. Funkcija svih ovih gore nabrojanih termina je da se spreče upravo takvi efekti. Dekapling predstavlja zaštitu mikrokontrolera od smetnji na vodovima napajanja. Za stabilizaciju ovog napona uglavnom se koristi popularni 78L05 integrisani stabilizator napona. Međutim, da bi se sprečile oscilacije napona napajanja na njegovom izlazu, poželjno je zalemiti keramički kondenzator od 100nF paralelno napojnim pinovima mikrokontrolera (pinovi Vss i Vdd), a što bliže njima. Ukoliko u projektu koristite više integrisanih kola, poželjno je ovo uraditi kod svakog od njih. Na taj način kondenzator sprečava bilo kakve nepoželjne oscilacije napona (obično nastale usled indukcije napona sa izlaznih pinova). U šemama u ovom uputstvu nisu nacrtani jedino zbog veće preglednosti. Detalji na http://en.wikipedia.org/wiki/Decoupling_capacitor. Sigurno vam se već desilo da prilikom uključenja ili isključenja svetla na prekidaču primetite varničenje kontakta. Idealno bi bilo kada bi prekidač odjednom mogao prebaciti svoje stanje od uključenog u isključeno i obrnuto. Međutim, kako se kontakti prekidača fizički ne mogu previše brzo kretati, neizbežno je javljanje par varnica pre konačne promene stanja. Kod uključenja ili isključenja svetla, ova pojava nije bitna. Ali mikrokontroler zbog svoje velike brzine usled ove pojave može zaključiti da je taster na njegovom ulaznom pinu umesto jednom pritisnut više puta. Da bi se ova pojava neutralisala potrebno je u mikrokontroleru realizovati smanjenje šuma na ulaznom signalu, odnosno debouncing. Debouncing rutina testira stanje pina, sačeka malo (koliko je potrebno da se stabilizuje stanje prekidača) i onda ga opet testira. Testiranje se ukoliko je potrebna veća preciznost može uzastopno izvršavati i više od dva puta. Ukoliko su u svim slučajevima dobijena ista logička stanja na pinu, to znači da je taster sigurno pritinut (otpušten), a u protivnom da nije. Ovaj princip standardno koriste kompjuterske tastature. Za više detalja pogledajte http://www.ganssle.com/debouncing.pdf. Alternativno, moguće je realizovati i hardverski debouncing, ali za njega svaki pin mora imati svoj prekidač što onemogućava multipleks ulaza (više o njemu kasnije) i sa svakim tasterom potrebno je povezati dva otpornika i kondenzator. To direktno poskupljuje proizvodnju, uvećava mogućnost pojave hardverskih grešaka i zahteva povećanje dimenzije i težine hardvera. PIC sam po sebi ne bi mogao mnogo toga uraditi bez par ulaznih elemenata (prekidači, senzori, sonde...). Elementi koje mu dodajemo mogu, ali i ne moraju biti digitalni. U tehničkom uputstvu preporučeno je da ulazni logički nivoi (pri naponu napajanja od 5V) budu u intervalu od 0 do 0,8V za logičku 0, i od 2,4V do 5V za logičku 1. Šta će se dogoditi ukoliko ovi elementi umesto precizno definisanih logičkih nivoa na ulazni pin dovedu napon od npr. 1,5V? 44

Kod mikrokontrolera nema „sivog“ stanja. Stanje na njegovom pinu mora biti ili crveno ili belo (navijam za Zvezdu). Ukoliko se ulaznom pinu mikrokontrolera dovede ovako nedefinisan napon, on može pročitati 0, a može i 1. Nema pravila. Ukoliko ulazni pin (u najgorem mogućem slučaju) nije povezan na eksterno kolo, napon na njemu može zaoscilovati, pa čak prouzrokovati uništenje mikrokontrolera. U praksi se nekad javi situacija da je potrebno na mikrokontroler dovesti upravo ovakav „sivi“ napon. U tom slučaju poželjno je koristiti uzlaze sa šmitovim okidačem (eng. Schmitt trigger), ili ih dodati eksterno (npr. preko 7414 šestostrukog invertora). U PIC16F84 šmitov okidač nalazi se na RA4 pinu. Na RB0 pinu nalazi se samo kada je ovaj definisan kao izvor interapta (više o njima kasnije). Kod ulaza sa šmitovim okidačem nema nedefinisanih stanja ulaznog pina. Stanje na pinu promeniće se tek kada se signal dovoljno približi njegovoj definisanoj oblasti. Ako se nakon toga vrati ka srednjoj (sivoj) oblasti, ulaz će i dalje javljati njegovo poslednje stabilno definisano stanje. Više o ovome imate na sajtu http://en.wikipedia.org/wiki/Schmitt_trigger. Očigledno je da će pri povezivanju taster prekidača na ulaze PIC16F84 mikrokontrolera biti potrebno da njegovi ulazi budu u svakom trenutku na tačno definisanom logičkom nivou. Ovo se hardverski realizuje Pull-up (povući nagore) ili Pull-down (povući nadole) otpornicima. Pull up otpornik je otpornik povezan između napona napajanja mikrokontrolera i ulaznog pina, pri čemu se taster prekidač vezuje između pina i mase. Kada je taster otpušten, pull up otpornik dovodi napon napajanja direktno na pin, postavljajući ga tako u stanje logičke jedinice, sve dok se ne pritisne taster. Bez njega bi napon na pinu verovatno zašao u nedefinisano stanje. Ovaj otpornik ne treba biti previše male vrednosti zbog manje potrošnje struje pri pritisnutom taster prekidaču. Preporučene vrednosti su od 4,7kΩ do 10kΩ. Na isti način na željeni pin mikrokontrolera može se postaviti pull down otpornik prema masi, kada bi se prekidač postavio prema naponu napajanja, što je ilustrovano u ranijim šemama. Više o pull-up otpornicima možete saznati na http://en.wikipedia.org/wiki/Pull-up_resistor. Postavljanje eksternih pull up otpornika komplikuje izradu štampane pločice. Stoga su na pinovima PORTB registra oni hardverski implementirani, a uključuju se resetovanjem bita 7 (Port B Pull Up) OPTION_REG registra. Primećujete da je ovo suprotno od onoga što biste mogli očekivati! Zato se takvi „nelogični“ bitovi označavaju sa crticom iznad njih ili NOT_ predznakom. To označava da je logička 0 njihovo aktivno stanje. Resetovanjem NOT_RBPU bita povezuju se interni otpornici mikrokontrolera na svaki od ulaza PORTB registra prema naponu napajanja mikrokontrolera. Interni otpornici spajaju se na sve ulazne pinove porta B. Pored te, OPTION_REG registar ima i razne druge funkcije, pa je stoga najpraktičnije ne menjati sadržaj njegovih ostalih bitova. Još jedna stvar vredna pažnje je elekrtomagnetna interferencija. Da bi se zaštitili od nje, poželjno je na svaki pin pre bilo kakvog hardvera povezati redni otpornik. 45

17. Još malo o hardveru Do sada ste pisali i pisali programe. Vreme je da se malo pozabavite unutrašnjom strukturom mikrokontrolera. Nakon toga neke stvari će vam biti jasnije. Sve instrukcije sa kojima radi PIC16F84 su četrnaestobitne. Međutim, unutar samih instrukcija nalazi se kôd instrukcije (po kome se npr. instrukcija CALL razlikuje od MOVLW) i operand, koji predstavlja podatak sa kojim radimo (bit, bajt ili oba u npr. bsf PORTA,2 instrukciji). Postoje i instrukcije koje nemaju operand (npr. CLRW). Pre izvršenja svake instrukcije PIC gleda sadrežaj registra PCL i PCLATH. Oni (tačnije bitovi 0-5 PCLATH + 0-8 PCL) čine jedinstven trinaestobitni PC (eng. Program Counter) registar. U njemu je smeštena adresa izvršavanja tekuće instrukcije. Po izvršavanju instrukcije, PC se uvećava za 1, i prelazi na sledeću instrukciju. Ukoliko je tekuća instrukcija instrukcija uslovnog skoka (DECFSZ, INCFSZ, BTFSC ili BTFSS), rezultat instrukcije (tačno ili netačno – 1 ili 0) dodaje se na PC, čime je omogućen skok preko sledeće instrukcije. Međutim ukoliko je tekuća instrukcija GOTO, ona će u PC postaviti novi adresu, i izvršenje programa nastaviće se odatle. Specijalan slučaj predstavlja koriščenje CALL instrukcije. PIC mora na neki način upamtiti mesto sa koga je skočio na potprogram. Ta informacija čuva se u steku. Stek je interni deo mikrokontrolera (kao uostalom i W registar) kome mogu pristupiti jedino instrukcije skoka i povratka iz potprograma ili interapt rutine (više o njoj kasnije). Njega možete zamisliti kao cev zatvorenu sa jedne strane u koju redom ubacujete klikere. Crveni, zeleni, žuti i plavi. Očigledno, ne možete izvući zeleni kliker ukoliko prethodno ne izvučete plavi pa žuti. Pri nailasku na CALL instrukciju, adresa naredne instrukcije se stavlja na stek, i vrši se izmena PC. Mikrokontroler skače na potprogram, i tamo nastavlja izvršenje programa sve do instrukcije povratka. Po nailasku na instrukciju povratka, mikrokontroler preuzima adresu povratka sa steka, i smešta je u PC. Dalje izvršenje programa nastavlja se odatle. Međutim, stek nije beskonačan. U njega se može upisati maksimalno 8 adresa za povratak (još manje ukoliko se koriste interapti). Nakon toga nove adrese povratka prebrisaće početne (crveni pa zeleni kliker...), što će prouzrokovati nepravilan rad programa. Ovo ograničenje ne bi trebalo preterano da Vas brine. U praksi uglavnom nema potrebe za potprogramima koji idu više od druge ili treće dubine. Ukoliko u programu imate više pozivanja potprograma, prilikom simulacije programa proverite sadržaj steka opcijom View, Hardware stack. Iako PIC nema set instrukcija kojima bi se mogle koristiti tabele u programu, moguće je implementirati ih upotrebom PCL i PCLATH registra i instrukcije RETLW k. Retlw k (Return with Literal in W) instrukcija omogućava povratak iz potprograma (isto kao i RETURN instrukcija), pri čemu se nakon povratka bajt k nalazi u W registru. Za obične potprograme to i nije neka velika pogodnost, ali je za tabele neophodno. Tabele se koriste pozicionirajući PCL registar na odovarajuću instrukciju. U primeru koji sledi tabela se koristi za odabir odgovarajućeg šablona za crtanje brojeva od 0 do 9 na sedmosegmentnom LED displeju.

46

; ****** Inicijalizacija i imenovanje ****** list p=16F84 ; Definiše upotrebljeni mikrokontroler #include ; Ubacuje nazive registra u program __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC ; Podešava konfiguracione bitove. BROJ equ 0x0C ; Promenljiva za broj koji se prikazuje (0x00-0x09) BROJAC equ 0x0D ; Brojač za pauzu. Inicijalno 0xFF org 0x00 ; ****** Podešavanje porta ****** bsf STATUS,RP0 ; Prebacuje program u BANK1 movlw 0x01 ; Konfiguriše pinove tako da su RB1 do movwf TRISB ; RB7 izlazni, a da je RB0 ulazni. clrf TRISA ; Svi pinovi na PORTA su izlazni. bcf OPTION_REG,NOT_RBPU ; Uključeni interni „pull up“ ; otpornici na PORTB bcf STATUS,RP0 ; Vraća program u BANK0 ; ****** Inicijalizacija ****** Ini clrf BROJ call Disp

; Postavljanje na 0 ; Prikaz broja na displeju

47

; ****** Testiranje prekidača ****** Cek1 btfss PORTB,0 ; Testiranje otpuštenosti prekidača goto Cek1 ; Nije otpušten call Pau ; Jeste otpušten. Pozovi pauzu. btfss PORTB,0 ; Još jedno testiranje zbog imunosti na goto Cek1 ; eventualna varničenja kontakta. Cek2 btfsc PORTB,0 ; Testiranje pritisnutosti prekidača goto Cek2 ; Nije pritisnut call Pau ; Jeste pritisnut. Pozovi pauzu. btfsc PORTB,0 ; Još jedno testiranje zbog imunosti na goto Cek2 ; eventualna varničenja kontakta. ; ****** Brojanje ****** movlw 0xF6 addwf BROJ,W btfsc STATUS,C goto Ini incf BROJ,F call Disp goto Cek1

; .246 u W (.246+.9+.1 = setovan Carry flag) ; Saberi sa BROJ, rezultat u W ; Da li je došlo do prekoračenja (Carry flag)? ; Jeste, resetuj brojač ; Nije, uvećaj brojač, ; prikaži rezultat i. ; nastavi sa testiranjem i brojanjem

; ****** Potprogram za prikaz na LED displeju ****** Disp call Tabl ; Obrazac za prikaz u W movwf PORTB ; Prikaži na displeju return ; Povratak iz potprograma ; ****** Tabela ****** Tabl movf BROJ,W ; U promenljivoj BROJ nalazi se vrednost od addwf PCL,F ; .0 do .9. Ta vrednost se dodaje na PCL. retlw b'01111110' ; Obrazac za crtanje cifre 0 - 0 retlw b'00001100' ; Obrazac za crtanje cifre 1 - 1 retlw b'10110110' ; Obrazac za crtanje cifre 2 - 2 retlw b'10011110' ; Obrazac za crtanje cifre 3 - 3 retlw b'11001100' ; Obrazac za crtanje cifre 4 - 4 retlw b'11011010' ; Obrazac za crtanje cifre 5 - 5 retlw b'11111010' ; Obrazac za crtanje cifre 6 - 6 retlw b'00001110' ; Obrazac za crtanje cifre 7 - 7 retlw b'11111110' ; Obrazac za crtanje cifre 8 - 8 retlw b'11011110' ; Obrazac za crtanje cifre 9 - 9 ; ****** Pauza ****** Pau decfsz BROJAC,F goto Pau return

; Pauza zbog debouncing ; rutine ; Povratak iz potprograma

; ****** Kraj programa ****** end

; Kraj programa.

48

Duplim testiranjem pritisnutosti taster prekidača sa pauzom između testiranja realizovana je debouncing rutina. Testiranje na otpuštenost, a zatim na pritisnutost sprečava nastavak brojanja ukoliko se prekidač neprekidno drži pritisnut, i omogućava promenu stanja prilikom pritiska, a ne prilikom otpusta tastera. Testiranje prekoračenja realizovano je sabiranjem vrednosti sa brojem 246 i testiranjem Carry flaga. Za vrednosti od 0 do 9 sabrane sa .249 Carry flag neće biti setovan, ali hoće za vrednosti veće od njih (.10). One će prouzrokovati ponovnu inicijalizaciju brojača, i ciklus brojanja će ponovo početi od 0. Prikaz dekadnog broja realizovan je direktnim dovođenjem napona na pojedine segmente LED displeja. Ovi segmenti su na LED displeju označeni su slovima a, b, c, d, e, f i g. Segment dp (eng. decimal point) „decimalna tačka“ ovde nije iskorišćen. Iako je program je napravljen za rad sa displejem sa zajedničkom katodom, može može se prepraviti za rad sa displejem sa zajedničkom anodom prepravkom tabele na taj način što se svi bitovi u tabeli (LSB nema uticaja na rad programa jer je pin RB0 povezan na taster) invertuju: retlw retlw retlw

b'01111110' b'00001100' b'10110110'

; 0 promeniti u b'10000001' ; 1 promeniti u b'11110011' ; 2 promeniti u b'01001001'

U tom slučaju potrebno je prepraviti električnu šemu tako da se zajednička anoda poveže na +5V. U potprogramu za prikaz možete videti klasičan primer pozivanja drugog potprograma iz prvog. MPLAB asembler ima direktivu DT (eng. Define Table) kojom se mogu brže unositi željene vrednosti u tabelu. Njen oblik je sledeći: addwf PCL,F ; Saberi sa PCL dt d'10', d'18', d'0', d'253', d'84', d'5' ; Vrednosti Iako na prvi pogled deluje da se na ovaj način štedi memorija mikrokontrolera, to nije slučaj. Asembler će dt direktivom naredne memorijske lokacije napuniti retlw instrukcijama koje sadrže vrednosti navedene iza direktive. Pri tome se mogu primenjivati svi načini označavanja brojeva (decimalni, heksadecimalni...). Ova pogodnost najviše dolazi do izražaja pri upisivanju ASCII karaktera: addwf PCL,F ; Saberi sa PCL dt “Proba ispisa teksta“ ; ASCII karakteri u tabeli U radu sa tabelama morate obratiti pažnju na dve stvari. 1. Morate biti sigurni da je broj koji sabirate sa PCL u tačno određenim granicama. U slučaju prekoračenja izvršavanje programa će se nastaviti sa slučajne memorijske adrese što će prouzrokovati nepravilan rad ili blokadu programa.

49

2. Kako je PC trinaestobitni registar čiji donji deo (0-255) je u PCL, a gornji (>255) u bitovima 0-5 PCLATH, potrebno je osigurati da tabela ne izađe iz bloka od 256 bajtova. Kod programa navedenog kao primer, to nije problem, jer je on ionako dug samo 43 bajta. Ukoliko je neophodno koristiti tabele sa većom količinom podataka, rešenje bi moglo biti u postavljanju više tabela. Veličinu bloka najjednostavnije možete proveriti brojanjem upotrebljenih instrukcija (bez direktiva), ili analizom .lst fajla generisanog prilikom asembliranja. Za postavljanje početka tabele na željeno mesto (početak bloka) možete koristiti ORG direktivu. Umesto tabele moguće je napraviti skok na proračunate memorijske lokacije addwf PCL,F instrukcijom, pri čemu se adresa na koju se treba skočiti čuva u W registru u obliku broja instrukcija koje se trebaju preskočiti da bi se došlo do željene. Ogrančenja vezana za tabele važe i u ovom slučaju. Da biste ih prevazišli, pogledajte AN548 sa http://www.microchip.com/.

50

18. Watchdog tajmer Pretpostavimo da ste napisali program koji se neprekidno izvršava na mikrokontroleru. Normalno, želeli bi da se osigurate da će program uvek nastaviti sa izvršavanjem bez obzira na to šta se sa njim događa. Uzmite u obzir sledeći slučaj. Pretpostavimo da PIC nadgleda određeni ulazni pin. Kada se na ovaj pin dovede logička 1, program skače na naredni deo i čeka da sledeći pin dobije logičku 1. Ukoliko se to ne desi, PIC će se vrteti u petlji i čekati. Izaći će iz petlje tek kada se na pinu pojavi 1. Pogledajte sada malo drugačiji primer. Pretpostavimo da ste napisali program, kompajlirali ga, čak i simulirali njegov rad u simulatoru. Međutim posle dugo vremena program se zaglavi u nekoj petlji (koliko ste samo puta Vi pritisnuli Ctrl Alt Delete kombinaciju na Windowsu). U oba slučaja potrebna Vam je neka vrsta reseta ukoliko se program zaglavi. To je svrha Watchdog (eng. pas čuvar) tajmera. Watchdog tajmer (skraćeno WDT) nije ništa novo. Mnogi mikrokontroleri i mikroprocesori imaju ga u sebi. Ali kako on radi? Unutar mikrokontrolera nalazi se interni RC oscilator koji obezbeđuje jedinstven takt, nezavistan od takta mikrokontrolera. Kada se WDT uključi, njegov brojač počinje sa 0x00, i redom se inkrementuje sve dok ne dostigne maksimalnu vrednost 0xFF. U trenutku prelaska sa 0xFF na 0x00 (što je 0xFF+1) PIC će se resetovati bez obzira na njegovo stanje. Jedini način na koji se može sprečiti ovaj reset, je periodično resetovanje WDT na 0 kroz program. Sada možete i sami uvideti da u slučaju zaglavljivanja mikrokontrolera u petlji WDT neće biti resetovan, što će prouzrokovati reset mikrokontrolera. Da biste mogli uspešno koristiti WDT potrebno je da znate tri stvari. Prvo za koliko vremena će WDT preći sa 0x00 na 0xFF, drugo kada ga trebate resetovati i treće kako podesiti softver programatora za njegovo uključenje. Vreme WDT WDT ima vreme prelaska sa 0x00 na 0xFF od oko 18mS. Ovo vreme zavisno je od nekoliko spoljnih faktora kao što su napon napajanja, temperatura mikrokontrolera i.t.d. Zbog lakšeg objašnjavanja zaokružiću ovo vreme na tačno 18mS. Ipak, ono se može i produžiti. bit 2,1,0

Odnos

Vreme

0, 0, 0

1:1

18mS

0, 0, 1

1:2

36mS

0, 1, 0

1:4

72mS

0, 1, 1

1:8

144mS

1, 0, 0

1:16

288mS

1, 0, 1

1:32

576mS

1, 1, 0

1:64

1,1S

1, 1, 1

1:128

2,3S

Unutar mikrokontrolera nalazi se tzv. preskaler (eng. pre podeliti). On se može programirati za deljenje WDT takta generisanog internim RC oscilatorom. Što se veći odnos deljenja koristi, takt WDT će biti sporiji. Preskaler se nalazi u OPTION_REG registru (0x81) na mestu od nultog do drugog bita. U tabeli je prikazan odnos bitova, odnos deljenja takta i vreme prekoračenja vrednosti WDT.

51

Upamtite da su ova vremena nezavisna od takta oscilatora mikrokontrolera. Mislite o ovim vremenima kao stvarnim (eng. real time), nasuprot taktu mikrokontrolera koji možete menjati fizičkom zamenom par delova u oscilatoru. Pretpostavimo da želite da WDT resetuje PIC nakon pola sekunde. Najbliža standardna vrednost je 576mS, odnosno 0,576S, pa je dovoljno poslati vrednost b101 u OPTION_REG registar. movlw movwf

b'101' 0x81

; Ovo je 0x05 ; Adresa OPTION_REG registra.

Međutim nije baš sve tako jednostavno. Po inicijalizaciji PIC-a postskaler je pridružen internom tajmeru mikrokontrolera (više o njemu kasnije). To znači da je potrebno prebaciti ga na WDT. Kako i interni i watchdog tajmer koriste iste bitove OPTION_REG registra Microchip preporučuje sledeću proceduru kako ne bi došlo do nehotičnog reseta PIC. ; ****** Inicijalizacija i imenovanje ****** list p=16F84 ; Definiše upotrebljeni mikrokontroler #include ; Ubacuje nazive registra u program __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC org 0x00 ; Podešava konfiguracione bitove. ; ****** Podešavanje WDT ****** * bsf STATUS,RP0 * movlw b'xx0x0111' * movwf OPTION_REG * bcf STATUS,RP0 clrf TMR0 bsf movlw

STATUS,RP0 b'xxxx1111'

movwf clrwdt movlw

OPTION_REG

movwf bcf

OPTION_REG STATUS,RP0

b'xxxx1xxx'

; BANK1 ; Izaberi tajmer i preskaler različit od 000 ; BANK0 ; Brisanje vrednosti internog tajmera i ; preskalera – pri upisu u tajmer, ; BANK1 ; Izaberi WDT, bez menjanja odnosa ; preskalera ; Obriši WDT ; Izaberi WDT, i postavi zeljeni odnos ; preskalera xxx. ; Za 0,576S to je b'xxxx1101' ; BANK0

U slučaju željenog odnosa različitog od 1:1 (vrednost preskalera 000) mogu se izbaciti instrukcije označene zvezdicom. Vrednosti u OPTION_REG registru levo od preskalera označene sa x imaju specijalne funkcije (poput uključenja Pull-Up otpornika) koje ćete naučiti u delu sa tajmerom i interaptima. Iz tog razloga im ovde nisu dodeljene konkretne vrednosti. Za sada je dovoljno da znate da se bitom 3 OPTION_REG registra vrši selekcija tajmera kome će biti pridružen delitelj po sledećem: 1 – postskaler WDT 0 – preskaler internog tajmera. 52

U primeru ste naučili upotrebu CLRWDT (eng. Clear Watchdog timer) instrukcije. Nakon nje, TO bit (eng. Time Out – isteklo vreme) STATUS registra biće iznova setovan, a naći će se u resetovanom stanju jedino prilikom WDT reseta. Više o tome naučićete u poglavlju sa reset funkcijom. Vreme izvršavanja instrukcija Kao što se sećate, PIC deli takt oscilatora sa 4. Ovo vreme naziva se instrukcijski ciklus. Ukoliko je kao izvor takta upotrebljen kristal od 4MHz, PIC će izvršavati instrukcije brzinom od 4MHz/4=1MHz, odnosno za jednu instrukciju koja traje 1 instrukcijski ciklus će mu trebati 1μS, dok će mu za instrukciju koja traje 2 instrukcijska ciklusa trebati 2μS. Način da zapamtite broj instrukcijskih ciklusa za sve instrukcije je prilično lak. Pretpostavite da sve instrukcije traju 1 instrukcijski ciklus. Ali, ukoliko instrukcija prouzrokuje nastavak programa sa neke druge adrese (promenjen je sadržaj PC), onda će ona trajati 2 instrukcijska ciklusa. Na primer MOVWF instrukcija traje 1 instrukcijski ciklus, jer samo premešta podatak sa jednog na drugo mesto. GOTO instrukcija traje 2 ciklusa jer prouzrokuje da PC skoči na neko drugo mesto u programu. RETURN instrukcija traje 2 ciklusa, jer se PC vraća na glavni program. Međutim, postoje 4 instrukcije koje mogu trajati 1 ili 2 instrukcijska ciklusa. To su DECFSZ, INCFSZ, BTFSC i BTFSS. One će preskočiti sledeću instrukciju u slučaju da je određeni uslov ispunjen i onda će trajati 2 ciklusa. Ukoliko taj uslov nije ispunjen, izvršiće se naredna instrukcija kao da se ništa nije ni desilo, i onda će trajati 1 ciklus. Pogledajte sada sledeći program.

Pet

movlw movwf decfsz goto end

0x02 BROJAC BROJAC,F Pet

Prva instrukcija postavlja vrednost 0x02 u W. Ovo ne prouzrokuje menjanje PC, pa ona traje 1 instrukcijski ciklus. Sledeća instrukcija je slična. Ona takođe ne menja stanje PC, pa i ona traje 1 ciklus. Sada će sledeća instrukcija izvršiti prvo smanjenje registra BROJAC za 1 i rezultat „testa na vrednost 0“ = 0 pridružiti PC. Na ovaj način PC se ne menja, pa instrukcija traje 1 ciklus. Sledeća instrukcija je GOTO, i ona traje 2 ciklusa. Onda se ponovo vrši smanjenje registra BROJAC za 1, ali kako je sada rezultat „testa na vrednost 0“ = 1, PC će promeniti svoju vrednost na PC+1, što troši 2 instrukcijska ciklusa. Znači ovaj program zauzeće ukupno 7 instrukcijskih ciklusa. Uz kristal od 4MHz program će trajati 4MHz / 4takta = 1μS po instrukcijskom ciklusu, što za 7 ciklusa iznosi 7 * 1μS = 7μS. Vidite koliko zbunjujući može biti instrukcijski ciklus instrukcija uslovnog skoka. Softver programatora Sećate se __CONFIG direktive? Za korišćenje WDT, on se mora preko nje uključiti sa WDT ON. A pošto je neki programatori ignorišu, potrebno je i unutar njihovog softvera podesiti konfiguracione bitove. Postupak njihovog podešavanja razlikuje se od programatora, do programatora (softvera). Uglavnom se traži njihov upis neposredno pre programiranja mikrokontrolera. 53

Sledećim programom namerno se dozvoljava prekoračenje WDT. Njegov takt koristi se za treptanje LED. Primećujete da je LED povezana tako da svetli pri dovođenju logičke 0 na pin, a da joj se napon dovodi direktno sa napajanja! To je bolje zbog manjeg grejanja i potrošnje. Osim toga PIC pored ograničenja struje po pojedinačnim pinovima (20mA) ima i ograničenje struje koju može dati ceo port (do 50mA za PORTA i do 100mA za PORTB), kao i ograničenje ukupne struje koju prima i kojom može napajati eksterne potrošače (150mA). PIC pri ovakvom povezivanju podnosi do 25mA po pinu, do 80mA za PORTA i do 150mA za PORTB. Za pin RA4 ovo je i jedino moguće rešenje, jer on na svom izlazu ne može dati logičku 1. ; ****** Inicijalizacija i imenovanje ****** list p=16F84 ; Definiše upotrebljeni mikrokontroler #include ; Ubacuje nazive registra u program __CONFIG _CP_OFF & _WDT_ON & _PWRTE_ON & _RC_OSC ; Podešava konfiguracione bitove. org 0x00 ; ****** Test WDT reseta ****** btfss STATUS,TO goto Led ; ****** Podešavanje porta ****** bsf STATUS,RP0 clrf TRISA clrf TRISA clrf TMR0 ; ****** Podešavanje WDT ****** bcf STATUS,RP0 clrf TMR0 bsf movlw

STATUS,RP0 b'10001111'

movwf

OPTION_REG

; Testiraj stanje TO bita ; Resetovan je, znači WDT reset ; Prebacuje program u BANK1 ; Svi pinovi ; su izlazni. ; Brisanje vrednosti internog tajmera i ; preskalera – pri upisu u tajmer, ; Vraća program u BANK0 ; Brisanje vrednosti internog tajmera i ; preskalera – pri upisu u tajmer, ; Prebacuje program u BANK1 ; Isključi Pull-up otpornike i ; izaberi WDT, sa maksimalnim ; vremenom preskalera

54

clrwdt movlw

b'10001110'

movwf bcf

OPTION_REG STATUS,RP0

; Obriši WDT ; Izaberi WDT, i postavi odnos ; preskalera od 1,1S ; BANK0

; ****** Inicijalizacija W i prvo prekoračenje WDT ****** clrw ; Obriši W Pet goto Pet ; Mrtva petlja. Vrti se ovde do ; prvog WDT reseta ; ****** Naredna prekoračenja WDT ****** Led xorlw b'00000100' ; Izmeni stanje bita 2 u W movwf PORTA ; Prebaci stanje iz W u PORTA Pet2 goto Pet2 ; Mrtva petlja. Vrti se ovde do ; sledećeg WDT reseta ; ****** Kraj programa ****** end ; Kraj programa. Nakon početne inicijalizacije program će se vrteti u prvoj mrtvoj petlji. Kako u njoj nema CLRWDT instrukcije, nakon 1,1S nastupiće WDT reset. Po resetu program će se izvršiti od početka, ali će deo sa testiranjem TO bita detektovati je li nastupio WDT reset ili ne, i ukoliko jeste dalje izvršavanje programa nastaviće se od labele Led gde će se izmeniti stanje RA2 pina. Nestabilnost WDT oscilatora usled promene temperature može biti efektno iskorišćena za merenje temperature mikrokontrolera (samim tim i spoljne temperature) bez ikakvih eksternih senzora. Za detalje pogledajte AN828.

55

19. Tajmer U slučaju da pišete program koji mora imati veliku ali tačno definisanu pauzu sigurno vam se neće svideti mogućnost postavljanja jedne petlje unutar druge i proračunavanja broja ciklusa za željenu dužinu pauze. Postoji elegantniji način rešavanja ovog problema. PIC16F84 ima u sebi integrisan tajmer. Impulsi ovog tajmera mogu biti sinhronizovan sa taktom izvršavanja instrukcija mikrokontrolera ili sa taktom eksternog oscilatora čiji impulsi se dovode na pin 3 (RA4/T0CKI). Glavna funkcija tajmera je brojanje (.0-.255) koje je za razliku od WDT sinhronizovano sa ovim taktom. U trenutku prekoračenja maksimalne vrednosti, flag tajmera se setuje, i ciklus brojanja opet počinje od nule. Prednost tajmera nad običnom petljom za kašnjenje je u činjenici da je brojanje interni proces mikrokontrolera, i da ni na koji način ne utiče na brzinu izvršavanja glavnog programa. Dovoljno je povremeno proveriti stanje flaga tajmera, kako bi program znao da je ciklus brojanja završen. Kako na ovaj način nije moguće dobiti veće periode, tajmer isto kao i WDT može koristiti preskaler. Budući da se za korišćenje i WDT i internog tajmera pretežno vrši manipulacija nad OPTION_REG registrom, vreme je da se bliže upoznate sa njegovom unutrašnjom strukturom. bit7 RBPU

INTEDG

T0CS

T0SE

PSA

PS2

PS1

bit0 PS0



NOT_RBPU (eng. Port B Pull Up) bit OPTION_REG registra služi za povezivanje internih otpornika PORTB registra na napon napajanja.



Upotrebu INTEDG (eng. Interrupt edge) bita naučićete u sledećem poglavlju.



T0CS (eng. Timer0 Clock Select) bit omogućava izbor takta tajmera. Ukoliko je resetovan, brojanje će se odvijati sinhronizovano sa taktom izvršavanja instrukcija koji je četiri puta manji od takta oscilatora. Ovaj takt se može dobiti sa CLKOUT pina mikrokontrolera. Ukoliko je T0CS bit setovan, brojanje će biti sinhronizovano sa eksternim taktom koji se treba dovesti na pin 3 (RA4/T0CKI).



T0SE (eng. Timer0 Source Edge) bit ima smisla jedino pri upotrebi eksternog takta. Njime se bira hoće li se brojanje vršiti pri prelasku sa logičke 0 na 1 (resetovan T0SE) ili sa logičke 1 na 0 (setovan T0SE).



PSA (eng. Prescaller Assigment) bit se koristi za selekciju pridruženosti preskalera. Ukoliko je setovan, postskaler će biti pridružen WDT, a ukoliko je resetovan preskaler će biti pridružen tajmeru.



Bitovima PS0 do PS2 bira se odnos deljenja preskalera po sledećoj tablici.

56

Bit 2, 1, 0

TMR0 odnos

WDT odnos

0, 0, 0

1:2

1:1

0, 0, 1

1:4

1:2

0, 1, 0

1:8

1:4

0, 1, 1

1:16

1:8

1, 0, 0

1:32

1:16

1, 0, 1

1:64

1:32

1, 0, 1

1:128

1:64

1, 1, 1

1:256

1:128

Primećujete da se i ovde pominje WDT odnos. On je tu jer se odnos tajmera od 1:1 može dobiti jedino pridruživanjem preskalera WDT, setovanjem PSA bita. Za takvo podešavanje primenjuje se kôd opisan u prošlom poglavlju sa instrukcijama označenim zvezdicama. Budući da se pri samom programiranju PIC16F84 vrši uključenje ili isključenje WDT (podešavanjem konfiguracionih bitova), ne može se doći u situaciju da se WDT sam uključi, i tako izazove reset mikrokontrolera, iako mu je pridružen preskaler.

Registar tajmera TMR0 (eng. Timer0) nalazi se na adresi 0x01, a njegov flag T0IF (eng. Timer0 Overflow Interrupt Flag) nalazi se u INTCON registru. Više o ovom registru naučićete u delu sa interaptima. Sledi program koji ilustuje upotrebu tajmera. On će instrukcijski ciklus preskalerom deliti sa 256, zatim softverski još sa 6, a onda će heksadecimalne brojeve (0x00 do 0x0F) prikazivati na LED displeju. Deljenje sa dva se kao što se sećate može realizovati rotacijom bitova unutar registra. U programu će biti upotrebljen ranije ilustrovani princip prikaza na LED displeju. ; ****** Inicijalizacija i imenovanje ****** list p=16F84 ; Definiše upotrebljeni mikrokontroler #include ; Ubacuje nazive registra u program __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC ; Podešava konfiguracione bitove DISP equ 0x0C ; Promenljiva za broj koji se prikazuje ; na displeju (0x00-0x0F) DEL equ 0x0D ; Promenljiva za rotaciju ORG 0x00 ; Definiše start programa ; ****** Inicijalizacija tajmera i displeja ****** clrf TMR0 ; Inicijalizacija tajmera clrf INTCON ; Brisanje flaga tajmera bsf STATUS,RP0 ; Prelazak u BANK1 clrf PORTA ; Postavlja sve pinove clrf TRISB ; kao izlazne movlw b'10000111' ; Tajmer je sinhronizovan sa ; instrukcijskim ciklusom, i preskaler je movwf OPTION_REG ; podešen za odnos 1:256 ; Pull up otpornici su isključeni bcf STATUS,RP0 ; Povratak u BANK0

57

; ****** Inicijalizacija brojača ****** Ini movlw 0x00 movwf DISP movlw b'00100000' movwf DEL

; Inicijalizacija ; displeja ; Inicijalizacija ; delitelja

; ****** Čekanje na prekoračenje tajmera ****** Taj bcf INTCON,T0IF ; Resetovanje flaga tajmera Cek btfss INTCON,T0IF ; Čekanje na setovanje flaga tajmera, goto Cek ; odnosno prekoračenje tajmera ; ****** Deljenje sa 6 ****** rrf DEL btfss STATUS,C goto Taj

; Rotiraj DEL registar nadesno. Kada se Carry ; flag setuje, nastavi dalje. Ukoliko i dalje nije ; setovan, čekaj na još jedan ciklus tajmera.

; ****** Prikaz cifre na displeju ****** call Tabl ; Uzmi obrazac iz tabele, movwf PORTB ; i prikaži cifru na displeju. ; ****** Testiranje prekoračenja vrednosti cifre na displeju ****** movlw 0x01 ; .1 u W addwf DISP,F ; Saberi DISP sa W. Rezultat u DISP btfsc STATUS,DC ; Da li je došlo do prekoračenja vrednosti 0x0F? goto Ini ; Jeste, počni brojanje od početka (cifre 0) goto Taj ; Nije, nastavi dalje sa brojanjem. ; ****** Tabela ****** Tabl movf DISP,W ; U promenljivoj DISP nalazi se vrednost od addwf PCL,F ; 0x00 do 0x0F. Ta vrednost se dodaje na PCL. retlw b'01111110' ; Obrazac za crtanje cifre 0 - 0 retlw b'00001100' ; Obrazac za crtanje cifre 1 - 1 retlw b'10110110' ; Obrazac za crtanje cifre 2 - 2 retlw b'10011110' ; Obrazac za crtanje cifre 3 - 3 retlw b'11001100' ; Obrazac za crtanje cifre 4 - 4 retlw b'11011010' ; Obrazac za crtanje cifre 5 - 5 retlw b'11111010' ; Obrazac za crtanje cifre 6 - 6 retlw b'00001110' ; Obrazac za crtanje cifre 7 - 7 retlw b'11111110' ; Obrazac za crtanje cifre 8 - 8 retlw b'11011110' ; Obrazac za crtanje cifre 9 - 9 retlw b'11101110' ; Obrazac za crtanje cifre A- A retlw b'11111000' ; Obrazac za crtanje cifre B - B retlw b'01110010' ; Obrazac za crtanje cifre C - C retlw b'10111100' ; Obrazac za crtanje cifre D - D retlw b'11110010' ; Obrazac za crtanje cifre E - E retlw b'11100010' ; Obrazac za crtanje cifre F - F ; ****** Kraj programa ****** end

; Kraj programa 58

Možda Vam izgleda čudno upotreba sabiranja umesto inkrementovanja registra DISP. Svakako da se njegovo uvećanje moglo izvršiti i inkrementacijom, ali na ovaj način lakše je nakon povećanja testirati njegovo prekoračenje. Jedino instrukcije sabiranja i oduzimanja menjaju stanje DC flaga, i jedino pri prekoračenjima donjih niblova (tačnije vrednosti 0x0F donjeg nibla). Za kraće periode moguće je nakon svakog prekoračenja postaviti inicijalnu vrednost tajmera na npr. .100. U tom slučaju tajmer će brojati od .100 do .255, kada će se setovati njegov flag. Isto tako moguće je primeniti drugačiji pristup, pa inicijalizovati TMR0 na .0, i testirati ga na vrednost npr. .100. Povedite računa o instrukcijama koje koristite za podešavanje tajmera, jer će većina instrukcija čije je odredište TMR0 registar obrisati preskaler.

59

20. Interapti - pojam Pojam interapta će vam verovatno biti najteži za razumevanje. Ne postoji lak način za njihovo objašnjavanje, ali nadam se da ćete pri kraju ove sekcije moći da ih uspešno primenjujete u svojim programima. Interapt je proces ili signal koji prekida izvršavanje glavnog mikrokontrolerskog programa i prebacuje njegovo izvršavanje na potprogram koji je zadužen za obradu interapta. Po povratku iz potprograma glavni program nastavlja sa radom kao da se ništa nije ni dogodilo. Ilustrovaću ovo na svakodnevnom primeru. Pretpostavimo da sedite kući i čitate ovo uputstvo. Odjednom vam mobilni signalizira prijem SMS poruke. Prekidate čitanje, pročitate poruku (eventualno i odgovorite), i nastavljate čitanje sa mesta na kome ste stali. Možete zamisliti glavni program kao čitanje uputstva, zvonjavu mobilnog kao izvor interapta, a proces čitanja poruke (i eventualnog odgovora na nju) kao potprogram za obradu intertapta. PIC16F84 ima 4 izvora interapta. Dva eksterna i dva interna. Za sada ćete naučiti primenu eksternih izvora, a interni će biti objašnjeni kasnije. Ukoliko pogledate oznake izvoda pinova PIC16F84 videćete da je na pinu 6 oznaka RB0/INT. Očigledno je da je RB0 ulazno izlazni pin PORTB registra. INT označava da se on može konfigurisati i kao pin eksternog interapta. Pri tome se on ponaša kao šmitov okidač, što otežava pojavu lažnih signala okidanja. Takođe se i pinovi RB4 do RB7 mogu koristiti za interapte. Pre nego što se upotrebi bilo koji izvor interapta, trebaju se uraditi dve stvari. Prvo se trebaju dozvoliti interapti, a zatim izabrati željeni izvori interapta koji će se koristiti u programu. Unutar PIC16F84 nalazi se INTCON (eng. Interrupt Controller) registar na adresi 0Bh. Njegov MSB nazvan je GIE (eng. Global Interrupt Enable). Setovanjem GIE mikrokontroler dozvoljava upotrebu jednog ili više izvora interapta. Ukoliko je GIE resetovan, korišćenje bilo kog interapta nije moguće. Njega možete uporediti sa centralnom bravom automobila. Bit 4 INTCON registra nazvan je INTE (eng. RB0/INT Interrupt Enable - uključi interapt na RB0/INT pinu). Setovanjem INTE bita dozvoljena je upotreba RB0 pina kao izvora interapta. Pre toga je (naravno) potrebno konfigurisati ga kao ulazni pin, kako se ne bi dogodilo da se interapt izazove prilikom menjanja njegovog stanja od strane samog programa. Sada se mikrokontroler treba podesiti za željeni signal izazvanja interapta. Pri rastućoj (sa 0V na +5V) ili pri opadajućoj ivici (sa +5V na 0V) signala. Drugim rečima da li želite da se interapt u mikrokontroleru izazove pri prelasku signala na RB0 pinu sa logičke 0 na logičku 1, ili sa logičke 1 na logičku 0. Ovo se podešava u OPTION_REG registru na adresi 81h. Setovanje njegovog bita 6 nazvanog INTEDG (eng. Interrupt Edge) prouzrokovaće interapt pri rastućoj ivici, a resetovanje pri silaznoj. Kako je nažalost OPTION_REG registar u BANK1, treba preći iz BANK0 u BANK1, tamo setovati ili resetovati INTEDG bit OPTION_REG registra, i vratiti se u BANK0. Najpraktičnije je ovo podešavanje izvršiti uz ostala u toku inicijalizacije mikrokontrolera. Ovim je PIC16F84 podešen za korišćenje interapta na RB0/INT pina PORTB registra. 60

Ukoliko želite koristiti više eksternih izvora interapta, možete koristiti pinove RB4 do RB7. Oni se razlikuju od RB0/INT pina u tome što se interapt javlja pri promeni stanja na pinovima. To znači da će se interapt javiti pri prelasku sa logičke 0 na logičku 1, ali i sa logičke 1 na logičku 0. Podešavanje ovih pinova za izvore interapta vrši se setovanjem bita 3 INTCON registra nazvanog RBIE (eng. Port B Change Interrupt Enable) „uključi interapte pri promeni stanja na portu B“. Kako se kod njih interapt izvršava pri svakoj promeni stanja pinovi RB4 do RB7 nemaju svoj bit za određivanje ivice signala pri kojoj će se izazivati interapt. Interapt flag Sećate li se kako se vrši setovanje Carry flaga? Pri nailasku na interapt na RB0/INT pinu na sličan način se setuje bit 1 (INTF eng.Interrupt flag), odnosno bit 0 (RBIF eng. Port B Interrupt flag) pri interaptu na RB4 do RB7 pinovima u INTCON registru. Kada interapta nema, interapt flag je resetovan. To je cela njegova funkcija. Sada se verovatno pitate kakva je njihova svrha. Ukoliko je interapt flag setovan PIC ne može i neće odgovarati na druge interapte. Pretpostavimo da je izazvan interapt. Odgovarajući interapt flag će biti setovan, i mikrokontroler će izvršiti potprogram za obradu interapta. Ukoliko interapt flag nije setovan, PIC će prihvatati nove interapte što može dovesti do neprestanog vraćanja programa na početak rutine za obradu interapta koja se usled toga nikada ne može izvršiti do kraja. Ukoliko se setite primera sa mobilnim, to je kao da Vam za vreme odgovora na SMS stigne nova poruka i prekine upis odgovora. Daleko je praktičnije završiti sa jednom porukom, i onda dozvoliti prijem novih. Interapt flagovi imaju još jednu funkciju, a to je omogućavanje interapt rutini detekciju izvora interapta (RB0/INT pin odnosno RB4 do RB7 pinovi) u slučaju korišćenja više izvora interapta. Iako PIC automatski setuje interapt flagove pri nailasku interapta, on ih ne resetuje pri povratku iz rutine za obradu interapta. Ovaj posao mora programer sam izvršiti (siguran sam da već znate kako), i treba se odraditi nakon završetka rutine za obradu interapta, a neposredno pre izlaska iz nje.

Uprošćen prikaz interne interapt logike 61

Start i interapt vektor programske memorije U trenutku dovođenja napona napajanja ili prilikom reseta, programski brojač (PC) pokazuje na adresu 0x00, na početak programske memorije. Međutim, pri pojavi interapta PC će adresu sledeće instrukcije staviti na stek, i skočiće na adresu 0x04. Dakle, kada pišete programe koji će koristiti interapte, pre svega trebate reći mikrokontroleru da preskoči preko adrese 0x04, i zadrži interapt rutinu koja počinje na adresi 0x04 odvojenu od ostatka programa. Ovo se veoma lako implementira. Najpre je potrebno da program standardno započne direktivom ORG 0x00. Dalje je potrebno preskočiti preko adrese 0x04. Ovo se radi postavljanjem GOTO instrukcije, nakon koje sledi labela pozicionirana za start glavnog programa. Nakon ove goto instrukcije sledi još jedna ORG direktiva, ovoga puta sa adresom 0x04, a nakon nje rutina za obradu interapta. Na kraju programa za obradu interapta potrebno je staviti RETFIE (eng. Return from interrupt) instrukciju. Ova instrukcija označava povratak iz interapt rutine. Kada PIC naiđe na ovu instrukciju PC uzima sa steka lokaciju na kojoj je PIC bio pre nego što se pojavio interapt. Sledi deo kôda koji ilustruje navedeno. org 0x00 goto Main org 0x04 : : : : : : retfie Main

; PIC počinje odavde pri uključenju i resetu ; Idi na glavni program ; PIC dolazi ovde pri pojavi interapta ; Ovde se nalazi rutina za obradu interapta koju ; PIC izvršava jedino pri nailasku na interapt. ; Na njenom kraju potrebno je obrisati odgovarajući ; interapt flag. ; Završetak rutine za obradu interapta ; Početak glavnog programa

Postoji par stvari na koje trebate obratiti pažnju prilikom korišćenja interapta. 1. Ukoliko koristite isti registar u glavnom programu i u rutini za obradu interapta imajte u vidu da će se sadržaj tog registra verovatno promeniti pri izvršenju rutine za obradu interapta. Na primer, recimo da koristite W registar da biste poslali podatak na PORTA, i takođe koristite W registar u rutini za obradu interapta za neku drugu operaciju. Ukoliko ne pazite, W registar će pri povratku iz rutine za obradu interapta zadržati vrednost koju je imao u interapt rutini, i pri povratku iz nje, ovaj podatak biće poslat na PORTA umesto vrednosti koju je W registar imao ranije. Rešenje ovoga je privremeno čuvanje vrednosti W registra u nekom od slobodnih registara, i vraćanje njegove stare vrednosti po završetku interapt rutine. Isto važi i za ostale registre (obično za STATUS) čiji sadržaj se menja u interapt rutini. 2. Potrebno je obratiti pažnju na minimalno vreme između dve uzastopne pojave interapta. Ukoliko se za takt mikrokontrolera koristi kvarc od 4MHz, PIC će izvršavati instrukcije brzinom od 1μS po instrukciji. Ovo vreme naziva se instrukcijskim ciklusom. U tehničkom uputstvu (eng. Datasheet) za PIC 62

3.

4.

5.

6.

7.

8.

navedeno je da se treba ostaviti najmanje 3 do 4 instrukcijska ciklusa (znači bar 3-4μS) između dve uzastopne pojave interapta. Razlog za je vreme koje je potrebno mikokontroleru za skok na rutinu za obradu interapta, setovanje interapt flaga i povratak iz potprograma za obradu interapta. Imajte ovo na umu ukoliko koristite eksterne izvore interapta. Na kraju interapt rutine bit GIE INTCON registra se automatski setuje. Automatsko setovanje GIE bita može da bude i nedostatak u jednom slučaju, tj. moguće je da instrukcija za resetovanje ovog bita (zabranu svih interapta) u glavnom programu uopšte ne bude izvršena. Naime, ukoliko interapt nastupi u trenutku izvršavanja instrukcije koja resetuje GIE bit, prvo će ta instrukcija biti završena do kraja (resetovaće se GIE bit), a zatim će početi izvršavanje interapt rutine koja će na svom kraju da automatski setuje bit GIE. Tako će GIE bit biti setovan iako je neposredno pre interapta bio resetovan. Da bi se zaštitili od ove situacije, Microchip preporučuje da se nakon resetovanja GIE bita proveri da li je bit zaista resetovan i da se, ukoliko nije, operacija ponovi. Sećate se da se bitovi 4 do 7 na PORTB registru mogu koristiti kao izvori interapta. Ne možete izabrati pojedinačne pinove na PORTB za interapte. Dakle, ukoliko uključite ove pinove, svi postaju dostupni. U čemu je svrha korišćenja 4 bita kao izvora interapta? Primer može biti kućni alarm, čija 4 senzora su povezana na pinove na PORTB registru. Bilo koji senzor može okinuti PIC za uključenje alarma, a rutina za alarm je rutina za obradu interapta. Ovo štedi neprekidno testiranje portova, i rasterećuje mikrokontroler za druge namene. Nažalost njihovim interapt flagom (RBIF INTCON registra) nije moguće izvršiti detekciju interapta na pojedinačnim pinovima, već jedino na svim. U slučaju korišćenja više izvora interapta moguće je da se za vreme interapt rutine izazvane RB0/INT pinom pojavi i interapt na bitovima 4-7 PORTB registra. Stoga je potrebno u samoj interapt rutini testirati prvi interapt flag, u zavisnosti od negovog stanja otići na rutinu za njegovu obradu, i tamo resetovati samo taj interapt flag. Odmah nakon povratka iz potprograma za obradu interapta, izvršiće se interapt izazvan drugim izvorom. Interapt flagovi setuju se bez obzira na stanje GIE bita, kao i pojedinačnih dozvola za interapte (kao u programu sa tajmerom). To može biti iskorišćeno za detekciju njihovih stanja iz samog programa bez korišćenja interapta. Naravno, odgovarajući interapt flag je kao i kod interapta potrebno ručno resetovati nakon detekcije. Budite oprezni prilikom korišćenja potprograma unutar interapt rutine. Ukoliko je u glavnom programu stek skoro pun (a biće pri pozivanju potprograma iz potprograma), još par takvih pozivanja unutar interapt rutine sigurno će izazvati njegovo prekoračenje. Uvek uzmite u obzir najgoru moguću varijantu, tj. da se interapt rutina javlja baš prilikom izvršavanja potprograma najveće dubine. Ne pozivajte iz rutine za obradu interapta potprograme koje već pozivate iz glavnog programa. Ukoliko je to neophodno, prilikom ulaska u interapt rutinu snimite sadržaj svih registara modifikovanih u potprogramu, i vratite ih natrag prilikom izlaska iz interapt rutine.

U sledećem poglavlju videćete program koji koristi interapte.

63

21. Interapti - program Prešli ste dosta teorije u prošlom poglavlju, i došlo je vreme da se upoznate sa programom koji koristi interapte. Program će pri pritiskanju prekidača brojiti od 0 do 7. Rezultat će se prikazivati na 3 LED na PORTA u binarnom obliku. Sam glavni program će samo prikazivati rezultat, a brojanje i testiranje prekoračenja biće realizovani interapt rutinom.

Najpre se mikrokontroler treba podesiti tako da pri izvršavanju programa preskoči deo na koji PC skače pri pojavi interapta. org goto

0x00 Main

; Ovde PC dolazi pri uključenju i resetu ; Odlazak na glavni program

org ; ; ; retfie

0x04

; Ovde će početi rutina za obradu interapta ; Rutina za obradu interapta. Upisaće se kasnije ; Ova instrukcija označava kraj rutine za obradu ; interapta, i vraća PC na glavni program. ; Početak glavnog programa

Main

Onda je potrebno podesiti PIC za korišćenje interapta na pinu 6: bsf bsf

INTCON,GIE INTCON,INTE

; Global interrupt enable (1 – uključi) ; RB0 Interrupt enable (1 – uključi)

64

Za svaki slučaj potrebno je resetovati interapt flag (nikad ne veruj mikrokontroleru): bcf

INTCON,INTF

; Obriši interapt flag

Kako su ovde iskorišćene čak 3 instrukcije za menjanje vrednosti samo jednog registra praktičnije je u pogledu štednje memorije i brzine izvršavanja programa zameniti ih sa dve. movlw

b'10010000'

movwf

INTCON

; bit 7 GIE – Global interrupt enable (1 – uključi) ; bit 4 INTE – RB0 Interrupt enable (1 – uključi) ; bit 1 INTF – Interrupt flag (0 – obriši) ; Inicijalizuj INTCON registar

Sada je potrebno podesiti portove. Sećate se da zbog korišćenja RB0 kao interapt pina, on mora biti postavljen kao ulazni; bsf movlw movwf clrf bcf bcf bcf

STATUS,RP0 ; Prebacuje nas u BANK1 0x01 ; b'00000001' u TRISB TRISB ; RB0/INT kao ulaz, a ostali kao izlaz TRISA ; Svi pinovi na PORTA su izlazni OPTION_REG,INTEDG ; Interapt se izaziva pri ; opadajućoj ivici signala OPTION_REG,NOT_RBPU ; Uključeni interni „pull up“ ; otpornici na PORTB STATUS,RP0 ; Povratak u BANK0

Kako interapt želimo izazivati pri opadajućoj ivici signala (sa +5V na 0V) mora se podesiti i INTEDG bit OPTION_REG registra. Takođe su resetovanjem NOT_RBPU bita uključeni pulll up otpornici. Program će koristiti promenljivu TEMPW za privremeno čuvanje W registra dok se izvršava interapt rutina i promenljivu BROJAC za pamćenje broja pritisnutih prekidača. BROJAC će u programu imati sledeće vrednosti: bitovi 76543210 00000000 .0 00000001 .1 00000010 .2 00000011 .3 00000100 .4 00000101 .5 00000110 .6 00000111 .7 00001000 .8 - prekoračenje Stoga je najpre potrebno imenovati registre i inicijalizovati vrednost BROJAC registra. TEMPW equ BROJAC equ clrf

0x0C 0x0D BROJAC

; TEMPW na adresi 0x0C ; BROJAC na adresi 0x0D ; Stavi 0x00 u BROJAC 65

Dalje je potrebno u glavnom programu napraviti petlju koja će vrednost promenljive BROJAC neprestano prikazivati na PORTA registru. Pri

comf movwf goto

BROJAC,W PORTA Pri

; Invertovani BROJAC u W registar (zbog LED) ; a odatle u PORTA ; Vrati se na početak petlje

Budući da prva pojava interapta nastaje tek kada se program nađe u glavnoj programskoj petlji (Pri), i da u sama petlja ne reaguje na stanje bitova STATUS registra, u interapt rutini nema potrebe za privremenim čuvanjem njegove vrednosti. U interapt rutini potrebno je najpre sačuvati vrednost W registra. movwf

TEMPW

; Privremeno čuvanje sadržaja W registra

Onda je potrebno inkrementovati sadržaj BROJAC registra. incf

BROJAC,F

; Uvećaj registar BROJAC.

Dalje je potrebno proveriti da li je promenljiva BROJAC prekoračila maksimalnu vrednost .7 (b'00000111') i došla do .8 (b'00001000'). Najpraktičnije je izvršiti testiranje trećeg bita BROJAC registra. btfsc clrf

movf bcf retfie

; Testiraj treći bit 00001000 BROJAC registra. ; Ukoliko nije setovan, preskoči sledeću ; instrukciju BROJAC ; Upisi 0x00 u BROJAC ; Ukoliko je BROJAC nakon inkrementacije ; prekoračio maksimalnu vrednost (b'00000111') ; sada je jednak .0 ; Ukoliko nije, sada je inkrementovan. TEMPW,W ; Vrati prethodni sadržaj W registra INTCON,INTF ; Obriši INTF – dozvoli nove interapte ; Kraj interapt rutine. BROJAC,3

Pogledajte sada celokupan program: ; ****** Inicijalizacija i imenovanje ****** list #include __CONFIG ORG TEMPW BROJAC

p=16F84 ; Definiše upotrebljeni mikrokontroler ; Ubacuje nazive registra u program _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC ; Podešava konfiguracione bitove

0x00 equ 0x0C equ 0x0D

; Definiše start programa ; Čuvanje sadržaja W registra na adresi 0x0C ; BROJAC na adresi 0x0D

66

; ****** Interapt rutina ****** org goto

0x00 Main

org movwf incf btfsc

0x04 TEMPW BROJAC,F BROJAC,3

clrf

movf bcf retfie

; Ovde PC dolazi pri uključenju i resetu ; Odlazak na glavni program

; Ovde će početi rutina za obradu interapta ; Privremeno čuvanje sadržaja W registra ; Inkrementuj BROJAC. ; Testiraj treći bit b'00001000' BROJAC registra. ; Ukoliko nije setovan, preskoči sledeću ; instrukciju BROJAC ; Upisi .0 u BROJAC ; Ukoliko je BROJAC nakon inkrementacije ; prekoračio maksimalnu vrednost (.7) ; sada je .0 ; Ukoliko nije, sada je inkrementovan. TEMPW,W ; Vrati prethodni sadržaj W registra INTCON,INTF ; Obriši INTF – dozvoli nove interapte ; Kraj interapt rutine.

; ****** Glavni program – inicijalizacija ****** Main movlw movwf bsf movlw movwf clrf bcf bcf bcf clrf

; bit 7 GIE – Global interrupt enable (1 – uključi) ; bit 4 INTE – RB0 Interrupt enable (1 – uključi) ; bit 1 INTF – Interrupt flag (0 – obriši) INTCON ; Inicijalizuj INTCON registar STATUS,RP0 ; Prebacuje program u BANK1 0x01 ; b'00000001' u TRISB TRISB ; RB0/INT kao ulaz, a ostali kao izlaz TRISA ; Svi pinovi na PORTA su izlazni OPTION_REG,INTEDG ; Interapt se izaziva pri ; opadajućoj ivici signala OPTION_REG,NOT_RBPU ; Uključeni interni „pull up“ ; otpornici na PORTB STATUS,RP0 ; Povratak u BANK0 BROJAC ; Stavi .0 u BROJAC

b'10010000'

; ****** Glavni program – petlja ****** Pri

comf movwf goto

BROJAC,W PORTA Pri

; Invertovani BROJAC u W registar (zbog LED) ; a odatle u PORTA ; Vrati se na početak petlje

; ****** Kraj programa ****** end

; Kraj programa.

Kao što je ranije rečeno RA4 pin ne može na svom izlazu dati logičku jedinicu. U slučaju da se na njega pošalje logička 0, ponašaće se isto kao i ostali pinovi, a u 67

slučaju jedinice, preći će u stanje visoke impedanse (kao da nije ni povezan). Pin RA4 razlikuje se od ostalih i po svom ulazu. Ulaz mu je sa Šmitovim okidačem. To omogućava bolji prijem signala sa prisustvom šuma (npr. sa udaljenog senzora). Kako je ovaj program dat samo ilustrativno, njim nije realizovana debouncing rutina. Prilikom pritiskanja prekidača možete primetiti da se umesto jednog ponekad javi preskok brojeva. Do sada ste naučili 32 instrukcije. Verovatno i sami uočavate da Vam sada veći problem od učenja novih instrukcija predstavlja učenje funkcija registara specijalne namene. U registare koje ste u potpunosti naučili spadaju PORTA, TRISA, PORTB, TRISB, PCL, PCLATH, TMR0 i OPTION_REG. To je osam potpuno i dva delimično (STATUS i INTCON) naučena registra. Sledi još jedan deo sa interaptima, a onda nešto novo.

68

22. Tajmerom izazvani interapti Sećate li se tajmera. Malo je nepraktično sve vreme čekati na promenu njegovog flaga. Praktičnije bi bilo da mikrokontroler za vreme brojanja tajmera obavlja neku drugu operaciju a da se pri setovanju njegovog flaga izvrši interapt rutina. Pogađate, moguće je. Pre nego što naučite kako se to može ostvariti, upoznaćete se sa internom strukturom INTCON registra. bit7 GIE

EEIE

T0IE

INTE

RBIE

T0IF

INTF

bit0 RBIF



GIE (eng. Global Interrupt Enable) omogućava ili zabranjuje upotrebu svih interapta. Njegovim setovanjem, dozvoljena je upotreba interapta.



Setovanjem EEIE (EEPROM Interrupt Enable) omogućen je završetak snimanja u EEPROM kao izvor interapta.



Setovanjem T0IE (eng. Timer0 Interrupt Enable) bita tajmer je upotrebljen kao izvor interapta.



INTE (eng. RB0/INT INTerrupt Enable) bit setovanjem dozvoljava korišćenje RB0 pina mikrokontrolera kao izvora interapta.



Setovanjem RBIE (eng. Port B Change Interrupt Enable) bita, omogućena je upotreba PORTB registra kao izvora interapta pri promeni logičkog stanja na RB4 do RB7 pinovima.



T0IF (eng. Timer0 Interrupt Flag) bit setuje se pri prekoračenju tajmera.



INTF (eng. Interrupt Flag) bit setuje se pri dolasku odgovarajućeg logičkog nivoa (odabranog INTEDG bitom OPTION_REG registra) na RB0 pin mikrokontrolera.



RBIF (eng. Port B Interrupt Flag) setuje se pri promeni logičkog stanja na pinovima RB4 do RB7.

Interapt flagovi se ne resetuju automatski nakon očitavanja. Da bi se dozvolili novi interapti, neophodno je resetovati željeni flag pre izlaska iz interapt rutine. Da bi se tajmer upotrebio kao izvor interapta, dovoljno je dozvoliti njegovo korišćenje setovanjem GIE i T0IE bitova, i resetovanjem njegovog flaga. Sva podešavanja vezana za običan tajmer (preskaler, eksterni takt) važe i u ovom slučaju. Kako je u interapt potprogramima uglavnom neophodno čuvati stanje STATUS registra posebna pažnja mora se obratiti na instrukcije koje prilikom njegovog vraćanja ne utiču (iznova) na promenu njegovog stanja kao što npr. MOVF instrukcija 69

može uticati na izmenu Zero flaga. Zbog toga se preporučuje upotreba SWAPF instrukcije. Swapf (eng. Swap F - zameni) instrukcija menja mesta gornjem i donjem niblu u registru. bit7

bit6

bit5

bit4

bit3

bit2

bit1

bit0

bit3

bit2

bit1

bit0

bit7

bit6

bit5

bit4

Sintaksa instrukcije je swapf f,d pri čemu je f registar nad kojim se izvršava operacija, a sa d je određeno odredište rezultata operacije. Sledi program koji ilustruje upotrebu 3 nezavisna dela. Električna šema ista je kao u prethodnom poglavlju. Prvim delom će LED1 treperiti. To će biti glavni program. Drugim delom će se pri pritisku tastera izazvati interapt koji će menjati stanje LED2. Trećim delom će se tajmerom izazivati interapt koji će menjati stanje LED3. Ova tri dela su samo uslovno nezavisna. Interapt potprogram troši vreme potrebno za izvršavanje svojih instrukcija, pa će u zavisnosti od brzine izvršavanja interapt potprograma (i brzine njenog pojavljivanja) glavni program raditi sporije. Međutim, interapt rutina se uglavnom pravi tako da njeno trajanje bude što kraće, pa tako njeno izvršavanje ne utiče u velikoj meri na brzinu glavnog programa. ; ****** Inicijalizacija i imenovanje ****** list p=16F84 ; Definiše upotrebljeni mikrokontroler #include ; Ubacuje nazive registra u program __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC ; Podešava konfiguracione bitove ORG 0x00 ; Definiše start programa cblock 0x0C TEMPW ; Čuvanje sadržaja W registra TEMPSTATUS ; Čuvanje sadržaja STATUS registra BROJAC1 ; BROJAC1. Inicijalno 0xFF BROJAC2 ; BROJAC2. Inicijalno 0xFF BROJAC3 ; BROJAC3. Inicijalno 0xFF SPORTA ; Shaddow registar za PORTA endc ; ****** Interapt rutina ****** org goto org movwf

0x00 Main 0x04 TEMPW

; Ovde PC dolazi pri uključenju i resetu ; Odlazak na glavni program ; Ovde će početi rutina za obradu interapta ; Čuvanje sadržaja W registra u TEMPW 70

swapf movwf movf

STATUS,W TEMPSTATUS SPORTA,W

; STATUS sa okrenutim niblovima u W ; i zatim u TEMPSTATUS registar ; Shaddow registar u W

; ****** Test interapta izazvanog prekidačem ****** btfss INTCON,INTF ; Interapt izazvan prekidačem? goto Taj ; Nije, idi na deo za tajmerski interapt. ; ****** Rutina za obradu interapta izazvanog prekidačem ****** xorlw b'00000010' ; Promeni stanje bita za LED2 u W ; ****** Izlazak iz interapt rutine izazvane prekidačem ****** call Vrat ; Updatuj PORTA i SHADDOW i ; Vrati stanja W i STATUS registra bcf INTCON,INTF ; Dozvoli nove interapte prekidača retfie ; Povratak iz interapt rutine. ; ****** Update PORTA i SHADDOW i vraćanje ****** ; ****** originalnog stanja W i STATUS registra ****** Vrat movwf PORTA ; Kopiraj W u PORTA movwf SPORTA ; Kopiraj W u Shaddow registar swapf TEMPSTATUS,W ; TEMPSTATUS sa okrenutim niblovima ; u W. Dva puta okrenuti niblovi daju movwf STATUS ; prvobitno stanje koje ide u STATUS swapf TEMPW,F ; Jednom okreni niblove u samom ; TEMPW registru, swapf TEMPW,W ; a drugi put sa W kao odredištem. return ; Kraj potprograma. ; ****** Rutina za obradu interapta izazvanog tajmerom ****** Taj decfsz BROJAC3,f ; Smanji BROJAC3. xorlw b'00000100' ; Promeni stanje bita za LED3 u W ; Gornja instrukcija izvršava se u svim slučajevima kada je vrednost BROJAC3 ; registra od .1 do .255. Kako je i naredna instrukcija ista, dva puta XOR-ovana ; vrednost daje originalno stanje W registra (kao pre XOR operacije). ; Kada je BROJAC3 = 0 gornja instrukcija ona se preskače i izvršava se samo ; jedna (naredna) XOR operacija, koja prouzrokuje željenu promenu stanja bita. xorlw

b'00000100'

; Promeni stanje bita za LED3 u W. ; Ova instrukcija se uvek izvršava.

; ****** Izlazak iz interapt rutine izazvane tajmerom ****** call Vrat ; Updatuj PORTA i SHADDOW i ; vrati stanja W i STATUS registra bcf INTCON,T0IF ; Dozvoli nove interapte tajmera retfie ; Povratak iz interapt rutine.

71

; ****** Glavni program – inicijalizacija ****** Main bsf movlw movwf clrf movlw

movwf bcf clrf clrf movlw

movwf

STATUS,RP0 ; Prebacuje program u BANK1 0x01 ; b'00000001' u TRISB TRISB ; RB0/INT kao ulaz, a ostali kao izlaz TRISA ; b'00000' u TRISA, svi pinovi PORTA su izlazni b'00000111' ; T0CS=0 - Tajmer je sinhronizovan sa ; instrukcijskim ciklusom ; Preskaler - PSA=111 je podešen za odnos 1:256 ; INTEDG=0 - Interapt se izaziva pri ; opadajućoj ivici signala (sa 1 na 0) ; NOT_RBPU=0 - Uključeni interni „pull up“ ; otpornici na PORTB OPTION_REG ; STATUS,RP0 ; Povratak u BANK0 TMR0 ; Inicijalizacija tajmera SPORTA ; Inicijalizacija Shaddow registra b'10110000' ; bit 7 GIE – Global interrupt enable (1 – uključi) ; bit 4 INTE – RB0 Interrupt enable (1 – uključi) ; bit 1 INTF – Interrupt flag (0 – obriši) ; bit 5 T0IE – Timer interrupt enable (1 – uključi) ; bit 2 T0IF – Timer interrupt flag (0 – obriši) INTCON ; Inicijalizuj INTCON registar

; ****** Glavni program – treptanje LED1 ****** Poc bcf INTCON,GIE ; Zabrani nove interapre btfsc INTCON,GIE ; Proveri jesu li interapti zaista zabranjeni goto Poc ; Nisu, zabrani ih opet. movf SPORTA,W ; SHADDOW u W xorlw b'00000001' ; Promeni stanje bita za LED1 u W movwf PORTA ; Kopiraj W u PORTA movwf SPORTA ; Kopiraj W u Shaddow registar bsf INTCON,GIE ; Dozvoli nove inerapte call Pet ; Ubaci kašnjenje goto Poc ; Vrati se na početak ; ****** Potprogram za kašnjenje od oko 0,2S ****** Pet decfsz BROJAC1,F ; Ove dve petlje služe za brojanje nadole od goto Pet ; 255 do 0, 255 puta, omogućavajući nam da decfsz BROJAC2,F ; možemo videti kako LED1 treperi goto Pet return ; Povratak iz potprograma ; ****** Kraj programa ****** end

; Kraj programa

Možete se zapitati zašto su upotrebljene dve swapf instrukcije pri vraćanju TEMPW u W, kada se isto moglo realizovati i movf TEMPW,W instrukcijom. Razlog je taj što će mowf instrukcija setovati Zero flag u slučaju da je u W bila vrednost 0x00, dok je 72

swapf instrukcija neutralna prema svim flagovima. Slično važi i za STATUS registar. Ukoliko je odredište instrukcije koja menja stanje flagova STATUS registra sam STATUS registar, njegovi flagovi postaviće se u zavisnosti od rezultata instrukcije, bez obzira na stanje bajta koji želimo poslati u njega. U delu sa testiranjem interapta možete primetiti da je testiran samo interapt flag prekidača. To je sasvim normalno, jer nešto mora da je izazvalo interapt kada se već ušlo u interapt rutinu. Ukoliko to nije bio prekidač, onda je sigurno bio tajmer Ukoliko su oba interapta nastupila istovremeno (setovana oba interapt flaga), najpre će se izvršiti interapt rutina prekidača, ali po povratku iz interapt potprograma odmah će se izazvati novi interapt jer je interapt flag tajmera i dalje setovan. Sigurno ste u delu za obradu tajmerskog interapta uočili neobičnu realizaciju kašnjenja. Ono se moralo izvesti na taj način (u prolazu) jer se ne sme dozvoliti da preveliko kašnjenje interapt potprograma koči izvršenje glavnog programa. U glavnom programu interapti su privremeno zabranjeni da se stanje SPORTA registra ne bi promenilo interapt rutinom za vreme njegove promene od strane glavnog programa. Testiranje zabrane svih interapta takođe je neophodno (pogledajte napomene uz interapte). Dosta je bilo interapta. Sledi nešto sasvim drugačije.

73

23. Indirektno adresiranje Sećate li se tabele? Kod nje je skok na željenu lokaciju izvršen sabiranjem PCL sa W. Nešto slično ali u odnosu na registre, moguće je postići korišćenjem FSR i INDF registra. INDF registar nije fizički registar. Njegovo adresiranje u stvari adresira registar čija adresa je sadržana u FSR registru (FSR je pointer adrese željenog registra). Takav postupak naziva se indirektno adresiranje. Pretpostavite da PORTA sadrži vrednost 0x03, a PORTB 0x2B. Ukoliko u FSR ubacite adresu PORTA registra (0x05), i pročitate sadržaj registra INDF, dobićete vrednost 0x03. Ukoliko sada inkrementujete FSR, on će ukazivati na PORTB (0x06). Sada će očitavanje vrednosti iz INDF registra vratiti vrednost 0x2B. Isto tako je moguće i upisivanje podataka u željene registre. Sledeći program ilustruje upisivanje vrednosti 0x00 u registre od 0x20 do 0x2F.

Pet

movlw movwf clrf incf btfss goto

b'00100000' ; Inicijalizacija pointera FSR ; na registar 0x20 INDF ; Indirektno brisanje željenog registra FSR,F ; Pozicioniranje pointera na sledeći registar FSR,4 ; Prekoračenje? 0x30 = b'00110000' Pet ; Nije, nastavi sa brisanjem

; Jeste, nastavak programa. Za razliku od tabele, zbog malog broja registara kod upotrebe indirektnog adresiranja nema ograničenja u smislu blokova podataka (bar kod PIC16F84 mikrokontrolera – kod mikrokontrolera sa većim brojem registara ovo nije slučaj). Indirektno adresiranje se u programima najčešće upotrebljava jedino u slučaju veće količine podataka. Do sada ste naučili 33 od 35 instrukcija, potpunu upotrebu deset registra i delimičnu upotrebu dva registra od ukupno 15. Prešli ste najveći (i najteži – interapti) deo gradiva, međutim ima se još mnogo toga naučiti.

74

24. EEPROM memorija Zamislite da imate PIC koji preko sistema fotoćelija broji posetioce koji su ušli kroz ulazna vrata banke, kao i one koji su izašli kroz izlazna vrata, i na osnovu broja lica u banci reguliše rad senzora pokreta, osvetljenja i klima uređaja. Kako ne biste želeli da išta prepustite slučaju, mikrokontroler radi sa uključenim WDT. Međutim, elektrodistribucija se postara da ne bude sve tako idealno i odjednom nestane struje. Kako banka ne bi bila banka ukoliko nema neku rezervu, 2 sekunde nakon nestanka struje uključuje se elektroagregat (što ne sprečava reset kompjutera i zabrinuto „Jao dođite kasnije, ne rade nam terminali“), i PIC (koji se takođe resetovao) kreće sa radom inicijalizujući u svom brojaču 1 osobu (u normalnom radu onoga ko prvi dolazi na posao). Nakon što se broj osoba u banci smanji za 1 osobu (što može nastati i mnogo kasnije, jer su klijenti banke čuli da je legla plata), prestaju da rade klima uređaji i osvetljenje, a senzori pokreta uključuju alarm i dojavljuju pljačku banke policiji. Znam znam. Jedan manji akumulator ili UPS rešio bi problem. Ali direktor banke ni da čuje. To direktno poskupljuje projekat. Pa nije valjda džabe kupio agregat! U ovom slučaju potrebno je da PIC i nakon nestanka napona napajanja zapamti vrednost promenljive BROJAC (ili više promenljivih ukoliko je broj osoba koje mogu stati u prostoriju veći od 255). Po dolasku napona napajanja ove vrednosti trebaju se pročitati, i prebaciti u odgovarajuće registre. Unutar PIC16F84 nalazi se 64 bajta EEPROM memorije (0x00–0x3F). Za razliku od registara koji su obična RAM memorija, ova memorija zadržava svoje stanje i nakon nestanka napona napajanja mikrokontrolera. Nažalost zbog fizičkih osobina EEPROM memorije rad sa njom nije ni izdaleka tako jednostavan kao rad sa običnim RAM registrima. Pored indirektnog adresiranja (za šta se koriste registri EEADR (eng. EEPROM Adress) i EEDATA (eng. EEPROM Data)) potrebno je inicirati proces čitanja ili snimanja bajta, što se vrši preko EECON1 (eng. EEPROM Controller1) i EECON2 (eng. EEPROM Controller2) registra. Pre nego što naučite čitanje i snimanje u EEPROM, upoznajte internu strukturu EECON1 registra. bit7 /

/

/

EEIF

WRERR

WREN

WR

bit0 RD



Bitovi 5 do 7 se ne koriste u EECON1 registru. Trebaju biti na logičkoj nuli.



EEIF (eng. EEPROM Interrupt Flag) bit predstavlja flag interapta izazvanog završetkom procesa snimanja bajta. Ovaj interapt može se dozvoliti setovanjem EEIE (eng. EEPROM Interrupt Enable) bita INTCON registra. Potrebno ga je ručno obrisati pre povratka iz interapt rutine. 75



WRERR (eng. Write Error) bit indikuje prekid snimanja bajta u EEPROM, usled isteka vremena WDT ili eksternog reseta mikrokontrolera. Program može nakon reseta testirati ovaj bit (uz to mora otkriti i da li je reset nastao usled nestanka napona napajanja ili ne), i na osnovu njegovog stanja dovršiti proces snimanja (sadržaj EEADR i EEDATA registra ne menja se nakon reseta).



WREN (eng. Write Enable) bit mora biti setovan, da bi bio moguć upis u EEPROM.



WR (eng. Write) bit koristi se za iniciranje upisa u EEPROM memoriju.



RD (eng. Read) bit koristi se za iniciranje čitanja iz EEPROM memorije.

Pogledajte najpre primer čitanja memorijske adrese 0x10 iz EEPROM memorije. bcf movlw movwf bsf bsf

STATUS,RP0 0x10 EEADR STATUS,PR0 EECON1,RD

bcf movf

STATUS,RP0 EEDATA,W

; Prebacuje nas u BANK0 zbog EEADR ; Želimo pročitati sadržaj EEPROM ; memorije sa adrese 0x10 ; Prebacuje nas u BANK1 ; Inicira proces čitanja ; EEPROM memorije ; Prebacuje nas u BANK0 ; Sadržaj bajta sa adrese 0x10 ; iz EEPROM memorije je u EEDATA, ; odakle se može prebaciti u W

Ovaj program trebao bi da Vam je u potpunosti jasan. Setovanjem RD bita iniciran je proces čitanja, a zatim se RD bit automatski nakon čitanja vraća na 0. Podatak iz EEPROM memorije dostupan je u EEDATA registru odmah u narednom instrukcijskom ciklusu, odakle je premešten u W registar. Pogledajte sada kako je realizovano snimanje bajta 0x24 u EEPROM adresu 0x10. bcf movlw movwf movlw movwf bsf bcf bsf

STATUS,RP0 0x24 EEDATA 0x10 EEADR STATUS,RP0 INTCON,GIE EECON1,WREN

; Prebacuje nas u BANK0 ; Bajt za snimanje ; u EEDATA ; na adresu ; 0x10 ; Prelaz u BANK1 zbog EECON1 ; Zabrana svih interapta (ukoliko ih ima) ; Dozvola pisanja u EEPROM

movlw movwf movlw movwf bsf bsf bcf

0x55 EECON2 0xAA EECON2 EECON1,WR INTCON,GIE EECON1,WREN

; ; ; Inicijalizacija upisa u EEPROM ; ; ; Dozvola interapta (ukoliko se koriste) ; Zabrana daljeg pisanja u EEPROM 76

Snimanje u EEPROM neće se inicirati ukoliko nije tačno ispoštovana procedura (0x55 u EECON2, 0xAA u EECON2, setovan WR) i to bez pauza (otud zabrana interapta) za svaki pojedinačni bajt. Microchip navodi da je ta procedura uvedena kako bi se sprečio nehotičan upis u EEPROM zbog mogućih grešaka u programu. Iz istog razloga WREN bit je potrebno držati setovanim jedino za vreme upisa u EEPROM. WR bit se automatski resetuje po završetku upisa. U slučaju serijskog snimanja podataka u EEPROM, potrebno je pre sledećeg snimanja proveriti stanje ovog bita, kako se ne bi desilo iniciranje novog upisa u EEPROM a da prethodno snimanje još nije završeno. To je obavezno, jer snimanje u EEPROM nije sinhronizovano sa instrukcijskim ciklusom, već se za upis u EEPROM koristi poseban interni oscilator, koji određuje vreme upisa od oko 10mS. Kod čitanja podataka iz EEPROM memorije nema ovakvih problema. Umesto testiranja flaga moguće je i jednostavno sačekati dovoljno dugo (npr. 12mS). Možda Vam se mere inicijalne procedure i WRERR bita čine preteranim. Ali zapitajte se šta bi se desilo ukoliko bi u EEPROM memoriji čuvali npr. obrasce za prikaz broja na LED displeju. U slučaju korupcije EEPROM memorije PIC ni nakon reseta ne bi mogao nastaviti sa normalnim radom. Morao bi se odlemiti sa štampane pločice i ponovo programirati (u mikrokontroler se sa programom snima i sadržaj EEPROM memorije). U sledećem poglavlju upoznaćete se sa programom koji koristi EEPROM memoriju i naučićete upotrebu EEIF bita i proces upisa podataka u EEPROM iz samog asemblera. Na taj način se sadržaj EEPROM memorije može čuvati zajedno sa programom u jednom .asm ili .hex fajlu.

77

25. EEPROM i interapti Sećate li se onog teškog? Da, interapta. U njihovim osnovnim podacima navedeno je da se mogu koristiti 4 izvora interapta. Dva hardverska (željena promena stanja na INT pinu i promena stanja na pinovima RB4-RB7) i dva softverska (prekoračenje tajmera i završetak slanja podatka u EEPROM). Ima li svrhe koristiti završetak slanja podatka u EEPROM kao izvor interapta? Teško. Sav proces može se završiti linijskim kôdom. Opravdanje njenog korišćenja može se naći u vremenski kritičnim programima kod kojih je potrebno za vreme snimanja u EEPROM izvršavati druge operacije, kako mikrokontroler ne bi gubio vreme čekajući (čak 10mS) na završetak snimanja. Bolje je da program umesto čekanja na završetak upisa u EEPROM radi nešto korisno. Sada ćete se upoznati sa programom koji po pritisku na taster menja stanje na LED displeju od 9 do 0, i snima ga u EEPROM. Po isključenju napona napajanja i njegovom ponovnom dovođenju, na LED displeju naći će se poslednja zapamćena vrednost (to je i bio cilj u primeru sa bankom). Glavni program imaće jedino funkciju učitavanja i snimanja trenutnih vrednosti u EEPROM, a interapt rutinom će se realizovati sve ostalo (test prekidača, smanjenje broja, prikaz na displeju). Kod ovakvog programa očigledno je da interapt rutina traje daleko duže od samog glavnog programa. To se ovde može tolerisati. Električna šema je ista kao u delu sa tabelama. ; ****** Inicijalizacija i imenovanje ****** list p=16F84 ; Definiše upotrebljeni mikrokontroler #include ; Ubacuje nazive registra u program __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC ; Podešava konfiguracione bitove cblock 0x0C TEMPW ; Privremeno čuvanje W registra TEMPSTATUS ; Privremeno čuvanje STATUS registra BROJAC ; Brojač za bebouncing pauzu. Inicijalno 0xFF DISP ; Broj koji se prikazuje na endc ; displeju i snima (0x09 – 0x00) ; ****** Inicijalizacija vrednosti u EEPROM memoriji ****** org 21x00 ; Početak EEPROM memorije de 0x00 ; Inicijalizacija početne vrednosti na ; displeju ; ****** Interapt rutina – čuvanje sadržaja registra ****** org goto org movwf swapf movwf

0x00 Main 0x04 TEMPW STATUS,W TEMPSTATUS

; Ovde PC dolazi pri uključenju i resetu ; Odlazak na glavni program ; Ovde će početi interapt rutina ; Čuvanje sadržaja W registra u TEMPW ; STATUS sa okrenutim niblovima u W ; i zatim u TEMPSTATUS registar 78

; ****** Test prekidača ****** bcf STATUS,RP0 Cek1 btfss goto goto btfss goto Cek2 btfsc goto goto btfsc goto

PORTB,0 Cek1 Pau PORTB,0 Cek1 PORTB,0 Cek2 Pau PORTB,0 Cek2

; Povratak u BANK0 – u glavnom ; programu pre skoka na interapt rutinu ; program se izvršavao u BANK1 ; Testiranje otpuštenosti prekidača ; Nije otpušten ; Jeste otpušten. Idi na pauzu. ; Još jedno testiranje zbog imunosti na ; eventualna varničenja kontakta. ; Testiranje pritisnutosti prekidača ; Nije pritisnut ; Jeste pritisnut. Idi na pauzu. ; Još jedno testiranje zbog imunosti na ; eventualna varničenja kontakta.

; ****** Prikaz cifre na displeju ****** movf DISP,W ; DISP u W call Tabl ; Uzmi obrazac iz tabele, movwf PORTB ; i prikaži cifru na displeju. ; ****** Testiranje prekoračenja vrednosti cifre na displeju ****** decf DISP,F ; Smanji DISP za 1. Rezultat u DISP btfss DISP,7 ; Testiraj MSB. On će biti 1 jedino ukoliko je ; došlo do prekoračenja sa 0x00 na 0xFF goto Povr ; Nije, izađi iz interapt rutine movlw 0x09 ; Jeste, inicijalizuj brojac na movwf DISP ; vrednost 0x09 Povr swapf

TEMPSTATUS,W

movwf swapf

STATUS TEMPW,F

swapf bcf retfie

TEMPW,W EECON1,EEIF

; TEMPSTATUS sa okrenutim niblovima ; u W. Dva puta okrenuti niblovi daju ; prvobitno stanje koje ide u STATUS ; Jednom okreni niblove u samom ; TEMPW registru, ; a drugi put sa W kao odredištem. ; Dozvola novih interapta ; Kraj interapt rutine.

; ****** Glavni program – inicijalizacija ****** Main bsf STATUS,RP0 ; Prebacuje program u BANK1 bcf EECON1,EEIF ; Reset interapt flaga movlw b'11000000' ; GIE=1 – Global interrupt enable movwf INTCON ; EEIE=1 – EEPROM interrupt enable movlw b'00000000' ; NOT_RBPU=0 - Uključeni interni movwf OPTION_REG ; pull up otpornici na PORTB movlw 0x01 ; b'00000001' u TRISB movwf TRISB ; RB0/INT kao ulaz, a ostali kao izlaz clrf TRISA ; Svi pinovi na PORTA su izlazni bcf STATUS,RP0 ; Povratak u BANK0

79

; ****** Čitanje iz EEPROM memorije ****** movlw 0x00 ; Želimo pročitati sadržaj EEPROM movwf EEADR ; memorije sa adrese 0x00 bsf STATUS,PR0 ; Prebacuje program u BANK1 bsf EECON1,RD ; Inicira proces čitanja ; EEPROM memorije bcf STATUS,RP0 ; Prebacuje program u BANK0 movf EEDATA,W ; Sadržaj bajta sa adrese 0x00 iz ; EEPROM memorije u W ; ****** Inicijalizacija brojača i LED displeja ****** movwf DISP ; Inicijalizacija brojača call Tabl ; Uzmi obrazac iz tabele i movwf PORTB ; Prikaži cifru na displeju ; ****** Snimanje u EEPROM ****** Gla movf DISP,W movwf EEDATA movlw 0x00 movwf EEADR bsf STATUS,RP0 bsf EECON1,WREN movlw 0x55 movwf EECON2 movlw 0xAA movwf EECON2 bsf EECON1,WR Kraj btfss goto

EECON1,WR Kraj

; DISP u W ; pa u EEDATA ; na adresu ; 0x00 ; Prebacuje nas u BANK1 zbog EECON1 ; Dozvola pisanja u EEPROM ; ; ; Otključavanje upisa u EEPROM ; ; ; Test završetka snimanja

; U ovom trenutku snimanje je završeno pa se interapt flag setuje i nastaje interapt. U interapt rutini čekaće se na pritisak prekidača, smanjiće se vrednost na displeju i tek onda će se izaći iz nje i nastaviti dalji program. bcf bcf goto

EECON1,WREN STATUS,RP0 Gla

; Zabrana pisanja u EEPROM ; Povratak u BANK0 ; Povratak na početak programa

; ****** Tabela ****** Tabl movf DISP,W ; U promenljivoj DISP nalazi se vrednost od addwf PCL,f ; .0 do .9. Ta vrednost se dodaje na PCL. retlw b'01111110' ; Obrazac za crtanje cifre 0 - 0 retlw b'00001100' ; Obrazac za crtanje cifre 1 - 1 retlw b'10110110' ; Obrazac za crtanje cifre 2 - 2 retlw b'10011110' ; Obrazac za crtanje cifre 3 - 3 retlw b'11001100' ; Obrazac za crtanje cifre 4 - 4 retlw b'11011010' ; Obrazac za crtanje cifre 5 - 5 retlw b'11111010' ; Obrazac za crtanje cifre 6 - 6 80

retlw retlw retlw

b'00001110' b'11111110' b'11011110'

; Obrazac za crtanje cifre 7 ; Obrazac za crtanje cifre 8 ; Obrazac za crtanje cifre 9 -

7 8 9

; ****** Pauza zbog debouncing rutine ****** Pau decfsz BROJAC,F ; Pauza zbog debouncing goto Pau ; rutine return ; Povratak iz potprograma ; ****** Kraj programa ****** end

; Kraj programa

Prilikom snimanja kôda u PIC16F84 mora se sadržaj memorijske adrese 0x00 u EEPROM memoriji podesiti na proizvoljan broj između 0x00 i 0x09. U protivnom će mikrokontroler uzeti inicijalno stanje iz EEPROM memorije (0xFF) i pri nailasku na tabelu izvršavanje programa će se nastaviti za 245 bajtova iza same tabele, što će izazvati nepravilan rad (tačnije resetovanje) mikrokontrolera. To je u programu učinjeno upotrebom DE (eng. Define EEPROM) direktive. Njom se jedan (ili više) bajtova smeštaju u EEPROM. Budući da je za nju potrebno prethodno definisati početak upisa u EEPROM memoriju (org direktivom i adresama od 21x00 do 21x3h), najpraktičnije je staviti je ispred ili iza programa, kako se ne bi desilo da se i program greškom upiše u EEPROM. Pri smeštanju više bajtova u EEPROM, možete bajt po bajt iza DE direktive odvojiti zarezom, ovako: de 0x05, 0xA8, 0x79... Iako izgleda da je EEPROM na neki način produžetak programske memorije, razlika svakako postoji. U EEPROM memoriji nije moguće izvršavati programe, isto kao što se ni iz programa ne može čitati (a ni menjati) sadržaj programske memorije (bar kod PIC16 serije). Možda ste primetili da u rutini za snimanje u EEPROM nije izvršena zabrana korišćenja svih interapta resetovanjem GIE bita. Ukoliko bi se interapti zabranili, program ne bi skočio na interapt rutinu, i neprestano bi se vrteo u petlji snimajući jedan isti bajt u EEPROM adresu 0x00. Ukoliko bi se ovo dovoljno dugo ponavljalo, ova EEPROM adresa bi se usled starenja pokvarila (kao ogrebotina na DVD disku). Jedna EEPROM memorijska lokacija može se menjati do 1 milion puta. Sve preko ove vrednosti povećava verovatnoću nastupa kvara adrese. Naravno, ukoliko se koristi više izvora interapta, ostali bi se morali privremeno zabraniti. Budući da ćete se u idućem poglavlju upoznati sa uspavanim stanjem mikrokontrolera, vreme je da naučite jednu lenju instrukciju. To je NOP (eng. No Operation). Ova instrukcija, osim što traje jedan instrukcijski ciklus ne radi ništa korisno. Kada program mikrokontrolera naiđe na nju, utrošiće jedan instrukcijski ciklus nizašta. Preći će preko nje, kao da je nema. Uglavnom se koristi u situacijama kada je potrebno realizovati tačno određeno, ili kratko kašnjenje (npr. u petljama kašnjenja ili debouncing rutini).

81

26. Sleep mod - pojam Pretpostavimo da želite napraviti hidroelektranu. Da biste proverili da li reka ima dovoljan protok vode tokom cele godine, odlučili ste da merite njen nivo mikrokontrolerom, i da prikupljene podatke povremeno (po popuni EEPROM memorije) prebacujete u laptop. Kako na reci nema električne mreže, mikrokontroler se napaja iz akumulatora. Negativni pol akumulatora (masa) spojen je sa rekom, a očitavanje nivoa vode se vrši interaptom pri promeni stanja na pinovima RB4 do RB7, koji su povezani sa odgovarajućim sondama na po 5cm dubine. Kada je nivo vode ispod najniže sonde, na svim pinovima je logička 1 (uključeni su interni pull up otpornici). Kada je nivo vode iznad najvišlje, voda se ponaša kao provodnik između mase i sondi, tako da je na svim pinovima logička 0. Mikrokontroler je povezan sa digitalnim časovnikom i dodatnom EEPROM memorijom, koji mu omogućavaju memorisanje tačnog trenutka rasta ili opadanja nivoa vode. Očigledno je da u aktivnom stanju mikrokontroler radi samo povremeno (u trenutku povećanja ili smanjenja nivoa vode), i veoma kratko (vreme potrebno za čitanje tačnog vremena iz sata, i upis vremena i nivoa vode u EEPROM memoriju). Kako će tokom 24h najverovatnije nastupiti jedan period plime i oseke, to iznosi samo oko 8 merenja dnevno. Preostalo vreme mikrokontroler će se vrteti u praznoj petlji čekajući na interapt, i bespotrebno trošeći struju iz akumulatora. SLEEP „spavajući“ mod predstavlja stanje u kojem se mikrokontroler nalazi u režimu smanjene potrošnje energije. U SLEEP modu blokira se rad glavnog oscilatora. Instrukcije se prestaju izvršavati, tajmer prestaje sa radom, a WDT se (ukoliko je uključen) resetuje (ali nastavlja sa radom zbog sopstvenog oscilatora). Portovi zadržavaju svoja stanja (izlaz – 0, izlaz – 1 ili ulaz – stanje visoke impedanse). Za najmanju moguću potrošnju potrebno je projektovati spoljna elektronska kola tako da ne vuku struju iz izlaznih pinova portova, i da ulazne pinove postave na stabilan logički nivo (0 ili 1). RA4/T0CKI pin bi takođe trebao biti na stabilnom nivou (ne bi smeo biti izlazni sa logičkom 1 jer je ne može dati). Napon napajanja mikrokontrolera može se spustiti i do 1,5V bez gubitka podataka. Potrošnja mikrokontrolera pada sa oko 2mA na oko 5μA. Ukoliko Vam je potrošnja struje izuzetno bitna, možete kupiti verzuju mikrokontrolera specijalno napravljenu za rad sa što manjom potrošnjom struje. U SLEEP mod ulazi se SLEEP instrukcijom, a iz njega se mikrokontroler može „probuditi“ na tri načina. 1. Dovođenjem logičke nule na MCLR pin mikrokontrolera, što prouzrokuje reset mikrokontrolera. Više o resetu, u idućim poglavljima. 2. Resetom preko isteka vremena WDT. 3. Interaptom na RB0/INT pinu, interaptom pri promeni stanja na PORTB registru, bitovima 4 do 7, ili interaptom izazvanim završetkom upisa u EEPROM. 82

Interapt izazvan tajmerom ne može se koristiti za buđenje iz SLEEP moda, jer je u SLEEP modu i tajmer uspavan. Ulaskom u SLEEP mod, menja se stanje određenih bitova STATUS registra. Vreme je da napokon proučite i njegovu unutrašnju strukturu. bit7 /

/

RP0

TO

PD

Z

DC

bit0 C



Bitovi 7 i 6 ne koriste se u PIC16F84. Trebaju biti u stanju logičke 0.



Bit 5 (RP0) koristi se kod direktnog adresiranja za izbor banke podataka po sledećem : 0 - BANK0 – 0x00-0x7F 1 - BANK1 – 0x80-0xFF



TO (eng. Time-Out) „prekoračenje vremena“ bit je na stanju logičke 0 nakon isteka WDT, a u stanju logičke 1 po dolasku napona napajanja, i izvršenju CLRWDT ili SLEEP instrukcije. Na osnovu stanja ovog bita program može detektovati da je reset mikrokontrolera nastao usled prekoračenja WDT.



PD (eng. Power-Down) bit postavlja se na 1 po dolasku napona napajanja ili izvršenju CLRWDT instrukcije, a na 0 po izvršenju SLEEP instrukcije.



Logička jedinica na Zero “nultom” bitu pokazuje da je rezultat zadnje aritmetičke ili logičke operacije jednak 0. Logička nula na ovom bitu ukazuje da je rezultat različit od 0.



DC (eng. Digit Carry/borrow) bit „bit prekoračenja/pozajmice cifre“ indikuje prekoračenje ili pozajmicu donjem niblu nastalu zbog izvršavanja instrukcija sabiranja ili oduzimanja.



Logička jedinica na C (eng. Carry/borrow) bitu „bitu prekoračenja/pozajmice“ ukazuje da je došlo do prekoračenja ili pozajmice u bajtu nad kojim su se izvršile operacije sabiranja, oduzimanja ili rotacije.

Kao što vidite iz samog STATUS registra, izvršenje SLEEP instrukcije prouzrokuje resetovanje PD bita i setovanje TO bita. Možda vam čudno izgleda buđenje iz SLEEP moda istekom WDT. On se u mikrokontroleru koristi za povremeno buđenje iz SLEEP moda, obavljanje određene operacije, i ponovni ulazak u SLEEP mod. Tako mikrokontroler može povremeno izvršiti poneku operaciju, a opet će većinu vremena provesti spavajući (i trošeći manje struje). Kako istek WDT prouzrokuje softverski reset mikrokontrolera program mora po resetu testirati TO bit, i na osnovu njegovog stanja zaključiti da li se radi o prvom uključenju mikrokontrolera, ili o prekidu nastalom istekom WDT, kako bi se mogao nastaviti započeti program. U praksi se mnogo češće sreće buđenje interaptima. U sledećem poglavlju upoznaćete se sa specifičnostima upotrebe interapta u SLEEP modu. 83

27. Buđenje iz Sleep moda Buđenje iz SLEEP moda interaptima razlikuje se od običnih interapta po tome što je moguće da se umesto skoka na interapt rutinu, izvršavanje programa nastavi iza SLEEP instrukcije. Naime, ukoliko je u SLEEP modu GIE setovan, pri interaptu će se mikrokontroler probuditi i skočiti na interapt rutinu, kao u običnom programu. Ali, ukoliko je GIE resetovan, pri interaptu (dozvoljenim odgovarajućim interapt flagom) će se probuditi i nastaviti dalje izvršenje programa, bez skoka na interapt rutinu. U zavisnosti od trenutka sticanja uslova za pojavu interapta moguće je da se interapt dogodi neposredno pre SLEEP instrukcije. U tom slučaju, SLEEP instrukcija se neće izvršiti, pa neće biti resetovan WDT i njegov preskaler, resetovan PD bit i setovan TO bit. Zbog toga je potrebno ručno resetovati WDT (ukoliko se koristi) neposredno pre SLEEP instrukcije. U slučaju da je potrebno saznati da li se izvršila SLEEP instrukcija, to se može proveriti testiranjem PD bita STATUS registra. Sada ćete se upoznati sa programom koji ilustruje upotrebu SLEEP moda i buđenje iz njega na oba načina (sa setovanim i resetovanim GIE). Program se sastoji iz dva dela. U prvom delu, program ulazi u SLEEP mod, i od korisnika se zahteva da postavi kombinaciju tastera T1 do T4. Prilikom svake promene stanja tastera izaziva se interapt (tasteri su povezani na pinove RB4 do RB7) i odabrana kombinacija se prikazuje na LED displeju u heksadecimalnom formatu. Nakon postavljenog željenog broja pritisne se T5 izazivajući novi interapt (RB0). Stanje postavljeno na displeju snima se u memoriju mikrokontrolera primenom indirektnog adresiranja. Postupak se ponavlja sve dok se ne snimi 5 kombinacija. U drugom delu, mikrokontroler se ponovo uspavljuje ali tako da interapt prouzrokuje njegovo buđenje i nastavak programa bez skoka na interapt rutinu. Po izazivanju interapta (T5) snimljene kombinacije se čitaju i prikazuju na displeju sa uključenom decimalnom tačkom (segment dp na displeju). Nakon 5 prikazanih kombinacija, program se ponavlja iz početka. Kako je zbog interapta i internih pull up otpornika potrebno da prekidači budu na portu B, slika će se na displeju prikazivati kombinacijom pinova PORTA i PORTB registra (tačnije pinovima RA0 do RA4 i RB1 do RB3). ; ****** Inicijalizacija i imenovanje ****** list p=16F84 ; Definiše upotrebljeni mikrokontroler #include ; Ubacuje nazive registra u program __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC ; Podešava konfiguracione bitove cblock 0x0C TEMPW ; Promenljiva za W registar TEMPSTATUS ; Promenljiva za STATUS registar TEMP ; Promenljiva za rotaciju endc ; .32 – .36 RAM memorija za snimanje stanja prekidača org goto

0x00 Main

; Ovde PC dolazi pri uključenju i resetu ; Odlazak na glavni program 84

; ****** Interapt rutina za prvi deo programa – normalne interapte ****** org 0x04 ; Ovde će početi interapt rutina movwf TEMPW ; Čuvanje sadržaja W registra u TEMPW swapf STATUS,W ; STATUS sa okrenutim niblovima u W movwf TEMPSTATUS ; i zatim u TEMPSTATUS registar swapf andlw

PORTB,W ; Uzmi stanje sa porta i zameni stanje niblova. b'00001111' ; Maskiraj neželjene bitove

; ****** Test interapta izazvanog prekidačem ****** btfss INTCON,INTF ; Interapt izazvan prekidačem T5? goto T14 ; Nije, idi na deo za prekidače T1 do T4. ; ****** Interapti izazvani prekidačem T5 ****** movwf INDF ; Indirektno snimanje u željeni registar incf FSR,F ; Pozicioniranje pointera na sledeći registar call Vrat ; Vrati sadržaj W i STATUS registra bcf INTCON,INTF ; Obriši interapt flag prekidača T5 retfie ; Vrati se iz interapt potprograma ; ****** Interapti izazvani prekidačima T1 do T4 ****** call Tabl ; Uzmi sliku za displej iz tabele. 85

call call bcf retfie Vrat swapf

Nacr ; Nacrtaj sliku. Vrat ; Vrati sadržaj W i STATUS registra INTCON,RBIF ; Obriši interapt flag prekidača T1 do T4 ; Vrati se iz interapt potprograma TEMPSTATUS,W

movwf swapf

STATUS TEMPW,F

swapf return

TEMPW,W

; TEMPSTATUS sa okrenutim niblovima ; u W. Dva puta okrenuti niblovi daju ; prvobitno stanje koje ide u STATUS ; Jednom okreni niblove u samom ; TEMPW registru, ; a drugi put sa W kao odredištem. ; Povratak iz potprograma.

; ****** Tabela ****** Tabl addwf PCL,F retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw

; Vrednost u W od b'00000000' do b'00001111' ; (0x00 do 0x0F) se dodaje na PCL ; bez decimalne tačke b'00011000' ; Obrazac za crtanje cifre 0 - 0 b'00111111' ; Obrazac za crtanje cifre 1 - 1 b'10010100' ; Obrazac za crtanje cifre 2 - 2 b'00010110' ; Obrazac za crtanje cifre 3 - 3 b'00110011' ; Obrazac za crtanje cifre 4 - 4 b'01010010' ; Obrazac za crtanje cifre 5 - 5 b'01010000' ; Obrazac za crtanje cifre 6 - 6 b'00011111' ; Obrazac za crtanje cifre 7 - 7 b'00010000' ; Obrazac za crtanje cifre 8 - 8 b'00010010' ; Obrazac za crtanje cifre 9 - 9 b'00010001' ; Obrazac za crtanje cifre A- A b'01110000' ; Obrazac za crtanje cifre B - B b'11010000' ; Obrazac za crtanje cifre C - C b'00110100' ; Obrazac za crtanje cifre D - D b'11010000' ; Obrazac za crtanje cifre E - E b'11010001' ; Obrazac za crtanje cifre F - F

; ****** Potprogram za crtanje slike na displeju ****** Nacr movwf PORTA ; Pošalji u PORTA bitove RA0 do RA4 movwf TEMP ; Pošalji u TEMP registar zbog zamene niblova swapf TEMP,W ; Zameni mesta niblovima tako da RB1 bit dodje ; na mesto bita 1 (isto se moglo realizovati ; i sa 4 RRF instrukcije) movwf PORTB ; Pošalji u PORTB bitove RB1 do RB3 return ; Povratak iz potprograma. ; ****** Glavni program – inicijalizacija ****** Main bsf STATUS,RP0 ; Prebacuje program u BANK1 movlw b'11110001' ; pinovi RB0 i RB4 do RB7 ulazni, movwf TRISB ; a RB1, RB2 i RB3 izlazni. clrf TRISA ; Svi pinovi porta A izlazni movlw b'00000000' ; INTEDG=0 - Interapt se izaziva pri 86

movwf bcf Opet movlw movwf

OPTION_REG STATUS,RP0 .32 FSR

; opadajućoj ivici signala (sa 1 na 0) ; NOT_RBPU=0 - Uključeni interni ; pull up otpornici na PORTB ; Povratak u BANK0

; Inicijalizacija pointera RAM memorije ; na registar .32

; ******* Postavi sliku na displeju pre uključenja interapta ****** swapf PORTB,W ; Uzmi stanje sa porta i zameni stanje niblova. andlw b'00001111' ; Maskiraj neželjene bitove call Tabl ; Uzmi sliku za displej iz tabele. call Nacr ; Nacrtaj sliku. ; ****** Uključi interapte ****** bsf STATUS,RP0 ; Prebacuje program u BANK1 movlw b'10011000' ; GIE – Global interrupt enable (1 – uključi) ; INTE – RB0 Interrupt enable (1 – uključi) ; RBIE – RB Interrupt enable (1 – uključi) ; INTF – Interapt flag za T5 (0 – obriši) movwf INTCON ; RBIF – Interapt flag za T1-T4 (0 – obriši) bcf STATUS,RP0 ; Povratak u BANK0 ; ****** Prvi deo programa – setovan GIE, normalni interapti ****** Poc sleep ; Uključi SLEEP mod ; U ovom trenutku program se vratio iz interapt rutine. Sada je potrebno proveriti da li ; je snimljeno svih 5 vrednosti. Međutim, bolje je ovde proveriti vrednost FSR ; registra sabiranjem, jer je moguće da se (npr. usled debouncinga na T5) izazove više ; uzastopnih interapta i tako snime vrednosti u još par narednih RAM adresa. Čak i ; da se to dogodi, testom Carry flaga može se detektovati taj slučaj za razliku od ; testa Zero flaga. movf addlw btfss goto

FSR,W .219 STATUS,C Poc

; FSR u W ; Test prekoračenja. FSR treba biti od .32 do .36 ; .37 i više + .219 = setovan Carry ; Još nema prekoračenja. Spavaj i dalje.

; U ovom trenutku snimljeno je svih 5 vrednosti u RAM adrese od .32 do .36 ; Sada se treba zabraniti odlazak na interapt potprogram. Zabr bcf btfsc goto

INTCON,GIE INTCON,GIE Zabr

; Jeste. Zabrani nove interapre ; Proveri jesu li interapti zaista zabranjeni ; Nisu, zabrani ih opet.

; ** Drugi deo programa – resetovan GIE, interaptima se nastavlja glavni program ** movlw 0xFF ; movwf PORTA ; Obriši LED displej (segmenti na PORTA). movwf PORTB ; Obriši LED displej (segmenti na PORTB) 87

bcf movlw movwf

PORTA,4 .32 FSR

; Uključi segment decimalne tačke. ; Inicijalizacija pointera RAM memorije ; na registar .32

; ****** Zabrani buđenje iz sleep moda prekidačima T1 do T4 ****** bsf STATUS,RP0 ; Prebacuje program u BANK1 movlw b'00010000' ; GIE – Global interrupt enable (0 – isključi) ; INTE – RB0 Interrupt enable (1 – uključi) ; RBIE – RB Interrupt enable (0 – isključi) ; INTF – Interapt flag za T5 (0 – obriši) movwf INTCON ; RBIF – Interapt flag za T1-T4 (0 – obriši) bcf STATUS,RP0 ; Povratak u BANK0 ; ****** Ponovo uspavaj mikrokontroler ****** Spa sleep ; Uspavaj mikrokontroler do pojave interapta. ; Po njegovoj pojavi, nastavi program bez skoka ; na interapt potprogram ; Utroši jedan instrukcijski ciklus ; Preporučljivo nakon buđenja

nop

; U ovom trenutku pritisnut je prekidač T5. movf call call bcf incf

INDF,W Tabl Nacr PORTA,4 FSR,F

; Indirektno čitanje željenog registra ; Uzmi sliku za displej iz tabele. ; Nacrtaj sliku. ; Uključi segment decimalne tačke. ; Pozicioniranje pointera na sledeći registar

; Test prekoračenja je isti kao i ranije, iako bi sada slobodno mogao biti sa XOR ; operacijom movf addlw btfss goto goto

FSR,W .219 STATUS,C Spa Opet

; ****** Kraj programa ****** end

; FSR u W ; Test prekoračenja. FSR treba biti od .32 do .36 ; .37 i više + .219 = setovan Carry ; Još nema prekoračenja. Spavaj i dalje. ; Ima prekoračenja. Počni program iz početka. ; Kraj programa

U Sleep modu oscilator je nestabilan prilikom buđenja. Naime, pošto je oscilator za vreme spavanja blokiran, nije mu baš lako da odjednom počne proizvoditi čiste taktove. Buđenje neće biti moguće dok se oscilator ne stabilizuje. Zato se pri korišćenju SLEEP moda ne može vršiti merenje vremena brojanjem instrukcijskih ciklusa instrukcija u programu, čak iako se buđenje interaptom dešava tačno određeno vreme nakon ulaska u Sleep mod. Kako RC oscilator najlakše počinje sa oscilacijama, vreme za njegovu stabilizaciju je skoro trenutno, dok je kod upotrebe ostalih vrsta oscilatora potrebno 1024 takta oscilatora za kompletnu stabilizaciju. Sve dok se stabilizacija takta ne završi, mikrokontroler se neće moći probuditi iz SLEEP moda. 88

28. Brojač Kako možete brojali spoljne signale? Jedan od mogućih načina predstavlja neprekidno testiranje pina na logičku 0 pa na logičku 1 iz glavnog programa (eng. pooling). Očigledno je da bi ovakaj princip brojanja zauzeo najviše resursa mikrokontrolera. Drugi način je interaptima. Njima je mikrokontroleru ostavljeno dovoljno vremena za glavni program, a ipak može pravovremeno odgovoriti na spoljne impulse. U praksi se često javlja potreba za brojanjem većih vrednosti, pri čemu se rezolucija brojača zaokružuje na dovoljan broj decimala. Da li Vam je toliko bitna razlika u brzini od 0,0025km/h ukoliko već vozite biciklu preko 30km/h? Teško da će biti ukoliko ne idete na „Tour de France“ (poznata biciklistička trka u Francuskoj). Dakle, kako brojati sa zaokruženjem? Potrebno je podesiti tajmer tako da umesto instrukcijskih ciklusa broji impulse sa RA4/T0CKI pina, setovanjem T0CS bita OPTION_REG registra. U slučaju odnosa preskalera 1:1, trajanje logičke 0 i 1 eksternog takta mora biti duže od 3 takta oscilatora PIC16F84 (tačnije oko 2 takta + 20nS), a u slučaju bilo kog drugog odnosa duže od 5 takova (tačnije 4 takta + 40nS). Osim promene izvora takta tajmera, sve je ostalo isto. Preskaler se podešava kao kod tajmera, interapt se izaziva kao kod tajmera, čak se i upisivanjem u TMR0 registar inicijalizuje tajmer i preskaler. Na taj način Timer0 ima funkciju brojača (eng. Counter). Šta se dobija upotrebom ovakvog brojača? Umesto da se interapt izaziva prilikom svakog impulsa, izazivaće se tek prilikom prekoračenja brojača. Za odnos preskalera od 1:1 to znači da će se interapt izazivati nakon svakog 255-og impulsa. Tako za glavni program ostaje mnogo više resursa. Ograničenjem minimalnog trajanja logičke 0 i logičke 1 ograničen je i maksimalni takt koji može meriti mikrokontroler. Međutim, ovo se može efikasno rešiti korišćenjem eksternih integrisanih delitelja signala (npr. 74390 ili 4040), koji dodatno hardverski dele ulazni signal. Ovde su moćniji mikrokontroleri u prednosti zbog postojanja više tajmera. Na primer, jedan bi se iskoristio za brojanje eksternih impulsa, a drugi za to vreme može generisati stabilnu vremensku bazu. Poređenjem ove dve vrednosti može se lako dobiti frekvencija eksternog signala. Za više detalja pogledajte AN689 Voje Antonića i AN592.

89

29. Reset Najjednostavnije rečeno, reset služi da izvršavanje programa počne iz početka. PIC16F84 ima 3 izvora reseta. Prvi je svakako reset prilikom dovođenja napona napajanja (eng. POR – Power-on Reset). Unutar mikrokontrolera nalazi se malo električno kolo koje detektuje porast napona napajanja do napona dovoljnog za rad mikrokontrolera. U trenutku dostizanja nominalnog napona, mikrokontroler se resetuje. Ovim se sprečava rad mikrokontrolera pri preniskom naponu napajanja. Ukoliko je potrebno, može se uključiti PWRTE (eng. Power-up Timer Enable) konfiguracioni bit koji drži mikrokontroler u stanju reseta oko 72mS od dovođenja napona napajanja. Ovo kašnjenje realizovano je internim RC oscilatorom nezavisnim od takta oscilatora. To je dovoljno da se napon napajanja podigne na nominalnu vrednost i da oscilator mikrokontrolera počne proizvoditi čiste neprigušene oscilacije. Nakon što se ovo kašnjenje završi, mikrokontroler (za svaki slučaj) čeka još 1024 takta oscilatora pre nego što počne izvršavati program. Drugi izvor reseta je MCLR pin mikrokontrolera. On mora uvek biti držan na logičkoj jedinici. Obično se to realizuje povezivanjem sa naponom napajanja preko otpornika od 10kΩ. U šemama u ovom uputstvu on je spojen direktno zbog veće preglednosti šeme, i jer se ne koristi. Pri dovođenju logičke 0 na ovaj pin (spajanje sa masom), mikrokontroler se resetuje. Za svaki slučaj u ulaznom stepenu ovog pina postavljen je Šmitov okidač koji ima ulogu filtriranja slabih impulsa, koji bi mogli prouzrokovati nehotični reset mikrokontrolera. Poslednji izvor reseta naučili ste u delu sa WDT. Možete izvršiti softverski reset namernim izostavljanjem CLRWDT instrukcije u željenom delu programa. Iako reset prvenstveno služi za ponovni start programa, testiranjem stanja TO i PD bitova STATUS registra, moguće je utvrditi na koji način je izazvan reset, i na osnovu toga nastaviti rad programa. TO

PD

Stanje

1

1

Stanje nakon izvršenja CLRWDT instrukcije

1

0

Stanje nakon izvršenja SLEEP instrukcije

0

0

WDT reset za vreme SLEEP moda

0

1

WDT reset za vreme normalnog izvršavanja programa

1

0

MCLR reset za vreme SLEEP moda ili buđenje interaptom

1

1

MCLR reset za vreme normalnog izvršavanja programa

1

1

POR reset pri dolasku napona napajanja

U prilogu ovog uputstva možete videti inicijalno stanje svih registara nakon reseta.

90

30. Srce mikrokontrolera Isto kao što Vaše srce pumpa krv određenim ritmom, mikrokontroler za svoj pravilan rad mora imati tačno podešene taktne impulse. Oni se dobijaju iz oscilatora. U ovom poglavlju biće prikazane šeme hardverskog povezivanja raznih vrsta oscilatora, i biće bliže objašnjene njihove specifičnosti.

Najjeftiniji je svakako RC oscilator, korišćen u dosadašnjim šemama. Sastoji se samo od kondenzatora i otpornika. U tablici su date vrednosti otpornosti i kapacitivnosti za dobijanje željenih frekvencija.

Frekv. (Khz) 26

Kapac. (pF) 300

Otpornost (kΩ) 100

83

100

100

243

300

10

311

20

100

428

300

5

756

100

10

1340

100

5

3500

33

5

2660

20

10

4610

20

5

Ovaj tip oscilatora može se koristiti za pun opseg frekvencija mikrokontrolera (DC do 4MHz, odnosno do 20MHz za brže verzije PIC16F84 mikrokontrolera). Mana mu je loša stabilnost frekvencije i „šetanje“ frekvencije usled promene temperature. Preporučene vrednosti otpornosti su od 3kΩ do 100kΩ, a kapacitivnosti preko 20pF. Gornja granica kapacitivnosti zavisi isključivo od željene maksimalne frekvencije. Što se tiče mikrokontrolera, on će bez problema raditi čak i sa taktom oscilatora manjim od 1Hz. Kao lenjivac. U nekim PIC mikrokontrolerima (nažalost ne u PIC16F84) nalazi se integrisani hardverski RC oscilator. Zbog preciznijeg takta, Microchip kalibracioni niz snima u deo programske memorije. Kasnije se ovaj niz može pročitati i softverski podesiti. Na OSC2 pinu pri radu RC oscilatora dobija se četvrtina takta oscilatora, što se može iskoristiti za sinhronizaciju dodatnih eksternih uređaja sa mikrokontrolerom. U SLEEP modu oscilator se blokira, pa ni ovaj signal više nije dostupan. Iako je oscilator mikrokontrolera nezavistan od ostatka hardvera, moguće je primenjujući male softversko hardverske trikove indirektno uticati na njegovu frekvenciju. Dovoljno je npr. jednim pinom mikrokontrolera uključivati paralelno povezivanje otpornika u RC članu. Postavljanjem pina na logičku 0 ili 1, dodatni otpornik će se paralelno spojiti sa već postojećim otpornikom, smanjujući rezultujuću vrednost otpornosti. Tako se može grubo menjati frekvencija oscilatora. Ovaj princip može biti iskorišćen za smanjenje frekvencije oscilatora u periodima kada mikrokontroleru nije potrebna puna brzina čime bi se istovremeno smanjila potrošnja mikrokontrolera. Međutim, zbog preporučenih vrednosti otpornosti (do 100kΩ) nije 91

preporučljivo ovim načinom menjati frekvenciju u većim opsezima. Zbog toga se može umesto samo otpornika uključivati dodatni RC član. Više o ovom principu imate na sajtu http://www.romanblack.com/ u delu PIC with 2 clock speeds! Ukoliko je potrebno rad mikrokontrolera sinhronizovati sa eksternim uređajima, može mu se spolja obezbediti spoljni takt. Konfiguracioni bitovi trebaju u tom slučaju biti podešeni na LP, XT ili HS. OSC2 pin je poželjno povezati na masu mikrokontrolera preko otpornika veće vrednosti (10kΩ), zbog smanjenja interferencije, iako to povećava potrošnju mikrokontrolera. Ukoliko nije potrebna velika brzina izvršavanja instrukcija, a bitna je potrošnja i stabilnost frekvencije, (npr. sat na baterije) PIC treba raditi sa 32KHz-200KHz kristalom. Na manjem taktu zbog manjeg pojačanja integrisanog oscilatornog kola PIC troši manje struje nego inače. Za ovakvu vrstu oscilatora treba podesiti konfiguracioni bit oscilatora na – OSC LP. Ukoliko je bitna stabilna frekvencija a i cena PIC16f84, dobar izbor bi bio kristalni oscilator do 4MHz. Za njega je potrebno konfiguracioni bit podesiti kao - OSC XT. A ukoliko je brzina imperativ, mogu se kupiti verzije PIC16F84 mikrokontrolera koje mogu bez problema raditi na taktu većem od 4MHz. Nažalost, one su i skuplje. Njihov konfiguracioni bit potrebno je podesiti kao – OSC HS. U ovom modu zbog najvećeg pojačanja integrisanog oscilatornog kola PIC16F84 troši najviše električne energije. Za ova 3 načina sa kristalnim oscilatorom primenjuje se sledeća šema:

Otpornik je potreban samo za retke tipove kristala. U najvećem broju slučajeva može se izostaviti. HS mod mogu koristiti jedino tipovi PIC16F84 mikrokontrolera predviđeni za rad na visokim frekvencijama.

Frekv. (Khz)

Kapac. (pF)

Konfig. bitovi

32

68-100

LP

200

15-30

LP

100

68-150

XT

455

22-100

XT

2000

15-68

XT

4000

15-68

XT

8000

10-68

HS

16000

10-22

HS

20000

5-10

HS

Dizajn internog oscilatora zahteva upotrebu paralelno rezanog kristala. Međutim, i redno rezani kristali mogu se koristiti kao izvor takta, ali jedino uz eksterno oscilatorno kolo. Njihova upotreba u šemi kristalnog oscilatora dovešće do frekvencije koja odstupa od specifikacija u karakteristikama proizvođača kristala. 92

Ukoliko želite imati izuzetno stabilnu frekvenciju možete umesto običnih koristiti OCXO (eng. Oven Controlled Xtal Oscillator) kristale koji u istom kućištu imaju kristal, grejač i termostat. Za napajanje grejača potrebno je dovesti spoljni izvor napajanja koji nažalost dodatno povećava potrošnju kola. Grejačem i termostatom reguliše se konstantna temperatura kristala iznad sobne temperature, tako da je temperaturni drift frekvencije kristala minimalan. Kako su takvi kristali (i takva kućišta) dosta skuplji od običnih, možete ih sami napraviti sledeći uputstva sa sajta http://www.romanblack.com/ u delu Simple xtal oven for accurate clocks. Keramički oscilator obično je zajedno sa kondenzatorima spakovan u zajedničko tropinsko kućište. Takvi elementi nazivaju se keramički rezonatori. Veća kapacitivnost kondenzatora povećava stabilnost oscilatora, ali takođe povećava i vreme potrebno za stabilizaciju oscilatornog kola pri uključenju mikrokontrolera ili buđenju iz SLEEP moda. U principu, ova 3 stanja konfiguracionih bitova (LP, XT i HS) razlikuju se jedino u pojačanju internog invertora oscilatornog kola što omogućava različit opseg frekvencija. Ukoliko Vam se desi da neki kristal ne može proraditi u jednom modu, probajte promeniti konfiguracione bitove oscilatora. Najbolje je koristiti oscilator sa najmanjim mogućim pojačanjem, uz uslov da se njime može postići željena brzina oscilatora. Za detalje o tipovima oscilatora, pogledajte AN588 sa http://www.microchip.com/. Čestitam! Sada znate funkcije svih pinova mikrokontrolera, upotrebu svih 35 instrukcija i svih 15 registara. Međutim, tek ste počeli sa učenjem. Skoro svaki softverski problem može se rešiti na više načina. Ukoliko želite da se određeni deo programa izvršava 5 puta, potrebno brojanje možete implementovati sabiranjem, oduzimanjem, inkrementacijom, dekrementacijom pa čak i rotacijom. U sledećim poglavljima upoznaćete se sa najčešće korišćenim softversko hardverskim tehnikama za realizaciju određenih zadataka.

93

31. MPASM direktive i makroi Ranije ste naučili par najkorišćenijih mogućnosti MPLAB asemblera. One su dovoljne za analizu bilo kog asemblerskog (pa čak i disasembliranog) programa. U ovom poglavlju naučićete par asemblerskih specifičnosti kojim će Vaš program biti čitljiviji i kojim ćete smanjiti mogućnost pojave grešaka prilikom njegovog pisanja. Da li Vam je zamoran prelazak iz banke u banku? Ko bi pamtio treba li se RP0 bit setovati ili resetovati! Ne morate. Koristite banksel direktivu. Dovoljno je iza nje navesti naziv registra kome pristupate, i ona će na svom mestu ubaciti odgovarajuću instrukciju prelaska (bcf STATUS,RP0 ili bsf STATUS,RP0). Već znate kako deluje equ direktiva. Pretpostavimo da ste imenu PAUZA pridružili decimalnu vrednost 100. Unutar potprograma tu vrednost koristite kao broj milisekundi. Pretpostavimo da vam u programu zatreba pauza duplo dužeg trajanja. Umesto imenovanja još jednog broja, možete napisati sledeće: movlw call

PAUZA * 2 ; PAUZA * 2 = .200 Cekaj ; Idi na potprogram

Na isti način za duplo kraću pauzu možete napisati: movlw call

PAUZA / 2 ; PAUZA / 2 = .50 Cekaj ; Idi na potprogram

Asembler u oba slučaja za vreme asembliranja računa vrednosti koje se trebaju naći na određenim mestima. One u svakom slučaju moraju biti poznate pre računanja. Neke od aritmetičkih operacija koje može izvršiti asembler su sledeće: – – – – – –

* / % + -

negacija (po drugom komplementu) množenje deljenje moduo (ostatak pri deljenju) sabiranje oduzimanje

Željeni prioritet operacija može se definisati zagradama. Npr. (8-6)*5. Osim matematičkih, asembler može izračunati i vrednosti određenih logičkih operacija. Na primer: – – – – – –

~ komplement > rotacija udesno (bez Carry Flaga) & AND ^ XOR | IOR

I kod njih se prioriteti definišu zagradama. Npr. ~((BROJ1&BROJ2)^BROJ3). 94

Prilikom ovakvih vrednosti morate biti sigurni da parametar ne može izaći izvan dozvoljenih granica. Isto tako, morate obratiti pažnju na moguće zaokruživanje broja (na primer prilikom deljenja). Sledeća pogodnost koju pruža MPLAB asembler je zamena teksta. Ukoliko u programu imate ovakav deo: TASTER

equ btfsc goto goto

3 PORTA,TASTER Prit Otpu

; Taster je povezan na RA3 pin ; Da li je taster pritisnut? ; Jeste ; Nije

i dalje je potrebno pamtiti na kom je portu povezan taster. Zamenom dela teksta za tim nema potrebe. #define

TASTER

btfsc goto goto

TASTER Prit Otpu

PORTA,3

; Zameni izraz ; PORTA,3 rečju TASTER ; Da li je taster pritisnut? ; Jeste ; Nije

#define direktivom nije moguće zameniti veći deo koda (2 ili više instrukcija). Za to se koriste makroi. Čak je moguće u makro preneti određene parametre ranije definisane. #define Test macro extern btfsc goto goto endm

TASTER PORTA,3 ; Imenuje nazive port,pin ; Određuje ulazne parametre Prit,Otpu ; Označava da su labele ili registri ; definisani izvan makroa port,pin ; Da li je taster pritisnut? Prit ; Jeste Otpu ; Nije ; Direktiva za oznaku kraja makroa

Kad god je unutar programa potrebno na osnovu pritisnutog tastera otići na Prit ili Otpu delove, dovoljno je kasnije umesto gornjeg koda napisati samo oznaku labele makroa i parametra „Test TASTER“. Kako je imenom TASTER zamenjena oznaka odgovarajućeg porta i pina, vrednosti port i pin unutar makroa uzeće ove vrednosti. Na taj način se u makro ubacuju željeni parametri. Unutar makroa moguće je koristiti sve instrukcije kao i u glavnom programu. Međutim, kako se makro poziva iz spoljnog programa, poželjno je da labele i registri unutar makroa ne dođu u konflikt sa delovima programa izvan makroa. Zbog toga je potrebno unutar makroa definisati korišćene unutrašnje i spoljne labele i registre. Na taj način moguće je i unutar glavnog programa i unutar makroa imati labelu istog naziva. U makrou ona mora biti definisana kao interna, što znači da joj program spolja ne može pristupiti. Labele definisane kao eksterne mogu se pozivati i iz makroa. Za kompletno uputstvo o upotrebi makroa, direktiva i aritmetičko logičkih operacija pogledajte DS33014J sa http://www.microchip.com/.

95

32. Komentari Na početku ovog uputstva, malo se pričalo o komentarima. U ovom poglavlju upoznaćete se sa modifikacijama zaglavlja tako da Vam bude prilagođenije, i sa načinima komentarisanja registara koji imaju bitove različitih funkcija. Sećate se zaglavlja koje ste do sada koristili. Prepravite ga po sledećem: ;********************************************************** ; Autor : ; Datum : ; Verzija : ; Naslov : ; ; Opis hardvera : ; Opis softvera : ; Potrebni fajlovi : p16F84.inc ; ;********************************************************** list #include __CONFIG

p=16F84 ; Definiše upotrebljeni mikrokontroler ; Ubacuje nazive registra u program _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC ; CP - zaštita od čitanja ; WDT - watchdog tajmer ; PWRTE - kašnjenje po uključivanju ; XT OSC - kristalni oscilator ; LP OSC - oscilator male potrošnje ; HS OSC - brzi oscilator ; RC OSC - otpornik i kondenzator

; ****** Inicijalizacija registara ****** cblock 0x0C TEMPW ; Privremeno čuvanje W registra TEMPSTATUS ; Privremeno čuvanje STATUS registra SPORTA ; Shaddow registar za PORTA SPORTB ; Shaddow registar za PORTB endc ; ****** Inicijalizacija vrednosti u EEPROM memoriji ****** org 21x00 ; Početak EEPROM memorije ; de 0x00 ; Inicijalizacija prvog bajta ; ****** Start programa ****** ORG 0x00 goto Main

; Start programa ;

96

; ****** Interapt potprogram ****** ORG 0x04 movwf TEMPW swapf STATUS,W movwf TEMPSTATUS

; Čuvanje sadržaja W registra ; STATUS sa okrenutim niblovima u W ; i zatim u TEMPSTATUS registar

; Prostor za interapt potprogram. Back bcf bcf bcf bcf

INTCON,T0IF INTCON,INTF INTCON,RBIF INTCON,EEIF

; Dozvoli nove interapte tajmera ; Dozvoli nove interapte prekidača ; Dozvoli nove interapte po promeni stanja ; Dozvoli nove interapte EEPROM-a

swapf

TEMPSTATUS,W

movwf swapf

STATUS TEMPW,F

swapf retfie

TEMPW,W

; ****** Početak programa ****** Main banksel TRISA

; TEMPSTATUS sa okrenutim niblovima ; u W. Dva puta okrenuti niblovi daju ; prvobitno stanje koje ide u STATUS ; Jednom okreni niblove u samom ; TEMPW registru, ; a drugi put sa W kao odredištem. ; Povratak iz interapt rutine.

; BANK 1 ; ; Konfigurisanje pinova ; ; Konfigurisanje pinova

movlw movwf movlw movwf

b'00000000' TRISA b'00000000' TRISB

movlw

movwf

b'00000000' ; ; !!!!! +------ PS0-PS2 - 000=1:2 001=1:4... ; !!!!+-------- PSA - 1=WDT 0=tajmer ; !!!+--------- T0SE eksterni takt 1=\ 0=/ ; !!+---------- T0CS - 1= eksterni takt 0=takt tajmera ; !+----------- INTEDG - 1=/ 0=\ ; +------------ RBPU - 0=uklj. 1=isključeni otpornici OPTION_REG ;

banksel

PORTA

; BANK0

movlw movwf movwf movlw movwf movwf

b'00000000' PORTA SPORTA b'00000000' PORTB SPORTB

; ; Inicijalizacija stanja portova i ; Shaddow registara ; ; ; 97

movlw

movwf

b'00000000' ; ; !!!!!!!+----- RBIF ; !!!!!!+------ INTF ; !!!!!+------- T0IF ; !!!!+-------- RBIE ; !!!+--------- INTE ; !!+---------- T0IE ; !+----------- EEIE ; +------------ GIE INTCON ;

– 0=obriši – 0=obriši – 0=obriši – 1=uključi – 1=uključi – 1=uključi – 1=uključi – 1=uključi

Start ; Prostor za programe. end

; Kraj programa

Na ovaj način program je pregledniji nego ranije, razumljivije je značenje bitova u OPTION_REG i INTCON registru, a najčešće korišćeni registri su unapred inicijalizovani pravilnim redosledom, što smanjuje mogućnost nepravilne inicijalizacije. Delove koji se ne koriste lakše je odjednom obrisati, nego ih po potrebi iznova pisati za svaki novi program. Po potrebi u zaglavlje se mogu dodati i najkorišćeniji delovi programa (npr. za pauzu, za korišćenje EEPROM memorije ili RS232 veze), ali je praktičnije odvojiti ih u zasebne celine u sklopu potprograma, na primer ovako: ;*********************************************** ; Tabela za ispis cifre na LED displeju ; Mora se nalaziti u bloku od 256 bajtova. Tabl movf CIFRA,W addwf PCL,F retlw b'01111110' ;0 retlw b'00001100' ;1 retlw b'10110110' ;2 retlw b'10011110' ;3 retlw b'11001100' ;4 retlw b'11011010' ;5 retlw b'11111010' ;6 retlw b'00001110' ;7 retlw b'11111110' ;8 retlw b'11011110' ;9 Možete ih takođe ubaciti i u formi makroa, što listing programa čini preglednijim. Prilikom pisanja programa neki put ćete koristiti TAB a neki put par razmaka. MPLAB za razliku od ostalih tekst editora za TAB postavlja 4 (umesto 8) razmaka. Zato je dobro pre štampanja listinga programa dodatno „srediti“ .asm fajl. Za to možete koristiti ASPIC_FIX program sa http://www.embedinc.com/ . 98

33. Maskiranje Pod maskiranjem se podrazumeva izdvajanje željenog bita prepisivanjem niza nula ili jedinica u ostale. Pretpostavimo da je potrebno dovesti treći bit registra PRIKAZ na treći bit PORTA registra, ali tako da se ne promeni stanje ostalih bitova PORTA registra. movf movwf movlw andwf bcf iorwf movwf movwf

PORTA,W ; PORTA u W, SPORTA ; a odatle u Shaddow registar b'00001000' ; Maskiranje svih osim trećeg bita PRIKAZ,W ; Rezultat b'00001000' ili b'00000000' u W, ; u zavisnosti od stanja trećeg bita ; PRIKAZ registra SPORTA,3 ; Resetovanje ranijeg stanja trećeg bita SPORTA,W ; Postavljanje samo trećeg bita na novu vrednost ; Rezultat u W, PORTA ; a odatle u PORTA registar i SPORTA ; u SHADDOW registar.

Rezultat AND operacije nad bitovima, biće 1 samo ako je na oba bita prisutna logička 1. Ukoliko se ostali bitovi maskiraju, u W će se naći jedino stanje trećeg bita PRIKAZ registra. Nasuprot AND operaciji, rezultat IOR operacije daje 1 ukoliko je bar 1 bit na logičkoj 1. U tom slučaju (budući da je treći bit resetovan BCF instrukcijom), stanje trećeg bita SPORTA registra zavisiće jedino od stanja trećeg bita W registra, koje je preuzeto iz PRIKAZ registra. Ostali bitovi u SPORTA registru zadržaće svoja stanja, jer IOR operacija sa bilo kojom vrednošću bita i nulom, daje sam taj bit.

99

34. Kompresija Kompresija je postupak kojim se troši manje memorije za čuvanje većeg broja podataka efikasnijim smeštanjem podataka u memoriji. Osnovni preduslov je da se u podatcima nalaze prazni (neiskorišćeni) bitovi. Na primer, ukoliko je potrebno u EEPROM snimati grupe od dva bita (kao u primeru sa buđenjem iz SLEEP moda), šteta je ne iskoristiti i ostatak bitova u bajtu. A ukoliko nije poznata konačna veličina (kraj) memorisanih podataka, mogu se brojati ciklusi snimanja i po završetku snimanja snimiti u npr. zadnjoj EEPROM adresi (0x3F). Ukoliko se snimaju samo 2 bita, onda je raspoloživa memorija u kompresovanom stanju 4 puta (8 bita / 2 bita) veća od maksimalne. Za EEPROM to znači da umesto 64 osmobitna, postaje dostupno 128 četvorobitna (128 nibla) ili 256 dvobitna dela. Kompresija, nije ograničena samo na EEPROM memoriju. Može se bez problema koristiti u običnoj kao i u programskoj memoriji u tabelama. Normalno, u slučaju programske memorije podatke u tabeli nije moguće menjati, već samo čitati. Pretpostavimo da je potrebno prva dva bita iz registara STANJE1, STANJE2, STANJE3 i STANJE4 kompresovati u registar STANJE. movlw andwf movwf rlf rlf movlw andwf iorwf rlf rlf rlf rlf movlw andwf iorwf rrf rrf rrf movlw andwf iorwf bit7 ST4.1

ST4.0

00000011b STANJE1,W STANJE STANJE2,F STANJE2,F 00001100b STANJE2,W STANJE,F STANJE3,F STANJE3,F STANJE3,F STANJE3,F 00110000b STANJE3,W STANJE,F STANJE4 STANJE4 STANJE4 11000000b STANJE4,W STANJE,F ST3.1

; Maskiranje nepotrebnih bitova ; Prva dva bita iz STANJE1 registra u W ; a odatle u STANJE registar ; Rotacija bitova tako da ; dođu na pravo mesto ; Maskiranje nepotrebnih bitova ; Sledeća dva bita iz STANJE2 registra u W ; a odatle u STANJE registar ; Rotacija bitova tako da ; dođu na ; pravo ; mesto ; Maskiranje nepotrebnih bitova ; Sledeća dva bita iz STANJE3 registra u W ; a odatle u STANJE registar ; Rotacija bitova ; tako da dođu ; na pravo mesto ; Maskiranje nepotrebnih bitova ; Zadnja dva bita iz STANJE4 registra u W ; a odatle u STANJE registar

STANJE ST3.0 ST2.1

ST2.0

ST1.1

bit0 ST1.0

100

Proces vraćanja u prvobitno stanje (iz STANJE u STANJE1, STANJE2, STANJE3 i STANJE4) naziva se dekompresija. movf movwf rlf rlf movf movwf rlf rlf movf movwf rlf rlf movwf

STANJE,W STANJE1 STANJE,F STANJE,F STANJE,W STANJE2 STANJE,F STANJE,F STANJE,W STANJE3 STANJE,F STANJE,W STANJE4

; STANJE u W ; Prva dva bita u STANJE1 ; Rotacija bajtova tako da ; dođu na pravo mesto ; STANJE u W ; Sledeća dva bita u STANJE2 ; Rotacija bajtova tako da ; dođu na pravo mesto ; STANJE u W ; Sledeća dva bita u STANJE3 ; Rotacija bajtova tako da ; dođu na pravo mesto ; Zadnja dva bita u STANJE4

U ovoj dekompresiji na tačnu vrednost postavljeni su samo nulti i prvi bit u svakom registru, a stanje ostalih bitova zavisi od stanja bitova u ostalim registrima. Ukoliko je to nepoželjno, ostali bitovi mogu se setovati ili resetovati maskiranjem. Bitova za Potreban kompresiju broj delova

Bitova za pune bajtove

1

8

8 (1)

2

4

8 (1)

3

8

24 (3)

4

2

8 (1)

5

8

40 (5)

6

4

24 (3)

7

8

56 (7)

8

1

8 (1)

Sa kompresijom broja bitova sa kojima osmobitni bajt nije deljiv, postupak je malo teži. Potrebno je odrediti minimalan broj punih bajtova, kompresovati bitove u njih, a zatim ih redom snimati u memoriju. Na isti način moguće je izvršiti kompresiju i dekompresiju podataka koji sadrže više od 8 bitova, sa tim što se onda podatci uvek snimaju u više od jednog bajta. Osim ovog, postoje i mnogo komplikovaniji načini kompresije (npr. ZIP algoritam). Budući da oni prevazilaze okvire ovog uputstva, ovde neće biti razmatrani.

Imajte na umu da se EEPROM memorija „troši“ za vreme snimanja. Zbog toga nije poželjno snimati svaki dvobitni deo posebno. Sigurnije je sačekati da broj delova dostigne celobrojni broj bajtova, i tek onda snimiti ceo bajt u EEPROM.

101

35. If ... Then ... Else ... Iznova i iznova upotreba instrukcija grananja zbunjuje početnike. U ovom poglavlju biće dodatno objašnjena njihova primena. Pogledajte sledeći primer, zajedno sa odgovarajućim algoritmom: ; Broj 5? ; Uporedi

movlw xorwf

.5 BROJ,W

btfsc goto goto

Z=0? STATUS,Z ; If Z = 0 Isti ; else goto Isti Razliciti ; then goto Razliciti Ne

Da

Različiti

Isti

Kao što primećujete, u programu se ne testira realno stanje registara, već jedino logičko stanje odgovarajućeg flaga (odnosno bita) unutar registra. Kako će stanje flaga direktno zavisiti od rezultata prethodne instrukcije (5 XOR 5 = 0 pa je Z setovan) koja utiče na njegovo stanje, upravo je njegovim testiranjem omogućeno grananje. Probleme može izazvati i razumevanje preskoka naredne instrukcije. Naime, prilikom izvršenja btfsc ili btfss instrukcije, nema realne potrebe (osim lakše čitljivosti takvog programa) za dve goto instrukcije, jer će program u slučaju da je odgovarajući uslov ispunjen (setovan ili resetovan flag) preskočiti narednu instrukciju. movlw xorwf

.12 BROJ,W

; Broj 12? ; Uporedi Da

btfss goto Isti ...

STATUS,Z ; If Z = 1 Razliciti ; else goto Razliciti ; then Isti

Z=1? Ne Različiti

; Razliciti

Razliciti ...

Isti

Iako je jednostavnije algoritme testiranja moguće napraviti bez dve goto instrukcije, dok ne usavršite programiranje upotrebljavajte prvi oblik (sa dve GOTO instrukcije). Pored btfsc i btfss instrukcija, teško je razumeti i incfsz i decfsz instrukcije. Pogledajte ilustraciju njihove primene u algoritmu koji broji od 25 do 0: movlw movwf Sman decfsz goto Broj0

.25 BROJ

; .25 ; u BROJ

BROJ,F Sman

; BROJ=0? ; Nije, vrati se ; Jeste.

Smanji BROJ BROJ=0?

Da

Ne Vrati se 102

36. Uslovno asembliranje Pretpostavimo da imate program koji kontroliše LED displej. Ništa čudno. Već ste to naučili. Jedini je problem u tome što jednom nabavite displej sa zajedničkom anodom, a drugi put ga nema u prodavnicama, pa morate kupiti displej sa zajedničkom katodom. Na sreću, pogodilo se da su priključci isti, da možete lako prebaciti katodu sa napajanja na masu, jedini je problem tabela. Šta možete uraditi? Zameniti tabelu! U redu. Ali šta ukoliko i drugi put promenite displej? Da li da čuvate dve verzije programa? Mora da postoji bolji način! MPLAB asembler sadrži par uslovnih direktiva. Njima se u zavisnosti od datih uslova može izabrati koji deo programa će se asemblirati, a koji ne. Pogledajte na primer sledeći deo: Nastavak sledi!

103

37. Jednakost dva broja U programima se često javlja potreba za testiranjem određenih vrednosti. Kao što ste već naučili, lako je porediti jednakost dva broja korišćenjem XOR operacije, i odgovarajućim skokom u zavisnosti od stanja Zero flaga. U slučaju testa više vrednosti, moguće je testirati ih na sledeći način: movlw xorwf btfsc goto

'G' SLOVO,W STATUS,Z Label1

; Slovo “G”? ; Uporedi ; Da li su isti? ; Jesu, idi na Label1

movlw xorwf btfsc goto

'R' SLOVO,W STATUS,Z Label2

; Nisu. Slovo “R”? ; Uporedi ; Da li su isti? ; Jesu, idi na Label2

movlw xorwf btfsc goto

'Z' SLOVO,W STATUS,Z Label3

; Nije. Da li je to slovo “Z” ; Uporedi ; Da li su isti? ; Jesu, idi na Label2

goto

Label4

; Nije nađena odgovarajuća vrednost. ; Idi na Label4

Postupak je moguće skratiti poređenjem višestruko XOR-ovanih vrednosti: ; Broj u W ; Da li je to slovo “G”? ; Da li su isti? ; Jesu, idi na Label1

movf xorlw btfsc goto

SLOVO,W 'G' STATUS,Z Label1

xorlw btfsc goto

'G' ^ 'R' ; Da li je to slovo “R” (G XOR (G XOR R) = R) STATUS,Z ; Da li su isti? Label2 ; Jesu, idi na Label2

xorlw btfsc goto

'R' ^ 'Z' ; Da li je to slovo “Z” (R XOR (R XOR Z) = Z) STATUS,Z ; Da li su isti? Label3 ; Jesu, idi na Label3

goto

Label4

; Nije nijedna vrednost od ponuđenih. ; Idi na Label4

U ovom slučaju asembler će prilikom asembliranja programa izračunati vrednost “G” XOR “R” (oznaka ^ označava XOR logičku operaciju) i postaviće dobijenu vrednost na rezultat. Na taj način ušteđeno je vreme potrebno za ručno XOR-ovanje. Jednom XOR-ovana vrednost ponovo se XOR-uje i takva se upoređuje sa ostalim. 104

Osim XOR operacije testiranje jednakosti može se izvršiti i oduzimanjem dva broja i testiranjem Zero flaga. movlw subwf btfss goto goto

'G' SLOVO,W STATUS,Z Razliciti Isti

; Slovo “G”? ; W = SLOVO - 30 ; Da li je W = 0 (biće kada su vrednosti iste)? ; Vrednosti se razlikuju ; Vrednosti su iste

Testiranje oduzimanjem više se sreće u programima. Verovatno jer je jednostavnije za razumevanje. Ukoliko imate čestu promenu vrednosti registra koji testirate bez mogućnosti testiranja njene jednakosti sa zadatom vrednošću neposredno nakon promene (npr. test TMR0 registra), pouzdanije je testirati prekoračenje vrednosti testom Carry (umesto Zero) flaga. Ovo je bolji način jer je moguće da između dve uzastopne provere (pogotovu ukoliko koristite duže interapte ili retko testirate jednakost) registar dođe a zatim i pređe preko zadate vrednosti pre provere. Carry flag bi (za razliku od Zero flaga) bio setovan i pri dostizanju vrednosti .0, a i pri prekoračenju. Detaljniji postupak prekoračenja naučićete u narednom poglavlju.

105

38. Manji ili veći Isto kao i poređenje jednakosti PIC16F84 može uz par instrukcija testirati da li je određeni broj A manji ili veći od broja B. Za to je najpraktičnije koristiti oduzimanje i testiranje Carry flaga. Pogledajte sledeći primer. U njemu se testiraju vrednosti W registra i registra BROJ. movlw subwf btfss goto goto

.2 BROJ,W STATUS,C Manji Veci

;2 ; W = BROJ - 2 ; Testiraj prekoračenje ; W=0; BROJ >= 2

Prilikom oduzimanja broj 2 se menja u svoj drugi komplement (0xFE) i ova vrednost se sabira sa vrednošću iz registra BROJ. Stoga, ukoliko je BROJ manji od 2 neće biti setovan Carry flag, pa će se dalje izvršavanje nastaviti od labele Manji. Kako se Carry flag setuje i kada su brojevi jednaki, ukoliko je BROJ veći ili jednak broju 2 program će se nastaviti od labele Veci. Ukoliko se okrene formula W = BROJ - 2 u W = 2 - BROJ moguće je testirati malo drugačija stanja. Na primer: movf sublw btfss goto goto

BROJ, W .2 STATUS,C Veci Manji

; BROJ u W ; W = 2 - BROJ ; Testiraj prekoračenje ; W 2 ; W>=0; BROJ 2

Dupla XOR operacija upotrebljena je da bi vrednost sa kojom se testira BROJ mogla biti uneta u samo jednoj instrukciji, što omogućava lakšu izmenu testirane vrednosti.

106

Testiranjem jednakosti oduzimanjem umesto XOR-ovanjem, postignuta je ušteda dve instrukcije. movlw subwf btfsc goto btfss goto goto

.2 BROJ,W STATUS,Z Isti STATUS,C Veci Manji

; ; W = BROJ - 2 ; Da li je rezultat 0? ; BROJ = 2 ; Nije. Testiraj Carry flag. ; BROJ < 2 ; BROJ > 2

107

39. Zamena sadržaja dva registra Ponekad (npr. pri sortiranju podataka) se javlja potreba za zamenom sadržaja dva registra. Obično se za to koristi dodatni privremeni (eng. temp) registar. movf movwf movf movwf movf movwf

BROJ1,W TEMP BROJ2,W BROJ1 TEMP,W BROJ2

; BROJ1 u W ; W u TEMP ; BROJ2 u W ; BROJ1 dobija početnu vrednost registra BROJ2 ; TEMP u W ; BROJ2 dobija početnu vrednost registra BROJ1

Na sledeći način možete direktno izvršiti njihovu zamenu bez upotrebe dodatnog registra. movf xorwf xorwf xorwf

BROJ1,W BROJ2,W BROJ1,F BROJ2,F

; BROJ1 u W ; BROJ1 ^ BROJ2 u W ; W ^ BROJ1 u BROJ1, W se ne menja ; W ^ BROJ2 u BROJ2

Ovaj algoritam moguć je jer se duplo XOR-ovana vrednost bilo kojim brojem ne menja. Potpuno istim načinom moguće je promeniti sadfržaj BROJ i W registra. xorwf xorwf xorwf

BROJ,F BROJ,W BROJ,F

; ; ;

108

40. On W goto ... Slično kao kod tabele, sabiranjem PCL sa određenim brojim možemo otići na proizvoljne memorijske lokacije. Pretpostavimo da je se registar OFSET uvećava pri svakom prolasku kroz program i da se na osnovu njegovog trenutnog stanja izvršavaju dalji programi jedan za drugim. Na kraju svog izvrsavanja svaki program izvršava goto Poc instrukciju kojim se nastavlja iz početka. Isto kao u tabelama i ovde je potrebno proveriti da li program prelazi granicu od 256 instrukcija. Poc

incf movlw xorwf btfsc clrf

OFSET,F .8 OFSET,W STATUS,Z OFSET

; Uvećaj OFSET ; Broj prekoračenja ; ; Da li je nastupilo prekoračenje? ; Jeste, inicijalizuj OFSET

movf

OFSET,W

; OFSET u W

PCL,F Program1 Program2 Program3 Program4 Program5 Program6 Program7 Program8

; U W se nalazi broj od 0 do 7 ; W=0 ; W=1 ; W=2 ; W=3 ; W=4 ; W=5 ; W=6 ; W=7

Skok addwf goto goto goto goto goto goto goto goto

Svakako možete zapaziti da se ovaj postupak ne razlikuje mnogo od tabele. Ograničenja vezana za njih važe i u ovom slučaju. U gornjem programu umesto zadnje intrukcije (goto Program8) moglo se odmah nastaviti sa izvršavanjem osmog programa. Ipak, ovako program izgleda preglednije i lakši je za analizu. Iako je time utrošena jedna instrukcija više, analiza ovakvog programa je prilično jednostavnija. Morate imati u vidu da će se u programu verovatno javljati greške. Razumljiv i dobro komentarisan program olakšava njegovu naknadnu ispravku. U protivnom, naći ćete se u gomili naizgled besmislenih instrukcija. Česta je pojava da se prilikom kasnijeg razvoja programa više vremena utroši na njegovu analizu, nego na pisanje novog programa iz početka. Nije ni čudo što se kod nerazumljivih programa naziva špageti kod.

109

41. Kašnjenje u petlji U dosta slučajeva potrebno je da program jednostavno čeka u petlji određeno vreme. Kako (za 4MHz kristalni oscilator) instrukcijski ciklus traje samo 1μS, potrebno je softverski realizovati duža kašnjenja. Kašnjenje je najpraktičnije implementirati unutar potprograma. Pri proračunu tačnog vremena kašnjenja mora se uzeti u obzir i vreme potrebno za skok na potprogram, kao i za povratak iz njega (2 * 2 instrukcijska ciklusa). Ovde je dat potprogram kojim će se (pri 4MHz) realizovati kašnjenje od tačno 1mS. Pau

movlw nop Pau4 addlw btfss goto return

0xF9 0xFF STATUS,Z Pau4

; Inicijalna vrednost u W. Tu nisu uračunata 2 ; instrukcijska ciklusa za skok na potprogram ; Oduzmi 1 od W sabirajući W sa 0xFF ; Da li je rezultat 0? ; Nije, nastavi sa petljom ; Jeste, vrati se iz potprograma.

Svaki prolazak kroz petlju troši 4μS. Addlw traje 1, btfss 1 i goto 2μS. I u trenutku izlaska iz petlje (W=0) kašnjenje je takođe 4μS. Potprogram za svoj rad ne koristi registre. Jedino W. U slučaju da je to potebno, moguće je u W zadati željenu dužinu pauze (4μS * W) i skočiti direktno na Pau4. Imajte na umu da je i Call instrukciji potrebno 2μS. Za duže pauze, mora se koristiti registar (u ovom slučaju PAUZA). Pre poziva potprograma je u W potrebno zadati željeni broj milisekundi kašnjenja. Njim je moguće realizovati pauze od 1 do 255mS (¼ S). Kas movwf Pet1 movlw call nop nop decfsz goto return

PAUZA 0xF8 Pau4 PAUZA,F Pet1

; W u PAUZA registar ; Inicijalizacija vrednosti ; 248 * 4 + 2 = 994 ovde ; Ostatak, ; za još 6μS ; Smanji vrednost u registru ; Još petlji. ; Povratak iz potprograma

Ukoliko Vam se ovaj način čini previše težak, možete isprobati PicLoops program koji generiše deo potrebnog kôda u zavisnosti od unetog vremena kašnjenja i brzine oscilatora. Autor tog programa prestao je da programira mikokontrolere, izbrisao je PicLoops sa svog sajta i sada kolekcionira stare video igrice. Program sam postavio na svom sajtu čiji link mođete naći na kraju ovog uputstva. Ukoliko ne želite išta instalirati online generator kašnjenja imate na linku http://www.piclist.com/cgi-bin/delay.exe. Iako izgleda kao program, radi se o linku. 110

42. Semplovanje Pretpostavimo da je potrebno određeno vreme pratiti promene na ulaznim pinovima, i dobijene podatke snimati redom (bit po bit) u RAM registre ili EEPROM memoriju. Takav postupak naziva se semplovanje, a pojedinačni dobijeni podaci (logička stanja pinova u određenom trenutku) semplovi. Kod semplovanja se javljaju četiri problema. Prvi se odnosi na maksimalan broj semplova, drugi na dužinu pauze između semplova, treći na rezoluciju semplova, a četvrti na preciznost pauze. Pretpostavimo da je potrebno promenom logičkog stanja na jednom pinu pratiti nivo reke (periode plime i oseke). Iako se semplovi mogu uzimati svake milisekunde, tolika preciznost jednostavno nije potrebna. Biće sasvim dovoljno ukoliko se između semplova ubaci pauza od 10 minuta, tako da za 1 sat mikrokontroler dobije 6 sempla, odnosno 6*24 = 144 sempla dnevno. Ovde se javlja prvi problem. Maksimalna raspoloživa količina memorije. Pogledajte kako se ona može odrediti. Kako su semplovi jednobitni, oni se mogu kompresovati i tako zauzeti samo 144/8 = 18 EEPROM adresa. Kako EEPROM PIC16F84 mikrokontrolera ima 64 adresa, to znači da bi u njega bilo moguće snimati semplove maksimalno (64*8)/144 = 3,5 dana! Ukoliko Vam je ovaj period previše kratak (idete na odmor u Egipat), morate nešto žrtvovati. Ili ćete kupiti dodatnu EEPROM memoriju, ili ćete povećati pauzu između semplova. Pogledajte šta se događa ukoliko izaberete drugo rešenje. U zavisnosti od raspoloživog vremena (i dubine novčanika), odmor u Egiptu može trajati i do 15 dana (nakon toga postaje dosadno). Znači, za 15 dana možete u EEPROM snimiti maksimalno (64*8)/15 = 34 sempla dnevno. Semplovi bi se uzimali (otprilike) svakih (24*60)/34 = 42 minuta. Ovo je i dalje sasvim dovoljno. Ovde se javlja drugi problem. Dokle će biti dovoljno? Objašnjenje daje teorija semplova. Po njoj je bilo koji signal moguće predstaviti semplovima uzetih na frekvenciji koja je bar duplo veća od maksimalne frekvencije originalnog signala. Šta to znači? Ukoliko je za period od 24 časa moguća pojava maksimalno dve plime i dve oseke, to predstavlja maksimalno 4 promene logičkog stanja na pinu. Da bi se svaka promena sigurno detektovala, semplovanje mora biti bar duplo brže od tih promena, odnosno biće potrebno bar 8 sempla dnevno. Ovo je minimalni dovoljan broj semplova, ali više semplova će svakako vernije prikazati signal. Na primer, po istoj teoriji svaki analogni audio signal (20Hz – 20 kHz) može se predstaviti digitalnim signalom semplovanim na (dovoljnih) 40kHz, međutim tako malim brojem semplova je teško razlikovati violinu od bas gitare. Dovoljan kvalitet postiže se tek pri desetostruko većoj frekvenciji (200kHz). Postoji li još neki način? Postoji i odnosi se na povećanje rezolucije semplova. To je treći problem. 111

Do sada je rezolucija semplova bila jednobitna, odnosno omogućavala je samo dva logička stanja (ima/nema vode). Sećate se da je pri učenju interapta predlagan metod merenja nivoa reke preko više ulaznih pinova. Ukoliko se za merenje koriste 3 pina, moguće je dobiti sledeća stanja: 000, 001, 011 i 111. Ona se mogu konvertovati u binarni oblik, i tada se dobija 00, 01, 10 i 11. Vidite da je dvobitnom rezolucijom moguće predstaviti 4 nivoa reke. Znači, ukoliko se za merenje nivoa vode koriste tri ulazna pina (umesto jednog), moguće je prikazati četiri nivoa reke uz dva bita unutar sempla. Duplo više bitova donosi i duplo povećanje memorije. Uglavnom je potrebno odabrati kompromis između dovoljnog broja semplova i njihove rezolucije, a to opet zavisi od konkretnih potreba merenja. Na primer za početni slučaj (merenje na svakih 10 minuta) uz tri sonde biće potrebno (6*24)*2 = 288 sempla, odnosno 288/8 = 36 bajtova dnevno. Međutim, sada će biti moguće dosta (četiri puta) preciznije pratiti povećanje i smanjenje nivoa. Pauzu između semplova treba što preciznije odrediti. To je četvrti problem. Greška od jedne sekunde unutar jednog sata za petnaest dana narasla bi na grešku od 6 minuta. Nekada to može biti zanemarljivo, ali nekada ne. Zbog što preciznijeg vremena semplovanje se uglavnom izvršava nakon prekoračenja tajmera (ili unutar interapta izazvanih tajmerom). Semplovanje nije ograničeno samo na merenje „egzotičnih“ signala kao što je nivo reke. U idućem poglavlju naučićete kako se semplovanje može efektno iskoristiti unutar debouncinga.

112

43. Debouncing Ranije ste videli da se debouncing može realizovati testiranjem tastera, pa kratkim čekanjem, i onda ponovnim testiranjem. Bolji način predstavlja testiranje tastera više puta, i izmenu jedino ukoliko je u svim slučajevima testiranja dobijeno novo stanje. Za testiranje se bez problema može iskoristiti semplovanje, sa tom pogodnošću što tada ranije opisanih problema nema. Dovoljno je napraviti petlju (ili petlju unutar petlje), uzeti sempl i resetovati petlju ukoliko se sempl promenio, kako bi testiranje ponovo počelo iz početka. Ukoliko se petlja završi, to znači da se stanje prekidača nije promenilo svo vreme trajanja petlje, pa tako zadnji sempl može biti uzet kao stabilno stanje prekidača. Ovako jednostavan princip ima naravno i par mana. Program se treba bar 20mS vrteti u petlji, i za to vreme neće moći da izvršava ostale operacije. Ukoliko kontakti prekidača neprestano varniče, program neće moći da izađe iz petlje. Osim toga interapti mogu izazvati privremen prestanak ili duže vreme testiranja prekidača. Dobar je jedino za programe gde se može dozvoliti čekanje na pritisnutost (ili otpuštenost) tastera. U ostalim situacijama trebalo bi koristiti testiranje prekidača unutar interapta izazvanih tajmerom. Kako se interapti izazvani tajmerom pozivaju prilično retko, potrebno je da semplovanje traje što kraće, odnosno da se u jednom prolazu uzme samo jedan sempl, uporedi sa prethodnim i smanji (uveća) unapred zadat brojač semplova. Ukoliko je sadašnje stanje sempla drugačije od prethodnog, brojač bi se ponovo inicijalizovao. Kada brojač (napokon) istekne, potrebno je saopštiti glavnom programu da je prekidač pritisnut (otpušten). Komunikacija između glavnog programa i interapta nije baš jednostavna. Uglavnom se primenjuje komunikacija preko par registara opšte namene. Na primer setovan bit 0 registra TASTERI značio bi da je pritisnut taster „LEVO“, a setovan bit 1 da je pritisnut taster „DESNO“. Glavni program trebao bi periodično testirati ove bitove, i u zavisnosti od njihovog stanja preduzimati određene akcije. U sledećim poglavljima upoznaćete se sa par komunikacionih protokola. Jedan deo je hardverski integrisan u savremenijim PIC mikrokontrolerima. Sigurno ćete primetiti kompromis između broja pinova koji se koriste za komunikaciju i brzine komunikacije.

113

44. Malo teorije oko memorije U početku beše DRAM. Klasičan predstavnik DRAM memorije je 4164 integrisano kolo. Njime je moguće adresirati ukupno 64Kbita (65536 bitova) podataka. Bitska matrica je unutar memorije organizovana u obliku redova i kolona. Da bi se pristupilo određenom bitu (bilo za čitanje ili upis podataka), potrebno je preko adresne magistrale pristupiti ćeliji u kojoj se taj bit nalazi. Zamislite mrežu zgrada u kojoj redovi imaju nazive ulica, a kolone brojeve zgrada.

Kroz takvu mrežu probija se naš glavni junak – nervozni poštar. On sa koverte čita dve informacije. Naziv (broj) ulice i broj zgrade. Za očitavanje kompletne adrese memorija bi morala imati čak 16 ulaznih pinova (8 za ulicu i 8 za broj). Ovo se uglavnom rešava multipleksom adresne magistrale (više o principu multipleksa naučićete kasnije), tako da se u memoriju najpre šalje broj reda, a za njim i broj kolone. Neophodna sinhronizacija obezbeđuje se preko dva (ovo je svakako manje od osam) dodatna pina. Poštar kao što sigurno već znate može obavljati dve operacije. Može doneti penziju, ili (doneti račun i) odneti penziju. Da li poštar doneti ili odneti penziju (čitati ili upisivati podatke u memoriju) zavisi od logičkog stanja WE (eng. Write Enable) pina. I na kraju memorija ima ulazni DIN (eng. Data In) i izlazni DOUT (eng. Data Out) pin. Njih je moguće povezati direktno na dva U/I pina mikrokontrolera. Međutim, kako je samo jedan od njih trenutno u funkciji u zavisnosti od stanja WE pina, oni se bez problema mogu spojiti jedan za drugi. Ukoliko se spoje, dobija se jedan U/I pin preko koga je moguće upisati ili pročitati jedan bit podataka sa predate adrese. Tako se jedan pin koristi i za ulaz i za izlaz (isto kao i pinovi mikrokontrolera). Naravno, prilikom čitanja podatka U/I pin mikrokontrolera povezan za magistralu podataka (spojeni DIN i DOUT pin) morao bi biti definisan kao ulazni (preko TRISA ili TRISB registra), a prilikom upisivanja kao izlazni.

114

To bi bilo to za čitanje i pisanje jednog bita. Za čitanje i pisanje jednog bajta moguće je redom čitati (ili pisati) u grupama od 8 bitova, ili kao kod Commodore 64 kompjutera paralelno adresnoj magistrali dodati još sedam 4164 DRAM memorija. U tom slučaju veličina adresne magistrale ostaje ista, a magistrala podataka umesto jednog zauzima čak 8 provodnika (ili 16 ukoliko se ulazni i izlazni pinovi memorije ne spoje jedan za drugi). Mogu se koristiti i 4464 memorije koje imaju u sebi 64Kbita * 4 (65536 * 4 bitova), odnosno uz istu adresnu magistralu imaju 4 pina na magistrali podataka (spojeni DIN i DOUT formiraju D1, D2, D3 i D4). Sada ono teško. Svaka bitska DRAM ćelija sastoji se od jednog kondenzatora i jednog tranzistora. Kako bi se kondenzator posle par mS potpuno ispraznio, ne bi više bio u stanju čuvati podatak, pa se morao povremeno (npr. svake druge milisekunde) osvežavati. Tako unutar Spectrum kompjutera Z80 mikroprocesor paralelno sa izvršavanjem instrukcija povremeno osvežava DRAM memoriju, dok kod C64 video kontroler osvežava memoriju za vreme dela instrukcijskog ciklusa u kome mikroprocesor ne pristupa memoriji. Mikrokontroler bi znači morao povremeno pročitati sadržaj celokupne memorije (ili bar onih memorijskih lokacija koje koristi), a zatim ih ponovo upisati. Teoretski, DRAM memoriju kapaciteta jednog bita možete dobiti povezivanjem kondenzatora direktno na U/I pin mikrokontrolera. Ukoliko mu se najpre određeno vreme dovede logička 1, kondenzator će se napuniti, i ukoliko se kasnije očita njegovo stanje taj pin će davati logičku 1. Ukoliko mu se pak dovede logička 0, kondenzator će se isprazniti, i kasnije će pri očitavanju davati logičku 0. Da se ne bi vremenom ispraznio, mora se povremeno očitati i osvežiti. DRAM memorija ima više mana nego prednosti. Punjenje i pražnjenje kondenzatora zahteva određeno vreme, tako da je vreme pristupa (eng. access time) ćelijama sporije od ostalih vrsta memorija. Memorija neće raditi u slučaju pokušaja očitavanja ili upisa većom brzinom od dozvoljene. Osvežavanje memorije troši dosta mikrokontrolerskog vremena. Zbog toga se DRAM memorija sve ređe koristi i pored niske cene. Razvojem elektronike pojavljuje se SRAM (statička RAM memorija) po pristupačnoj ceni. U njoj se memorijske ćelije sastoje od nekoliko tranzistora povezanih u formi Flip Flopa, tako da im osvežavanje nije potrebno, a jednom upisan podatak ostaje u SRAM memoriji sve do upisa sledećeg ili do gubitka napona napajanja. Za razliku od DRAM, u SRAM memoriji je napušten princip multipleksa adresne magistrale (zbog veće brzine), tako da se adresa željenog bita može zadati u jednom koraku. Klasičan njen predstavnik bila bi npr. 5564 memorija (SRAM 8Kbita * 8). Nezaobilazna je i EPROM memorija. Ona na sebi ima mali stakleni „prozor“ preko koga se može brisati. Naime, podaci se u EPROM mogu snimati preko odgovarajućih programatora specijalnom procedurom (kao snimanje koda u PIC). Taj proces obično zahteva više napone od radnih (+12V umesto +5V). Kada se podaci jednom snime u EPROM memoriju, ne mogu se snimiti naredni sve dok se EPROM određeno vreme ne izloži ultraljubičastoj svetlosti. Taj proces ubrzava „curenje“ naelektrisanja isprogramirane EPROM memorije, i na taj način se EPROM obriše. Tek onda je moguće ponovno programiranje. Većinu EPROM memorija moguće je postaviti u sleep mod, dovođenjem logičke 1 na njen CE (eng. Chip Enable) pin. 115

Ukoliko je na OE (eng. Output Enable) pinu EPROM memorije prisutna logička 1, svi pinovi magistrale podataka (D0 pa nadalje) naći će se u stanju visoke impedanse. To omogućava multipleks magistrale podataka, i njeno deljenje između EPROM i RAM memorije (Commodore 64 koristi isti princip sa svojom ROM memorijom). Pri radu sa bilo kojim eksternim memorijama morate obratiti pažnju na brzinu pristupa podacima (obično od 45nS do 450nS). Iako je uglavnom moguće donekle „overklokovati“ memoriju, to ne predstavlja dobru praksu. Jednom će svakako stradati. Bolje da to bude što kasnije. Kao što uočavate za upotrebu adresne i magistrale podataka potreban je veliki broj pinova, ali joj je i brzina maksimalna. Zbog toga se najviše koristi u kompjuterima. Mikrokontroleri se zbog velikog broja potrebnih pinova uglavnom uopšte ne povezuju sa eksternim hardverom adresnom magistralom, već se sve više razvija specifičan hardver, kojim se određenim komunikacionim protokolima može upravljati manjim brojem pinova, uz manju brzinu pristupa. Za više detalja pogledajte TB011 sa http://www.microchip.com/.

116

45. RS232 i RS423 Kako poslati podatak iz PIC mikrokontrolera u Vaš kompjuter? Postoje dva načina. Povezati potreban broj pinova porta B direktno za adresnu magistralu (npr. paralelni port kompjutera), i postaviti pinove porta B u određeno stanje, ili povezati samo 2 pina (jedan za slanje, a drugi za prijem podataka) na kompjuter (npr. serijski port) i slati podatke kroz njih bit po bit određenom brzinom. Očigledno je da bi paralelni prenos podataka trebao biti mnogo brži od serijskog. Međutim, brzina kojom kompjuter može pročitati ove podatke je (u odnosu na PIC) toliko mala, da se ne dobija nikakvo značajno povećanje brzine, a za prenos podataka je zauzeto više pinova mikrokontrolera. Osim toga, paralelni port ima prilično nestandardan interfejs, a ni komercijalno nisu dostupni programi za njegovu upotrebu. Sledećim programom prenosi se poruka u kompjuter, preko serijskog (RS-232) porta. Najpre je potrebno uneti poruku koja će se poslati. Najlakše je uneti je u PIC u obliku tabele. MPLAB asembler može sam vršiti konverziju ASCII koda, što olakšava unos poruke. ASCII kod za slovo T, označava se sa a'T' ili 'T'. ; ****** Tabela sa tekstom ****** Text addwf PCL,F ; dodaj W na PCL dt 'Zdravo!', 0x0D, 0x0A, 0x00 ; Vraća karaktere, ; 0x0D Vraća znak Return ; 0x0A Vraća oznaku za novi red ; 0x00 Označava kraj teksta Da bi se na serijski port poslao karakter, potrebno je u jednom registru čuvati redni broj slova koje se prikazuje (broj koji se dodaje na PCL) i pozvati rutinu za slanje karaktera, povećavajući svaki put vrednost u pointer registru. Kada se dodje do zadnjeg karaktera, iz tabele se vraća 0x00, na osnovu čega potprogram detektuje kraj niza karaktera. U rutinu se ulazi sa rednim brojem prvog karaktera (ofsetom) u W. Uzmi movwf Pet movf call addlw btfsc return call incf goto

; Postavi vrednost iz W u pointer poruke ; Stavi pointer u W ; Vraća ASCII karakter u W ; Setuje Zero flag ako je W = 0 ; Preskače ako Zero flag nije setovan ; Završava potprogram ako je W = 0 Slan ; Šalje karakter na serijski port POINTER,F ; Pozicioniraj pointer na sledeći karakter Pet ; Još karaktera POINTER POINTER,W Text 0x00 STATUS,Z

Serijski prenos podataka sastoji se od postavljanja odgovarajućeg pina na logičku 0 i logičku 1 u tačno određenim trenutcima. Njegovo uobičajeno stanje je visok logički nivo (1), a nizak nivo (0) pri tome označava startni bit. Pri brzini prenosa podataka od 4800 boda, vreme koje bit provede u stanju logičke 0 treba biti 1/4800 = 208μS. 8 bita podataka svaki trajanja jednog perioda slede za ovim startnim bitom. Visok logički 117

nivo duži od perioda jednog bita označava stop bit. Bitovi se šalju sa prvim bitom najmanje težine (LSB). Podatci se u kompjuteru čitaju na polovini bitskog perioda, da bi se pouzdanije detektovalo da li je odgovarajući bit na logičkoj 0 ili 1. Prilikom slanja ASCII koda slova A (b'0100 0001') u kompjuter bi se poslala ovakva sekvenca: START 0

0123 4567 1000 0010

STOP 1

Start i stop bit neophodni su radi sinhronizacije prijemnika sa predajnikom. Naponski nivoi RS232 porta su -3V ili niže za logičku jedinicu, i +3V i više za logičku 0. Ovo se uglavnom može zaobići, tako što se koriste nivoi od +5V za logičku 0 i 0V za logičku 1, ukoliko je kabl za povezivanje dovoljno kratak. Primećujete da je ovo obrnuto od onoga što biste mogli očekivati! Za tačno određivanje potrebnih pauza može se koristiti ranije opisan potprogram za kašnjenje sa 52 * 4μS petljom za jednu bitsku periodu pri 4800 boda. Kako sam program za slanje traje 12μS, u W će se naći broj 49. U potprogram se ulazi sa željenim karakterom u W. Izlaz za kompjuter je na PORTA registru, bit 2 (pin 1). Izl

movwf movlw movwf bsf

TXREG 0x08 BITOVI PORTA,2

; Stavi W u registar predaje ; 8 bitova podataka ; Brojac za bitove ; Startni bit (invertovan, sećate se) +5V na RA2

Pet

movlw call rrf btfsc

.49 Pau4 TXREG,F STATUS,C

goto bsf goto

Obr PORTA,2 Kraj

; 49 decimalno, vreme za kasnjenje ; U potprogramu za pauzu cekaj 49*4=196μS ; Prebaci zadnji desni bit u Carry flag. ; Ako je Carry flag = 0, želi se setovanje bita ; (nizak naponski nivo) ; u protivnom je bit = 0 (visok nivo) ; +5V na pinu 1 (RA2) ; Je li gotovo?

bcf nop

PORTA,2

; 0V na pinu 1 (RA2) ; da bi obe opcije trajale tačno 12μS

BITOVI,F Pet .52 Pau4 PORTA,2 .104 Pau4

; 1 bit manje. Preskoči kada dođe do 0 ; ima još bitova. Kašnjenje za slanje ovog. ; 52 decimalo, vreme za kašnjenje 208μS ; Kašnjenje za zadnji bit podataka ; 0V (visoko stanje) za stop bitove ; 104 decimalno ; za dva puta duži stop bit ; Povratak

Obr

Kraj decfsz goto movlw call bcf movlw call return

U ovim potprogramima prikazane su skoro sve potrebne rutine potrebne da bi PIC poslao poruku „Zdravo!“ u kompjuter preko serijskog porta. Ostalo je još njihovo povezivanje. Program koji sve to povezuje, mogao bi izgledati ovako: 118

Slan bsf movlw movwf bcf clrf movlw call movlw call Blok goto

STATUS,RP0 0x00 TRISA STATUS,RP0 PORTA .50 Kas 0x00 Izl Blok

; Prebacuje u BANK1 ; Postavlja sve pinove kao izlazne ; na PORTA ; Vraća u BANK0 ; RA2 = 0 (RS232 visoko stanje) ; Kasnjenje od 50 mS ; preko potprograma za duže pauze ; Ofset za prvi karakter poruke ; Slanje poruke u kompjuter ; Kraj u beskonačnoj petlji

Malo komentara o programu: Svi bitovi na PORTA registru su postavljeni kao izlazi. Kako program koristi tabelu, potrebno je testirati njeno prekoračenje. Redosled potprograma, naravno, nije bitan. Bitno je jedino da glavni program (Slan) bude prvi. Za ispravan rad programa, potrebno je osigurati dovoljnu preciznost takta oscilatora, pa se ovaj program može upotrebiti jedino uz kristalni oscilator od 4MHz. Za povezivanje sa kompjuterom dovoljno je pin 1 mikrokontrolera (RA2) povezati sa pinom 2 (RX) devetopinskog ženskog SUB D konektora, i masu (GND) na pin 5 konektora. Kabl ne bi trebao biti duži od 1,5m. U protivnom, morali bi se koristiti odgovarajući drajveri (obično se to radi integrisanim kolom MAX232) namenjeni pretvaranju logičkih nivoa sa pinova mikrokontrolera u nivoe pogodne za RS232 komunikaciju. Na strani kompjutera uključite Vaš terminalski program. U samom Windowsu imate Hyper terminal. Izaberite odgovarajući COM port i u podešavanjima izaberite 4800 bita u sekundi, 8 bita podataka, bez provere parnosti i jedan stop bit. Spojite konektor sa kompjuterom i uključite mikrokontroler. Svaki put kada ga uključite (ili resetujete), poruka „Zdravo!“ će se prikazati na ekranu. U programu nije korišćen Shaddow registar zbog jasnije ilustracije. Međutim, u realnoj situaciji bilo bi ga korisno implementirati. Iako je za serijsku komunikaciju neophodan tačno određen takt oscilatora, postoje softverske tehnike koje omogućavaju RS232 komunikaciju merenjem signala sa kompjutera, i kalibrisanjem sopstvenog vremena signala i pauze po ovom signalu. Time je omogućena upotreba jeftinijeg RC oscilatora dovoljne brzine. Za detalje pogledajte tehnička uputstva AN510, AN555, AN593 i AN712 sa http://www.microchip.com/. Savremeniji PIC mikrokontroleri imaju hardverski rešenu RS-232 komunikaciju. Kod RS423 drajvera prijemnik i predajnik su (kao kod RS232) polarizovani u odnosu na masu. Međutim, naponski nivoi su mu od -4 do -6 za logičku 1 i +4 do +6V za logičku 0. To omogućava da je (uz korišćenje istog komunikacionog protokola) RS423 kompatibilan sa RS232 drajverom, ali da može postići brzinu prenosa podataka do 100kB/S, kao i da signal sa jednog predajnika mogu istovremeno primati 10 prijemnika. 119

46. Algoritmi za detekciju grešaka Prilikom prenosa podataka moguće je da se na spojnim putevima jave određene smetnje. Na primer, ukoliko se mobilni telefon uključi u blizini kablova kojim su povezani PIC i kompjuter. Prilikom slanja podataka infracrvenom vezom moguće je da svetlost sunca ili sijalice ometa ispravan prijem. Pri radio vezi smetnje bi mogla izazvati grmljavina ili aktivnost lokalnog radio predajnika. Kako bi mikrokontroler mogao ispravno primati signale i u slučaju smetnji, poželjno je softverski detektovati smetnje i (ukoliko je to moguće) ukloniti ih iz korisnog signala. To ne znači da se sa time treba preterivati (u primeru u prošlom poglavlju pretpostavlja se da se mikrokontroler nalazi u neposrednoj blizini kompjutera pa je uticaj smetnji zanemarljiv), pogotovu što algoritmimi zauzimaju deo brzine i memorije mikrokontrolera i što su njima preneti podaci veći od originalnih, pa je slanje sporije. U vašem terminalskom programu primetili ste podešavanje provere parnosti. Kod nje bit nakon MSB sadrži informaciju o ispravno primljenih ranijih 7 bita. Kako funkcioniše provera parnosti? Najpre se bitovi 0-7 koda željenog karaktera redom sabiraju, i proverava se da li je njihov zbir paran broj (deljiv sa 2 bez ostatka). Ukoliko jeste MSB se setuje (parna parnost) ili resetuje (neparna parnost). Za slovo A (b'0100 0001') i neparnu parnost poslati bitovi bi izgledali ovako: START 0123 4567 BIT PARNOSTI 0 1000 0010 0

STOP 1

Terminalski program u kompjuteru nakon prijema sabira redom bitove 0-7 i uporedjuje njihovu parnost sa primljenim bitom parnosti. U slučaju neslaganja prijaviće grešku ili će jednostavno ignorisati primljeni karakter. Ovaj princip je dovoljno pouzdan za detekciju greške nad jednim bitom poslatog podatka. Međutim, u slučaju pojave greške nad više bitova bit parnosti nije dovoljan. Umesto provere bita parnosti može se određeni broj primljenih bajtova sabrati i uporediti njihov zbir. Na primer ukoliko se u kompjuter šalju sledeći podatci: 3, 8, 15, 4, 26, 87 u mikrokontroleru bi se izračunao njihov zbir 3+8+15+4+26+87=143 koji bi se poslao nakon podataka unutar par dodatnih bajtova. Kompjuter bi nakon prijema sabrao sve podatke i uporedio dobijeni rezultat sa primljenim. Taj princip naziva se provera ukupnog zbira (eng. checksum). Nažalost sa njim su prenešeni podatci duži, a ni on nije pouzdan u slučaju pogrešno primljena 2 (ili više) bita (ukoliko na primer nije primljen nijedan bit podataka niti kontrolne vrednosti, svi “primljeni“ bajtovi kao i njihov zbir biće jednaki 0, što pogrešno indikuje ispravno primljene podatke). Ovo je ipak mnogo pouzdanije od provere parnosti. Više o checksumu imate u TB026. Najpraktičniji način detekcije grešaka u prenosu postiže se primenom CRC (eng. Cyclic Redundancy Check) algoritma, koji pruža najbolji kompromis između brzine algoritma, pouzdanosti detekcije greške i veličine dodatno prenetih podataka. Više o njegovom principu imate u AN730. 120

U slučaju dvosmerne komunikacije (mikrokontroler ka kompjuteru i kompjuter ka mikrokontroleru) moguće je nakon detektovane greške u suprotnom smeru poslati podatak o rednom broju neispravnog podatka, i na taj način zatražiti jedino njegovo ponovno slanje, ili pak ponovno slanje cele grupe podataka (tačnije za signalizaciju greške pri RS232 vezi koriste se dodatni provodnici, ali se oni uglavnom izbegavaju). Svakako da je ovaj način prilično vremenski zahtevan, a nije ni moguć u slučaju jednosmerne komunikacije. Da ti problemi prevazišli primenjuju se algoritmi za korekciju grešaka. Oni će biti detaljnije objašnjeni u narednom poglavlju. Uglavnom je potrebno pronaći kompromis između najčešćih vrsta grešaka i količine prenetih podataka za spojni put (provodnici, optička veza, audio veza, radio talasi...) koji se koristi. Pri tome mnogo može pomoći odgovarajući izbor modulacije signala. Prilikom RS232 komunikacije signali se modulišu preko odgovarajućeg drajvera (MAX232) koji pretvara naponske nivoe od +5V i 0V u +15V i -15V, i dalje se oni tako modulisani prenose kroz provodnike. Kod USB ili I2C veze naponski nivoi su 0V i +5V. Kod ostalih vrsta spojnih puteva uglavnom je neophodno eliminisati jednosmernu komponentu napona (dužu pojavu logičke 0 i logičke 1). Zbog toga se za modulaciju sporijih (npr. audio) veza mogu primenjivati RTTY, DTMF, FSK, PSK i razni drugi načini. Za modulaciju bržih (npr. optičkih) veza najčešće vrste modulacije su Manchesster, CMI, Miller, MCMI i 5B6B. Iako je radio, audio ili optička komunikacija nesumnjivo interesantna, prevazilazi okvire ovog uputstva, tako da će nadalje biti objašnjena jedino veza žičanim provodnicima. Uz neodgovarajući izbor modulacije neće Vam pomoći ni najbolji korektivni algoritam. Pogledajte samo kolike su razlike u brzini prenosa podataka preko RS232 i SPI veze, ili u daljini preko I2C i RS485 veze!

121

47. Algoritmi za korekciju grešaka Najjednostavniji algoritam za korekciju poslatih podataka zahtevao bi prenos podataka 3 puta, pri čemu bi se za ispravno primljene podatke uzeli samo oni koji su bar u dva slučaja ista. Na taj način istovremeno je realizovana i detekcija i korekcija grešaka. Međutim, taj princip je prilično neefikasan, jer su preneti podaci tri puta duži od originalnih, pa i prenos podataka traje tri puta duže. Algoritam za korekciju jednog bita u tri poslata bajta mogao bi se realizovati po sledećem principu. Pretpostavimo da je potrebno RS232 vezom preneti dva bajta (nazovimo ih A i B). Radi detekcije grešaka šalje se i bit parnosti. Neposredno nakon njih pošalje se i bajt C koji predstavlja rezultat XOR operacije nad bajtovima A i B. Ispravna situacija izgledala bi ovako: A P 1011 1001 1

B P 0110 1011 1

C P 1101 0010 0

Međutim ukoliko bi u prenosu podataka došlo do greške u bajtu A, događa se sledeće: A P 1010 1001 1

B P 0110 1011 1

C P 1101 0010 0

Prijemnik bi najpre na osnovu bita parnosti detektovao da je pogrešno primljen bajt A. Da bi ga regenerisao primenjuje XOR nad ispravno primljenim bajtovima B i C. Ovo je slično zakonima u matematici: Ukoliko je A*B=C, onda važi i A=C/B i B=C/A. 0110 1011 B XOR 1101 0010 C = 1011 1001 A Da je pogrešno primljen bajt B izvršila bi se XOR operacija nad bajtovima C i A, a da je pogrešno primljen bajt C, ne bi se ni izvršavala korekcija, jer su nam bitni jedino A i B. Specijalan slučaj predstavljao bi pogrešno primljen bit parnosti A ili B bajta. Onda bi se regenerisani bajt uporedio sa originalnim, i u slučaju da su oba bajta ista zaključio da je pogrešno primljen upravo bit parnosti. Kako je proverom bita parnosti moguće ispravno detektovati korupciju samo jednog bita unutar bajta, ovaj princip pogodan je jedino za regeneraciju jednog bita unutar 3 poslata bajta (A, B i C). U slučaju korupcije više bitova, potrebno je koristiti drugačije algoritme.

122

48. I2C RS232 komunikacija pogodna je jedino za direktno povezivanje dva uređaja. Njom je teško povezati PIC sa više uređaja istovremeno (npr. sa A/D konvertorom, dodatnom EEPROM memorijom i još jednim mikrokontrolerom). Svakako da je takvu komunikaciju moguće ostvariti direktnim povezivanjem pinova mikrokontrolera, ali to troši njihove dragocene pinove, i komplikuje softver zbog različitih komunikacionih algoritama. I2C (eng. Inter Integrated Circuit bus) veza omogućava povezivanje mikrokontrolera sa jednim ili više dodatnih uređaja koristeći za to samo dva pina, i I2C komunikacioni protokol. Naravno, i ti uređaji moraju imati mogućnost (softversku ili hardversku) I2C komunikacije. Zadnjih godina pojavljuje se sve više hardverskih dodataka koji proširuju upotrebu mikrokontrolera, a za komunikaciju koriste upravo I2C vezu (umesto ranije adresne i magistrale podataka). U I2C vezi moguće je imati jedan glavni mikrokontroler (eng. Master) koji upravlja dodatnim I2C hardverom (eng. Slave), ili pak više glavnih mikrokontrolera (eng. Multimaster) od kojih svaki može upravljati dodatnim Slave I2C hardverom. U nastavku će biti opisan jedino prvi slučaj. I2C veza je specifična po tome što se logička 1 ne šalje na uobičajeni način, već predajnik prilikom predaje logičke 1 prelazi u stanje ulaza (visoke impedanse), a logička 1 se javlja pod uticajem (eksternog ili internog) pull up otpornika. Prijemnik je za to vreme takođe u stanju ulaza, ali on (za razliku od predajnika) vodi računa o signalu koji prima. Na taj način omogućena je komunikacija preko jedne linije, uz nemogućnost kratkog spoja. Preko druge linije Master obezbeđuje takt neophodan za sinhronizaciju prijemnika signala. Takt mora biti strogo sinhronizovan sa slanjem signala. Postoji ograničenje njegove maksimalne brzine, ali ne i minimalne, tako da će Slave prilikom slanja podataka po potrebi čekati dok Master ne bude slobodan za njihov prijem (tj. dok Master ne pošalje takt). Kako je algoritam I2C protokola razvijen tako da je nemoguće da dva uređaja istovremeno šalju podatke, svaki Slave ima svoju jedinstvenu adresu preko koje mu se pristupa. Jedan deo adrese mu fabrički dodeljen na osnovu funkcije, a drugi deo bira se fizičkim prespajanjem pinova. Svakom Slave hardveru povezanom sa Masterom treba inicirati slanje ili prijem podataka. U slučaju da je potrebno neprekidno testiranje Slave hardvera, neprestano bi se izvršavala njihova prozivka (kao u Vojsci). Prilikom prijema bajta za adresiranje Slave hardvera svaki od priključenih Slave detektuje da li se radi o njemu, i preduzima traženu akciju (obično slanje ili prijem par bajtova). Svaki Slave hardver ima svoje specifičnosti tako da se moraju proučiti njegovi tehnički podatci. Na primer prilikom snimanja bajta u I2C EEPROM memoriju potrebno je poslati 7 bita za adresiranje baš tog Slave hardvera (resetovan LSB u njemu inicira upis), 2 bajta za adresu (za memorije do 64Kb) i 1 bajt podatka. Za čitanje se šalje 7 bita za adresiranje Slave hardvera (setovan LSB inicira čitanje), 2 bajta za adresu i čita se 1 bajt. Početak, kraj kao i razdvajanje bajtova realizovani su slično kao u RS232 komunikaciji preko START, STOP i još par kontrolnih bitova. Isto kao RS232 i I2C protokol je hardverski implementovan u moćnijim PIC mikrokontrolerima. Za više detalja pogledajte AN515, AN541, AN554 i AN578. 123

49. RS485, RS422 RS232 zahteva napone od -3V i niže, i +3V i više. RS423 napone od -4 i niže, i +4 i više. I2C napone od +5V i 0V. Međutim, njihovi drajveri koriste zajedničku masu, tako da i pored tolike razlike napona nisu pogodni za veće daljine zbog mogućih smetnji. Smetnje koje mogu biti indukovane (u odnosu na masu) mogu na strani prijemnika uticati na pogrešnu detekciju napona. Zbog toga je za veće daljine praktičnije koristiti diferencijalni predajnik i prijemnik. Kod diferencijalnog primopredajnika umesto linije za signal i mase koriste se dve linije (A i B) za signal, i zajednička masa. Kada je na liniji A +5V na B je 0V i to predstavlja logičku 1. Logičku 0 predstavlja 0V na A i +5V na B liniji. U prijemniku se detektuje razlika napona na ove dve linije. Zbog uspešne detekcije razlika napona mora biti bar 0,2V, ali drajveri će po RS485 standardu raditi i sa bilo kojim naponima od -7V do +12V. Kako se indukovane smetnje javljaju na svim provodnicima, one se potiru, omogućavajući brzinu prenosa od 10Mb/S do 10m daljine, ili 100kb/S do 1,2km. U slučaju da brzina nije bitna, softver se podešava za najmanju (a ipak dovoljnu) brzinu. U protivnom, postepeno se povećava brzina do pojave grešaka. Onda se brzina malo smanji, i ostavi na toj vrednosti. Za detekciju grešaka mogu se koristiti ranije opisani algoritmi. Početni i krajnji drajver trebaju na svojim ulaznim / izlaznim pinovima imati „terminatorske“ otpornike kojima se eliminiše refleksija signala sa krajeva linija. Budući da je preko PIC mikrokontrolera moguće jedino predati, a ne i primiti signale sa RS485 veze (Ovo nije sasvim tačno. Za detekciju bi se mogli koristiti integrisani komparatori napona ili A/D konvertori prisutni u moćnijim mikrokontrolerima, ali sa lošijim rezultatima), za detekciju signala moraju se koristiti MAX485, TI 75175, DS1487 ili SN75176 drajveri. Iako je sasvim moguće direktno sa pinova mikrokontrolera proizvoditi potrebne predajne napone, poželjno je i za to koristiti ova kola, jer su ona projektovana tako da smanjuju električne smetnje, čak i u slučaju nepostojanja terminatorskih otpornika. Iako je primenom RS485 komunikacionog protokola moguće postići velike daljine koristeći jeftine linije (npr. telefonske parice), radi boljih rezultata i većih daljina poželjno je izabrati provodnike čija je impedansa približno jednaka ulaznoj impedansi prijemnika. Za manje brzine i daljine ovo ne bi trebalo predstavljati problem. Pre projektovanja kola, proučite tehničke podatke odgovarajućih kola, jer se njihove karakteristike prilično razlikuju. Na primer uz MAX481, MAX483, MAX485, MAX487 i MAX1487 moguće je ostvariti dvosmernu naizmeničnu komunikaciju (simpleks) preko samo dve linije, dok je MAX488 i MAX490 kolom moguć istovremen prijem i predaja, ali preko četiri linije (dupleks). MAX488 ili MAX491 drajverom moguće je realizovati repetitor signala koji postavljen na polovini linije regeneriše signal i tako omogućava duplo duže linije. Postoje i galvanski izolovani drajveri (pogodni za područja sa jakim smetnjama – grmljavinom), npr. MAX253 i MAX1480. Ipak, najbolje je u tim slučajevima ukopati linije ili koristiti koaksijalne ili optičke kablove (još kada bi i Telekom Srbije to shvatio). 124

Kako je RS485 protokolom moguće da se pinovi predajnika isključe (tako što pređu u visokoimpedansno stanje – slično ulazima mikrokontrolera), moguće je na taj način kao u I2C protokolu preko istih linija paralelno povezati više mikrokontrolera. Naravno, mora se povesti računa o sprečavanju istovremene predaje (npr. pojedinačnim asdresiranjem kao u I2C protokolu). Ovo je moguće jer RS485 standardom nije propisan komunikacioni softver, već jedino hardver. To znači da možete napisati sopstveni komunikacioni protokol (ili koristiti gotovi RS232 – pogotovu ukoliko je hardverski implementovan u mikrokontroleru) koji će zadovoljiti vaše konkretne potrebe. To pruža slobodu programeru da unutar protokola ugradi sopstvene algoritme „prozivke“ više dodatnih mikrokontrolera (do 32 ili uz više drajvera u jednom integrisanom kolu do 256), algoritme detekcije i korekcije grešaka, jednom rečju da koristeći standardan stabilan komunikacioni hardver softverom komunicira na koji god način želi. Korišćenjem repetitora moguće je realizovati virtuelno beskonačne mreže. Međutim uz veće daljine i više povezanih mikrokontrolera (pogotovu uz repetitore) kašnjenje signala može biti preveliko. Što duže linije, to veće kašnjenje, samim tim i manja brzina. Najveća razlika između RS485 i RS422 protokola je u predajniku. RS422 predajnik ne može se naći u stanju visoke impedanse, tako da mikrokontroler može jedino slati signal preko dve linije, dok bi taj signal moglo istovremeno primati do 10 prijemnika. Za više detalja pogledajte AN1076. Osim ovih, postoji još par RS (eng. Recommended Standard) protokola poput RS449 i RS530, međutim budući da oni predstavljaju varijaciju već opisanih principa, kao i da se retko kada koriste, ovde neće biti razmatrani.

125

50. DMX512 Ponekad je dovoljno slati informacije samo u jednom smeru. DMX512 (eng. Digital MultipleX) predstavlja komunikacioni protokol sposoban za adresiranje do 512 prijemnika i koji se uglavnom koristi za upravljanje rasvetom. Za povezivanje se koriste RS485 drajveri, a protokol predstavlja softver za upravljanje tim drajverima. Kako se DMX512 protokolom povezuje jedan predajnik sa više prijemnika samo u jednom smeru, prijemnici nemaju način signalizacije neispravno primljenog podatka. Konkretno za slučaj rasvete, to im nije ni potrebno. Čak i da dođe do greške, ionako će naredni podatak sadržati ispravnu vrednost jačine svetla. DMX512 protokol napravljen je tako da se podaci neprestano (tačnije bar jednom u sekundi) šalju prijemnicima. Pošto je RS232 komunikacioni protokol integrisan u novijim mikrokontrolerima, DMX512 predstavlja modifikaciju RS232 protokola kako bi se njim preko RS485 drajvera moglo adresirati do 512 prijemnika. Modifikacija se sastoji u drugačijem obliku START bita (dosta duža logička 0 pa 1), STOP bita (dve logičke 1) i rednom slanju svih 512 bajtova sa STOP bitovima između njih. Broj poslatih bajtova mogao bi se smanjiti za slučaj manjeg broja prijemnika. Prijemnici bi morali redom brojati primljene bajtove kako bi videli koji je bajt za njih. Više detalja imate u AN1076 i na www.esta.org.

126

51. LIN LIN komunikacioni protokol podržava dvosmernu komunikaciju preko jednog provodnika (+ masa). Protokol je nastao ukrštanjem I2C i RS232 protokola. Napon na liniji je u neaktivnom stanju na nivou logičke 1 generisane (kao kod I2C) pull up otpornikom. Bilo koji član mreže (eng. nod) može na liniju poslati logičku 0, koja na taj način prelazi u dominantno stanje i briše postojeću logičku 1. Za razliku od I2C veze umesto linije za takt, podaci se kroz provodnik prenose asinhrono, kao kod RS232 veze. Napon na liniji (generisan pull-up otpornikom) iznosi od 9 do 18V u odnosu na masu. LIN protokol je zbog većeg broja nodova napravljen tako da mikrokontrolerima omogući što jeftiniji hardver, pa je zato moguće koristiti RC oscilatore, pri čemu se svi slave nodovi softverski sinhronizuju sa masterom po prijemu njegovog signala. Zbog toga kao sinhronizacioni impuls pre svake poruke master šalje bajt b'01010101'. Tako je svakom slave nodu omogućena sinhronizacija korekcijom sopstvenih vremenskih rutina u skladu sa primljenim bitskim vremenima logičke 0 i 1. Nakon sinhronizacionog bajta sledi jednobajtno zaglavlje, u kome se saopštava kakvi podaci slede. U njemu 4 bita (bit 0 do bit 3) adresiraju nodove na liniji, 2 bita (bitovi 4 i 5) određuju dužinu informacija (2, 4 ili 8 bajtova), i zadnja 2 bita (6 i 7) služe za proveru parnosti zaglavlja. LIN protokolom nije specifiran format narednih informacija, osim SLEEP komande i checksuma informacija. Kako nakon pojave greške LIN protokolom nije omogućena njena prijava, master može u delu sa informacijama zatražiti prijemni status od pojedinačnih nodova. Svi nodovi mogu primati poruke od ostalih nodova direktno, tako da dodatna intervencija mastera u tom slučaju nije potrebna. Ipak, master mora obezbediti povremenu prozivku nodova u slučaju da su njihovi podaci potrebni ostalim nodovima. Master može poslati sve nodove u sleep mod, slanjem identifikacionog bajta 0x80. Ostali nodovi po prijemu ove komande trebaju podesiti interapt po promeni stanja na pinu na liniji, tako da i oni mogu otići u sleep mod. Bilo koji nod može probuditi ostale slanjem 0x80 koda. Po njegovom prijemu svi nodovi se bude i čekaju dalje informacije od mastera. LIN protokol nije stekao veliku popularnost zbog kašnjenja u proizvodnji odgovarajućih integrisanih drajvera, male daljine i podložnosti smetnjama usled direktno polarisane linije. Za više detalja pogledajte AN729, AN235 i AN237.

127

52. DALI DMX512 komunikacija je jednosmerna. Zato joj je primena ograničena na upravljanje rasvetom. Međutim, njen princip je nepraktičan u slučaju kvara sijalice (reflektora). Zgodnije bi bilo kada bi bilo moguće da drajver za sijalicu detektuje da li ona zaista radi, i da po potrebi obavesti master o kvaru. DALI (eng. Digitally Addressable Lighting Interface) protokol je namenjen upravljanju pre svega fluo cevima. Zbog čega baš njima? Zbog toga za istu potrošnju električne energije jaču svetlost od njih (Lm/W) daju jedino metal-halidne, sodijumske (i niskog i visokog pritiska) sijalice, kriogenske i retki Luxeon eksperimentalni tipovi LED. Što se tiče početnih investicija, od svih ovih tipova jedino fluo cevi se mogu nabaviti po povoljnoj ceni. Iako jedna fluo cev košta oko 1,3€ (u odnosu na sijalicu sa užarenim vlaknom koja je oko 0,2€), vremenom će se isplatiti kroz manji račun za električnu energiju. Verujte mi na reč. Imam ih u svim prostorijama osim kupatila (zbog vlage). Iako se regulacija svetlosti sijalica sa užarenim vlaknom lako implementira faznom regulacijom, kod fluo cevi sa prigušnicama je to mnogo teže izvesti. Tek su se oko 2000-te godine pojavili tranzistori dovoljno jeftini i dovoljno velikog probojnog napona da mogu poslužiti kao konvertori mrežnog napona u napon potreban za rad fluo cevi. Taj princip koristi DALI za funkciju dimera (eng. DALI dimming ballast). Dimerom je omogućeno da se potrošnja električne energije još više smanji. Na DALI interfejs moguće je povezati do 64 nodova. Regulacija svetlosti postignuta je u 255 koraka, ali logaritamskog odnosa. On pruža prirodniji odnos pojačanja i smanjenja svetlosti. Takođe je moguće proizvesti i moćne efekte postepenog pojačanja ili smanjenja svetla, podešavalje svetla po grupama i slično. DALI protokol nema posebne integrisane drajvere. Umesto njih, implementirani su diskretnom tehnologijom. Tačnije, za prijem i predaju signala koriste se optokapleri, čime je pored niske cene drajvera omogućeno i galvansko odvajanje linije od mrežnog napona. Kako je DALI protokol rezultat saradnje Microchipa i International Rectifiera, dodatne informacije o DALI protokolu mogu se jedino naručiti na CD-u sa sajta http:// www.irf.com/product-info/lighting/. Za više detalja pogledajte AN809 i AN811.

128

53. SPI SPI (eng. Serial Peripheral Interface) predstavlja komunikacioni protokol namenjen brzom prenosu signala, na kratkim odstojanjima. Iako SPI protokol nema ograničenje najmanje brzine, zbog bržeg prenosa veće količine podataka se mikrokontroleru obično zabranjuje izvršavanje ostalih operacija. Upravo zbog toga Vaš digitalni foto aparat ne možete istovremeno koristiti kao web kameru, niti na MP3 plejeru ne možete slušati muziku dok je povezan sa kompjuterom. Obično se koristi prilikom komunikacije sa serijskim EEPROM memorijama, kao i memorijskim karticama (MMC, SD, xD, CF...). Iako memorijske kartice u osnovi predstavljaju veliku EEPROM memoriju, imajte u vidu da je proces formiranja sistema za podršku fajlova (eng. Filesystem npr. FAT16, FAT32 ili NTFS) u memorijskim karticama kao i sistem snimanja i čitanja fajlova iz takvog fajl sistema prilično komplikovan, tako da PIC16 serija mikrokontrolera obično nema dovoljno resursa za njeno efektno korišćenje. SPI protokol sličan je I2C protokolu, sa glavnom razlikom adresiranja raznih slave uređaja preko posebnog pina, a ne prozivkom njihove adrese. Na taj način slave hardver ne mora imati dodatne pinove za formiranje svoje adrese, ali mikrokontroler mora obezbediti po jedan pin za adresiranje svakog slave hardvera ponaosob. Za jedan SPI slave hardver dovoljne su tri linije, a svaki naredni mora imati svoj CS (eng. Chip Select) pin. Ukoliko je na CS pinu povezanom na odgovarajući slave SPI hardver prisutna logička 0, onda će on reagovati na signale sa ostale dve linije. U protivnom, ignorisaće ih i njegovi pinovi biće neprestano u stanju visoke impedanse, omogućavajući adresiranje ostalih slave SPI hardvera. Interesantna je mogućnost istovremenog slanja podataka svim Slave hardverima ukoliko su sve CS linije na logičkoj 0 (svi slave očekuju podatke). Isto kao kod I2C protokola, mikrokontroler (master) je uvek zadužen za generisanje takta preko SCK linije. Preko druge (SI) linije sinhronizovano sa taktom šalju se podatci u ili iz mikrokontrolera. Za više detalja pogledajte AN248, AN648 i AN909. Isto kao i RS232 i I2C kod moćnijih mikrokontrolera je SPI hardverski implementovan.

129

54. INKnet RS485 standardom propisan je jedino hardver. INKnet predstavlja softver razijen od strane Ed Nisley-ja, a čiji su principi opisani u Circuit Cellar časopisu. Za razliku od DMX512 protokola, INKnet protokolom moguća je dvosmerna komunikacija. Iako je INKnet protokol prvenstveno razvijen za 8052 mikroprocesor (tih godina su mikrokontroleri bili retki i skupi), protokol se može iskoristiti ili prilagoditi bilo kom današnjem mikrokontroleru. Komunikaciju inicira centralni mikrokontroler (master), šaljući zahtev za informacijama pojedinačnim ćelijama (nodovima - eng. node). Oblik poruke je takav da se u njoj pre informacije šalje desetobajtno zaglavlje, a nakon njega informacije sve do maksimalne veličine poruke od 255 bajtova. bajt 0 – rezervisano, mora biti 0 bajt 1 – dužina poruke sa zaglavljem (9 do 255) bajt 2 – adresa noda primaoca informacije bajt 3 – komanda primaocu bajt 4 – adresa noda pošaljioca informacije bajt 5 – adresa rezervisanog noda bajt 6 – MSB bajt status flagova noda bajt 7 – LSB bajt status flagova noda bajt 8 – LSB bajt checksuma bajt 9 – MSB bajt checksuma bajtovi 10 do 255 – informacije Uočavate da je ovim načinom moguće poslati maksimalno 245 bajtova informacija. Više informacija moralo bi se poslati unutar više poruka (kao SMS poruke). Iako svi nodovi mogu istovremeno primiti informacije, master je taj koji će na osnovu zaglavlja (i informacija) regulisati rad i komunikaciju između nodova. Slično kao adresa noda primaoca i pošaljioca, rezervisani nod će nadalje odgovarati na poruke pošaljioca koji ga je rezervisao. Komanda primaocu ukazuje šta nod primaoc poruke treba uraditi sa informacijom. Ovde su prikazane standardne komande, ali mogu se po potrebi proširiti, što zavisi od konkretnih zahteva mreže. 80 - POLL Poll from master to node 81 - STATUS Status response from node to master 82 - UNBUSY Force node "unbusy" regardless of actual status (use with caution!) 88 - RESERVE Reserve node for exclusive use of "from" node (except for polls & responses) 89 - RELEASE Release node for general use (may be sent by any node) 90 - CONSOUT Console output (to display) 91 - CONSIN Console input (from keyboard) 92 - CONSECHO Echo of console input message 93 - CONSFILE Console input (from file) 130

Unutar status bajta noda, takođe (kao kod STATUS registra mikrokontrolera) određeni flagovi opisuju funkcije noda. Flagovi su sledeći: 15 - BUSY Node is busy handling previous message 14 - OVERRUN At least one previous message was lost 13 - ECHO Node will echo all CONSIN messages 12 - LFSTRIP Node strips LF after CR on CONSIN msgs 11 - CSUM Node detected a checksum error 10 - reserved 09 - reserved 08 - MASTER Node is network master Flagovi od 0 do 7 su rezervisani. Ovakav princip omogućava efikasnu integraciju standardnog RS485 drajvera i namenskog softvera za pravljenje sopstvene mreže mikrokontrolera. Detekcija grešaka implementirana je checksumom, a korekcija ponovnim slanjem informacije ukoliko prijemni nod pošalje zaglavlje sa setovanim CSUM bitom njegovog status bajta. Za više detalja pogledajte časopise Circuit Cellar broj 10 (avg/sep 1989), 11 i 12. U njima možete pronaći i objašnjenja interesantnih principa komunikacija bez mastera (detekcijom kolizije ili rednim transferom dozvole predaje od jednog ka drugom nodu). Unutar istih časopisa možete videti i organizacionu strukturu složenijih komunikacionih protokola, formiranu po slojevima (eng. Layers) u CEBus protokolu. Za jednostavniji komunikacioni protokol preko RS485 drajvera pogledajte časopis Circuit Cellar broj 21.

131

55. S-ARTnet INKnet protokol sa RS485 drajverima pored očiglednih prednosti ima i par mana. Pored signala, svakom nodu potrebno je dovesti i napon napajanja (+5V i 0V). Bilo bi svakako jeftinije ako bi se broj provodnika mogao na neki način smanjiti. S-ARTnet (eng. Serial, Addressable, Receive/Transmitter) protokol rešava ovaj problem, tako što se kroz dva provodnika prenosi i napon napajanja i koristan signal. Ovo je omogućeno tako što izlazni napon drajvera može biti 15V, 7,5V ili 0V. Prijemnik na osnovu ovih napona detektuje da li je poslata logička 0 ili logička 1. Kako napon od 0V traje prilično kratko, nodovima će za to vreme napajanje obezbeđivati kondenzator. S-ARTnet protokolom moguće je adresirati do 30 slave nodova. S-ARTnet protokol kao i INKnet ima master koji za komunicira sa pojedinim slave nodovima. Međutim, njegovi slave nodovi nisu dodatni mikrokontroleri, već ih predstavlja specijalizovano integrisano kolo CS212. Ono u sebi ima objedinjen komunikacioni protokol, dva ulazna i dva izlazna pina i ulazno izlazni drajver. Adresa odgovarajućeg slave noda hardverski se postavlja povezujući pinove CS212 kola ka masi ili naponu napajanja (slično kao kod I2C). Master i slave nodovi komuniciraju preko 10-bitnih poruka. Poruka može biti jedna od 3 sledeća tipa: 1. Sinhronizacija – Master šalje poruku 0111111110. Na osnovu nje svi slave nodovi sinhronizuju svoj takt. 2. Piši – Master šalje poruku tipa A0 A1 A2 A3 A4 Pa Wr D0 D1 Pd gde A0 do A4 bitovi sadrže adresu željenog noda, D0 i D1 logičko stanje koje se treba postaviti na izlaznim pinovima CS212 kola, Wr bit (1 za indikaciju upisa) i Pa i Pd bitove za proveru parnosti adrese i ostatka poruke 3. Čitaj – Master šalje poruku A0 A1 A2 A3 A4 Pa Rd gde su A0 – A4 bitovi adrese, Pa bit za proveru parnosti adrese i Rd bit (0 za indikaciju čitanja). Po prijemu, CS212 šalje poruku I0 I1 Pd gde su I0 i I1 logička stanja na njegovim ulaznim pinovima, a Pd je bit provere parnosti. S-ARTnet kao ni DALI ne sadrži integrisane drajvere za master, ali ih ima u CS212 kolima. Neophodna konverzija logičkih nivoa se za master obezbeđuje odgovarajućim konvertorima signala. Preko ovog protokola master može adresirati do 30 slave nodova, odnosno očitavati 60 udaljenih ulaznih pinova, i postavljati do 60 udaljenih izlaznih pinova slave nodova. Po potrebi, master može periodično vršiti prozivku svih nodova. Zbog male dužine poruka i trostepenog stanja na liniji, moguće je prozivati svih 30 nodova 6 do 7 puta u sekundi. Više o ovom protokolu imate u časopisu Circuit Cellar broj 21.

132

56. CAN Svi raniji principi zahtevaju softversku detekciju i/ili korekciju grešaka u okruženju podložnom smetnjama. Naravno da je to moguće uraditi (kao u INKnet protokolu), ali Microchip se potrudio pa je softver koji bi inače opterećivao mikrokontroler prebacio u hardver. Tako jedno integrisano kolo (MCP2510 ili MCP2515) obavlja komunikacionu funciju (u kojoj je implementirana CRC detekcija grešaka, korekcija grešaka, izazivanje interapta po prijemu signala...), a drugo predstavlja drajver za spojni put (MCP2550 ili MCP2551). Drajverom upravlja komunikacioni čip, a komunikacionim čipom mikrokontroler preko SPI protokola. Isto kao RS485, i CAN standard koristi diferencijalne signale. Međutim, za razliku od RS485, CAN standardom propisan je i komunikacioni protokol. U njemu je mikrokontroler rasterećen od komunikacionih algoritama, i može svu svoju snagu upotrebiti za ono za šta je i namenjen. Po CAN protokolu ne vrši se (kao kod I2C ili INKnet) prozivka svakog pojedinačnog noda. Ne. Nodovi se ne adresiraju ni posebnim pinovima kao kod SPI protokola. Umesto toga, nodovi su ravnopravni. Svi oni moraju određeno vreme „osluškivati“ stanje na liniji pre nego što počnu sa predajom, kako ne bi upali u već postojeću vezu. Ukoliko se ipak dogodi da dva ili više nodova istovremeno započnu predaju podataka, na scenu stupa kolo za detekciju kolizije (eng. Collision Detection). Po detekciji kolizije nod koji je prvi predao logičku 0 unutar podatka nastavlja sa predajom, dok ostali (čim detektuju 0 dok u stvari šalju 1) momentalno prestaju sa predajom, čekaju dok se ne završi sa slanjem kao i neko vreme nakon toga (da se ne bi javilo novo preplitanje), i tek onda pokušavaju novu predaju. Kako je logička 0 „dominantna“, ona će uvek prebrisati logičku 1 (slično kao u I2C). Na taj način podatak će stići do prijemnika neizmenjen i bez ikakvog kašnjenja ili korekcije, a za komunikaciju se (zbog iste linije za slanje i prijem podataka) koriste samo dva provodnika (i zajednička masa). U CAN mreži pojedinačni nodovi nemaju adrese. CAN protokol nije adresno već komandno orjentisan sistem. Zbog toga nodovi obično komuniciraju između sebe periodično šaljući poruke po liniji. Ako je nekome potrebna, eto mu je. Ukoliko nije, ignorisaće se. Struktura CAN protokola omogućava upotrebu hardverskih CAN ekspandera (kao kod S-ARTnet veze). Microchip je zaključio da se veliki broj nodova sastoji jedino od odgovarajućeg U/I hardvera (U/I pinova, A/D konvertora ili PWM modulatora), pa je proizveo seriju U/I ekspandera koji se mogu direktno povezati na CAN mrežu, i čijim je hardverom moguća direktna manipulacija od strane ostalih (inteligentnijih) nodova. Za više detalja pogledajte datasheetove drajvera, komunikacionog čipa, CAN I/O ekspandera, AN215, AN228 i AN754. Razvitkom CAN mreže originalni protokol pretrpeo je izmene softvera, pa je moguće sresti verzije CAN 1.2, CAN 2.0A, CAN 2.0B i ECAN. Na sreću, novije verzije podržavaju starije (eng. backward compatibile). Za više detalja pogledajte AN916. 133

Jedan deo do sada opisanih komunikacionih protokola je hardverski integrisan u jačim serijama mikrokontrolera. To ipak ne znači da se slabiji mikrokontroleri (čitaj PIC16F84) ne mogu koristiti za određene vrste komunikacija. Uvek je moguće (u slučaju da je mikrokontroler dovoljno brz) pravovremeno direktno manipulisati ulazno izlaznim pinovima, i na taj način ostvariti softversku implementaciju hardverskih komunikacionih rutina (eng. bit-banging) kao što je ilustrovano u RS232 vezi. Taj način nekada može biti i neophodan (na primer prilikom istovremene upotrebe 3 RS232 veze jednim mikrokontrolerom). Komunikacioni protokoli ne prestaju da se razvijaju. I sami verovatno znate da se nekada mogao koristiti jedino dial-up, zatim ISDN, a onda ADSL. Brzina i dalje raste. Mikrokontroleri su u potpuno istoj situaciji.

134

57. Koju vezu odabrati? Ne postoji univerzalan odgovor na ovo pitanje. Sve zavisi od toga za šta Vam je potrebna. Dobar uporedni prikaz imate u časopisu Circuit Cellar broj 26. U sledećoj tabeli dat je uporedni pregled ovde opisanih vrsta komunikacije sa svojim specifičnostima:

drajver

Paralelna ne

RS232 MAX232

RS485 MAX485

DMX512 MAX485

I2C

SPI ne

ne

LIN da

DALI PC357NT

S-ARTnet da

CAN MCP2551

softver nije potreban implement. ne ne implement. implement. implement. ne hardverski MCP2510 max. broj zavisi od adr. 1 pred., 1 32 pred., 32 1 pred., 512 1 pred., malo zavisi od 1 master + 1 master + 64 1 master + 30 112 pred., članova magistrale prij. prij. prij. prij. kapaciteta linije 16 slave slave slave 112 prij. max. brzina ograničena 20kbita/S 100kbita/S 100kbita/S 5Mbita/S 100, 400kbita/S 20kbita/S ? ? 1Mbit/S hardverom do 3Mbita/S ili 3,2Mbita/S max daljina mala,oko 15m 1,2km 1,2km mala,oko mala,oko 20cm 40m ? ? 40m pri 0.5m 0.5m 1Mbit/S detek. gresaka ne bit parnosti zav. od soft. ne ne ne parnost +? dva bita hardverska

ne

ne

checksum zav. od soft. ?

0V, +5V

0V, +5V

0V, +18V

parnosti ne

hardverska

0V, 7.5V, 15V

-40V, +40V

korek.gresaka ne zav. od soft. max. napon 0V, +5V -25V, +25V drajvera osetljivost zavisi od +-3V, prijemnika hardvera prema masi neaktivno 0V preko +3V stanje način pren. zav.od hard. asinhroni

zav. od soft. ne -7V, +12V -7V, +12V

+-0.2V +-0.2V zavisi od zavisi od zav. od drajv. +-?V trostepena diferencijalni diferencijalni hardvera hardvera diferencijalni zavisi od preko 0,4V nema takta visoka imp. bez Preko 9V preko ?V 15V softvera razlike u + takta razlike u + razlike zav. od soft. asinhroni sinhroni sinhroni asinhroni asinhroni asinhroni

+-0,5V diferencijalni nema signala

simpl.br.prov dupl.br.prov. repetitor ul. impedansa

2 + masa 4 + masa da >=12k

2 + masa /

zav. od mag. zav. od mag. / zav.od hardv.

1 + masa 2 + masa / 3k do 7k

2 + masa / da >=12k

4 + masa / / zav.od hardv.

2 + masa / / zav.od hardv.

?

1 + masa 2 / / / / zav. od drajv. zav. od optok.

1+masa / / zav. od hardv.

asinhroni

100k

160

58. Paralelna D/A konverzija Ovde će biti prikazana dva hardverska načina realizacije paralelnog D/A konvertora. Paralelna D/A konverzija za razliku od serijske zauzima više pinova, ali daje stabilniji generisani napon i ne opterećuje mikrokontroler. Pogledajte najpre hardversku realizaciju paralelnog D/A konvertora principom binarne težinske otporne mreže (eng. binary weighted DAC). Decimalni Bitovi broj RB3 RB0

Ovde je primenjena binarna otporna mreža kod koje je otpornost povezana na pinove bita veće težine dva puta manja. Na PORTB dovoljno je dovesti željenu binarnu kombinaciju, i na izlazu će se odmah javiti stabilno analogno stanje. Zbog karakteristika ove mreže, bitovi veće težine više utiču na stanje izlaznog napona od bitova manje težine. Tako setovanje RB3 pina podiže napon za 2,51V, a RB0 za samo 0,48V. Zbog bolje linearnosti idealno bi bilo upotrebiti otpornike sa dupliranom vrednošću prethodnih. Međutim, to zbog standardnih vrednosti otpornika poskupljuje realizaciju.

Izlazni Napon

0

0000

0V

1

0001

0,48V

2

0010

0,87V

3

0011

1,21V

4

0100

1,55V

5

0101

1,79V

6

0110

1,99V

7

0111

2,17V

8

1000

2,51V

9

1001

2,63V

10

1010

2,75V

11

1011

2,85V

12

1100

2,96V

13

1101

3,05V

14

1110

3,12V

15

1111

3,20V

Kako je impedansa izlaznih pinova (pri oba logička stanja) PIC mikrokontrolera prilično niska (manja od 75Ω pri naponu napajanja od 5V) daljim širenjem otporne mreže ne bi se postigli zadovoljavajući rezultati, pre svega u pogledu linearnosti izlaznog napona. Osim toga, preciznost ovog kola u velikoj meri zavisi od tačnih vrednosti i tolerancije upotrebljenih otpornika. Po potrebi binarna težinska mreža može se napraviti sa logaritamskom a ne linearnom karakteristikom izlaznog signala. To može biti od koristi kod povećanja dinamičkog opsega govora u sistemima za digitalizaciju zvuka, jer po Laplacianovoj distribuciji oblast oko napona bliskog 0 nosi više informacija od oblasti sa većim amplitudama. Za više detalja ovakve težinske mreže pogledajte http://www.ke4nyv.com/index2.htm. U situacijama kada je neophodna veća rezolucija D/A konvertora može se koristiti D/ A konvertor sa R-2R otpornim nizom (eng. R-2R ladder DAC). 136

Kod ove šeme, umesto dupliranja vrednosti otpornosti koriste se otpornici istih vrednosti. Korišćenjem integrisanog otpornog niza, kolo sa ovakvom šemom može čak imati manje dimenzije. Rezolucija ovog kola je osmobitna. To znači da se ovim kolom može (za razliku od prethodnog) dobiti čak 255 stabilnih analognih stanja. U tablici možete videti neke tipične vrednosti izlaznog napona u zavisnosti od postavljenog binarnog stanja na PORTB. Decimalni broj

RB7

RB0

Izlazni napon

0

00000000

0V

27

00011011

0,5V

53

00110101

1V

79

01001111

1,5V

105

01101001

2V

157

10011101

3V

209

11010001

4V

235

11101011

4,5V

255

11111111

5

Linearnost ovog kola je skoro idealna, a zavisi jedino od tolerancije upotrebljenih otpornika. Za kompletnu tablicu izlaznih napona i detalje pogledajte AN655 sa http:// www.microchip.com/.

Za generisanje složenijih talasnih oblika izlaznih napona, najpraktičnije je uzimati bajtove za POTRB iz tabele. Tako se mogu sa lakoćom realizovati testerasti, trouglasti, sinusoidni oblici napona, pa čak i DTMF tonovi. Ukoliko mikrokontroler treba izvršavati i druge operacije za vreme generisanja signala, možete jednostavnije funkcije realizovati i softverski. Na primer, u interapt rutini možete neprekidno povećavati stanje PORTB registra. Tako dobijate testerasti signal. Naizmeničnim povećavanjem i smanjivanjem stanja PORTB registra dobijate testerasti signal. I sinusni signal možete dobiti korišćenjem matematičkih funkcija.

137

59. Serijska D/A konverzija Serijska D/A konverzija koristi drugačiji princip. Kod nje se kondenzator na izlazu naizmenično puni i prazni tačno određenim odnosom, održavajući tako napon na njemu u željenim granicama. Postupak kojim se puni i prazni kondenzator naziva se modulacijom širine impulsa (eng. PWM – Pulse Width Modulation). Iako je hardverski realizovana u nekim savremenijim PIC mikrokontrolerima, u PIC16F84 može se implementirati softverski. Ova tehnika često se koristi za uključenja i isključenja prekidačkog tranistora određeno vreme. Na primer ukoliko je napon +12V a tranzistor provodi 25, 50 ili 75% vremena, efektivni napon biće 3, 6 i 9V. Minimum napona postojaće kada je na pinu neprekidno prisutna logička 0, maksimum kada je neprekidno prisutna logička 1, a polovina kada se na 50% periode naizmenično menja logičko stanje pina. Ovaj način D/A konverzije uglavnom se upotrebljava za regulaciju brzine motora jednosmerne struje. Nije pogodan za primene u kojima je potrebna veća stabilnost izlaznog signala zbog generisanja smetnji i harmonika.

Nastavak sledi

Pored ovih, postoji još mnogo, mnogo principa po kojima se može implementovati D/ A konverzija. Pogledajte http://en.wikipedia.org/wiki/Analog-to-digital_converter za više detalja. Za PIC16F84 od značaja bi mogao biti interesantan način modulacije tona sa download sekcije sajta www.elektronika.ba (picsound). Gornja granična frekvencija koju možete dobiti bilo kojim od prikazanih načinina D/ A konverzije zavisi isključivo od brzine oscilatora mikrokontrolera. Svakako da je možete povećati manjim brojem različitih semplova koje koristite za generisanje željenog talasnog oblika, ali u tom slučaju gubite na preciznosti generisanog signala. Sve zavisi od toga kakav signal želite generisati. Na primer četvorobitna rezolucija D/ A konvertora sasvim je dovoljna za generisanje prilično čistog sinusoidnog signala, ali je za generisanje DTMF tonova neophodna bar osmobitna rezolucija. Ukoliko se mikrokontrolerom generišu sinusoidalni naponi stalne frekvencije, poželjno je na izlazu D/A konvertora staviti analogni filter, propusnik željenog opsega frekvencije. Posebno je to poželjno kod serijskih D/A konvertora zbog harmonika i smetnji koje oni generišu.

138

60. Flash A/D konvertor Verovatno Vam je već poznato da PIC16F84 nema u sebi integrisan A/D konvertor za razliku od nekih savremenijih mikrokontrolera. Međutim, uz jednostavan interfejs sa njim je moguće meriti odgovarajuće vrednosti napona. U narednim poglavljima biće prikazano par principa A/D konverzije. Da biste shvatili rad raznih vrsta A/D konvertora morate se najpre upoznati sa principom rada naponskog komparatora. Naponski komparator nalazi se integrisan u savremenijim verzijama PIC mikrokontrolera. Međutim, iako ga PIC16F84 nema, može mu se dodati spolja. 4 naponska komparatora u sebi sadrži popularno analogno integrisano kolo LM339. Sa jednim kolom moguće je detektovati 5 decimalnih stanja, a sa dva 9 stanja. Kako je LM339 potpuno analogno kolo, da biste na njegovom izlazu dobili naponske nivoe logičke 0 i logičke 1, morate ga napajati istim naponom napajanja kao i PIC (+5V). Šta u stvari radi naponski komparator? On poredi (eng. Compare) napone svoja dva ulaza, i ukoliko je jedan veći od drugog, menja stanje svog izlaza. Na primer, ukoliko se na jedan njegov ulaz dovede se referentni napon od 3V, a na drugom ulazu se napon polako povećava od 0 do 5V, izlaz komparatora biće u stanju logičke 0 sve dok napon na drugom ulazu ne pređe zadatih 3V. Najteže će se naponski komparator snaći ukoliko se pogodi da je napon na oba ulaza potpuno isti (3V). Ka kom će izlazu (logička 0 ili logička 1) tada biti naklonjen uglavnom zavisi od stanja izlaza neposredno pre jednakih napona. Jedini predstavnik potpuno paralelnog A/D konvertora je Flash A/D convertor. On je realizovan pomoću više naponskih komparatora. Na jedan ulaz svih komparatora doveden je mereni napon, a na drugi su dovedeni referentni naponski nivoi koji se redom smanjuju od najvećeg do najmanjeg. Pri tom smanjivanju može se (menjanjem vrednosti otpornika) koristiti logaritamski ili linearni odnos napona. Glavna prednost Flash konvertora je kako mu ime kaže (eng. munja) njegova brzina. Kako on nije vezan za takt mikrokontrolera, kompletnu A/D konverziju može obaviti trenutno. Međutim, ima on svoje mane. Broj upotrebljenih naponskih komparatora direktno određuje broj stanja izlaza. Ako želite flash A/D konvertorom realizovati četvorobitnu konverziju, biće Vam potrebno 16 ulaza (i 16 ulaznih pinova mikrokontrolera). Za osmobitnu konverziju potrebno je 255 ulaza. Pinovi RB4 do RB7 upotrebljeni su jer se njima može izazvati interapt pri promeni ulaznog napona. Iako je problem velikog broja ulaznih pinova moguće prevazići upotrebom određenih digitalnih konvertora u binarni format, ovoliki broj naponskih komparatora nije baš najjeftiniji. Zato se ovaj tip A/D konvertora retko koristi. 139

61. Brojački A/D konvertor Ovaj tip A/D konvertora u stranoj literaturi (eng.) se još sreće sreće pod nazivima Counting ili Digital ramp. Zamolite svog prijatelja da zamisli broj između 0 i 1000. Zamislio je. Krenite redom sa pitanjima: Da li je to broj 0? Nije. Da li je to broj 1? Nije. Da li je to broj 2? Nije. ... Verovatno će mu dosaditi mnogo pre nego što se uopšte približite zamišljenom broju. Njemu će dosaditi. Mikrokontroleru neće. Ovaj A/D konvertor specifičan je po tome što mu je za rad potreban D/A konvertor. Taj D/ A konvertor u šemi je realizovan R/2R otpornim nizom. Izlaz D/A konvertora vodi se na jedan ulaz eksternog naponskog komparatora, a na drugi ulaz dovodi se mereni napon. Izlazni napon D/A konvertora se povećava korak po korak (od 0V do 5V). U trenutku kada naponski komparator promeni stanje, očita se trenutno stanje na izlaznim pinovima D/A konvertora. To stanje odgovara merenom analognom naponu. Sasmim tim preciznost A/D konvertora u najvećoj meri zavisi od preciznosti D/A konvertora. Verovatno i sami uviđate manu ovog principa. Ukoliko je mereni napon blizu svoje maksimalne vrednosti, mikrokontroler mora D/A konvertorom povećavati napon od 0V pa sve do merenog napona. To može potrajati. Da bi se vreme merenja što više skratilo, primenjuje se princip opisan u narednom poglavlju. Glavna rutina programa sa ovakvim principom izgledala bi ovako: Pet incf SPORTB,F ; Povećaj Shaddow registar. movf SPORTB,W ; Prebaci u W, movwf PORTB ; pa u PORTB – tako povećaj izlazni napon. btfsc PORTA,RA0 ; Jesu li se ovi naponi sada izjednačili? goto Pet ; Nisu, povećavaj i dalje. ... ; Jesu, W sadrži vrednost A/D konverzije. 140

62. Sukcesivno aproksimativni A/D konvertor Da bih Vam ilustrovao princip rada ove A/D konverzije obrazložiću Vam princip algoritma binarne pretrage unutar sortiranog niza podataka. Opet zamolite svog prijatelja da zamisli broj između 0 i 1000. Zamislio je. Sada ga pitajte je li njegov broj veći od [0+((1000-0)/2) = 500] 500. Nije. Znači njegov broj je između 0 i 500. Da li je veći od [0+((500-0)/2) = 250] 250? Nije. Znači broj je između 0 i 250. Da li je veći od [0+((250-0)/2) = 125] 125? Nije. Broj je između 0 i 125. Da li je veći od [0+((125-0)/2) = 62,5] 63? Jeste. Broj je između 63 i 125. Da li je veći od [63+((125-63)/2) = 94] 94? Jeste. Broj je između 94 i 125.

Da li je veći od [94+((125-94)/2) = 109,5] 110? Jeste. Broj je između 110 i 125. Da li je veći od [110+((125-110)/2) = 117,5] 118? Nije. Broj je između 110 i 118. Da li je veći od [110+((118-110)/2) = 114] 114? Nije. Broj je između 110 i 114. Da li je veći od [110+((114-110)/2) = 112] 112? Jeste. Broj je između 112 i 114. Da li je veći od [112+((114-112)/2) = 113] 113? Jeste. Onda je to broj 114. Ovaj princip možete zamisliti kao sečenje pice. Iseče se na pola, zatim na četvrtine, pa na osmine, i tako sve do najmanjeg parčeta. Vidite da ste za razliku od prethodnog slučaja sa samo 10 pitanja uspeli da dođete do tačnog rezultata. E sada. Ukoliko ovaj princip primenite umesto (kao u brojačkom A/ D konvertoru) postepenog povećanja napona korak po korak, vreme utrošeno na merenje biće mnogo, mnogo kraće, uz potpuno istu električnu šemu. Program je prilično jednostavan. Najpre se setuje bit najveće težine (MSB - RB7) na PORTB registru. U zavisnosti od stanja naponskog komparatora, ovaj pin ostavi se setovan ili se resetuje. Onda se prelazi na RB6, RB5, RB4... clrf PORTB ; Inicijalizuj PORTB bsf PORTB,7 ; Setuj MSB btfss PORTA,0 ; Ukoliko je napon preveliki, bcf PORTB,7 ; resetuj ga. bsf PORTB,6 ; Setuj naredni btfss PORTA,0 ; Ukoliko je napon preveliki, bcf PORTB,6 ; resetuj ga. bsf PORTB,5 ; Setuj naredni ... I tako sve do RB0 pina. Na kraju će PORTB sadržati izmerenu vrednost napona. Kod je dat ilustrativno, a u pravim programima bi se koristio i Shaddow registar. 141

63. Wilkinsonov A/D konvertor Ranije šeme zbog upotrebe D/A konvertora zauzimaju previše dragocenih pinova mikrokontrolera. Osim toga, one zahtevaju upotrebu naponskog komparatora za svoj rad. Očigledno je da se PIC16F84 takav kakav je ne snalazi najbolje sa merenjem i poređenjem napona. Sa njegove strane mnogo je zgodnije mereni napon konvertovati u neku drugu fizičku veličinu. Na primer u vreme. Taj princip primenjen je u sledećim šemama. One Vam mogu poslužiti za merenje otpornosti, temperature (upotrebom NTC ili PTC otpornika), intenziteta svetlosti (upotrebom fotootpornika) ili kapacitivnosti (upotrebom kapacitivnih senzora). Kako radi ovaj interfejs? Najpre drži RB0 na logičkoj 1 dovoljno dugo da bi se kondenzator napunio. Ovo vreme je 5*R*C, odnosno za maksimalnu vrednost testiranog otpornika od 10kΩ oko 5mS. Čim se kondenzator u potpunosti napuni, naizmenično se vrši postavljanje pina na logičku 0 (pražnjenje kondenzatora), konfigurisanje pina kao ulaz i testiranje da li se kondenzator dovoljno ispraznio (prazan je kada na pinu mikrokontrolera javi logicka 0). Broj ciklusa pražnjenja / testiranja ili proteklo vreme direktno određuje vrednost merene otpornosti. Prekid programa interaptima za vreme merenja dovešće do nepreciznog očitavanja vrednosti. Zato se oni moraju isključiti dok se merenje ne završi. Ukoliko Vam je potrebno brže merenje, možete umesto naizmeničnog menjanja stanja pina (ulaz/izlaz) možete koristiti neku od sledećih šema: Ovo kolo najpre drži RB0 na logičkoj 0 dovoljno dugo da se kondenzator isprazni, odnosno da mu oba pola budu na potencijalu od 0V. Zatim se pin RB0 postavlja u stanje ulaza, i meri se vreme za koje će se na pinu javiti logička jedinica. Kako se kondenzator sada puni preko otpornika, ovo vreme direktno će zavisiti od trenutne vrednosti otpornosti. Prednost ove šeme nad prethodnom je mogućnost pojave interapta po promeni stanja na RB0/INT pinu, što rasterećuje mikrokontroler za ostale potrebe. Sa ovim kolom se uglavnom dobijaju najbolji rezultati. RB0 se postavi na logičku 1, kondenzator se napuni, a zatim se meri vreme koje je potrebno da se na pinu javi logička 0. I sa ovom šemom moguće je po završenom merenju otići na interapt rutinu. Možda Vam čudno deluje taj skok na interapt rutinu. Kako će onda program meriti vreme? Jednostavno. Još jednim interaptom izazvanim tajmerom. Ove tehnike mogu se primeniti za bilo koju vrednost otpornika i kondenzatora. Međutim, ukoliko se koristi kondenzator kapacitivnosti veće od 100nF između 142

kondenzatora i pina potrebno je postaviti zaštitni otpornik od oko 220Ω. On sprečava preveliku struju na pinu mikrokontrolera u trenutku naglog punjenja ili pražnjenja kondenzatora. Microchip čak navodi da se usled prevelike struje na pinovima portova može promeniti stanje TRISA ili TRISB registra, pa ga je stoga poželjno povremeno softverski „osvežiti”. Donja granica kapacitivnosti kondenzatora zavisi jedino od brzine vašeg mikrokontrolera. Pri kristalu od 4MHz sasvim je moguće koristiti vrednosti od 33pF. Što manji kondenzator upotrebljavate, merenje će biti kraće. Kako vreme za koje se kondenzator napunio ili isprzanio nema direktne veze sa celzijusovim stepenima ili svetlosnim luksom, vrednosti ovih veličina najjednostavnije je dobiti iz odgovarajuce tabele. Bilo koja izobličenja pri merenju (poput nelinearne karakteristike upotrebljenog senzora) mogu se odmah kompenzovati u samoj tabeli. Još jedna mogućnost gornjih šema ogleda se u mogućnošću merenja kapacitivnosti umesto otpornosti. Na taj način može se na primer izmeriti položaj osovine promenljivog kondenzatora. Naravno, u tom slučaju umesto promenljivog, u šemu je potrebno postaviti običan otpornik što manjeg stepena tolerancije. Ove šeme zbog svoje jednostavnosti imaju jedan veliki nedostatak. Sa njima nije moguće dobiti veću preciznost zbog promene radnih karakteristika upotrebljenog kondenzatora usled promene radne temperature. Zbog toga se može koristiti kompenzacija ovih nedostataka koristeći kalibracioni otpornik i merenjem njegove vrednosti neposredno pre merenja otpornosti senzora. Za detalje pogledajte AN512, AN513 i AN863 sa http://www.microchip.com/. Možda smatrate da ovo nije prava A/D konverzija zbog ograničenja na merenje otpornosti i kapacitivnosti, a ne napona! U pravu ste. Međutim, uz male izmene električne šeme moguće je realizovati pravu desetobitnu A/D konverziju. Za princip rada i detalje pogledajte http://www.ele.uva.es/~jesus/adsd.pdf. Ovakav princip merenja u literaturi se naziva još i Single Slope A/D konvertor.

143

64. Konverzija otpornosti i kapacitivnosti u frekvenciju Raniji principi A/D konverzije bili su pogodni za merenje raznih fizičkih veličina jedino u slučaju da senzori nisu previše udaljeni od mikrokontrolera. Ukoliko biste želeli da merite npr. temperaturu na terasi, morali bi razvući bar oko 5m provodnika. Ti provodnici otpornosti senzora dodaju svoju otpornost koja zavisi od njihovog poprečnog preseka i dužine. Osim toga usled svojih fizičkih veličina uvode povećanje mogućnosti pogrešnog merenja. Na primer usled sopstvene zavisnosti otpornosti od temperature (ponašaju se kao mini senzor temperature), usled povećanja kapacitivnosti na vodovima (provodnici su uglavnom bliski jedan drugom, pa se ponašaju kao kondenzator) ili usled indukovanih električnih smetnji (što duži kablovi, to bolja antena). U industriji se upravo iz tih razloga udaljeni senzori umesto sa promenljivim naponom prave sa promenljivom strujom (4-20mA). PIC16F84 je prilično mali potrošač električne energije. Nema svrhe napraviti kolo za merenje spoljne temperature, ubaciti mu čak i SLEEP mod, a onda mu dodati senzor čija je prosečna potrošnja 12mA. Nije li upravo to rasipništvo u efikasnom iskorišćenju datih nam resursa dovelo do opšteg povećanja zagađenja planete Zemlje! Kao što ste ranije videli PIC16F84 se ne snalazi najbolje sa direktnim merenjem napona. Šta najlakše radi? Meri vreme i broji. U ovoj šemi upotrebljeno je popularno integrisano kolo NE555 povezano kao astabilni multivibrator. Tako povezano, ono će u zavisnosti od kapacitivnosti elektrolitskog kondenzatora od 1μF i otpornosti merenog otpornika od 10kΩ u mikrokontroler slati impulse, tačno određenom frekvencijom. Što je otpornost promenljivog otpornika manja, ova frekvencija će biti veća. Algoritam programa trebao bi u fiksnom vremenskom intervalu (npr. 0,5S – što duži interval to veća preciznost) brojati impulse. Kako je za eliminaciju smetnji poželjno koristiti ulaz sa šmitovim okidačem, impulse je najpraktičnije dovesti na RA4 (ukoliko se ne koriste interapti za brojanje) ili RB0 (ukoliko se koriste interapti za brojanje) pin. RB0 pin se ponaša kao ulaz sa šmitovim okidačem jedino kada je podešen za interapte. Ukoliko je daljina od mikrokontrolera do NE555 previše velika, možete povećati napon napajanja NE555. Za još veće daljine može se kombinovati NE555 sa RS485 drajverom. U stvari kako je ovde potreban jedino predajnik, deo integrisanog invertora signala (7406) biće dovoljan. Ukoliko umesto promenljivog otpornika postavite stalan otpornik malog stepena tolerancije dobijate odličan merač kapacitivnosti upotrebljenog kondenzatora. Detalje o ovom principu imate na http://www.globu.net/pp/english/PP/ne555.htm. Tu se nalaze podaci o frekvencijama u zavisnosti od kapacitivnosti i otpornosti. 144

65. Konverzija napona u frekvenciju Konvertor napona u frekvenciju (eng. VCO - Voltage Controlled Oscilator – naponski kontrolisani oscilator) u frekvenciju pretvara mereni napon.

Nastavak sledi!

145

66. Integrisani A/D konvertori Pretpostavimo da Vam je potreban A/D konvertor koji bi brzo merio željeni napon, ne zahtevajući pri tome intervenciju mikrokontrolera (npr. prilikom snimanja i kompresije zvuka). U tom slučaju najpraktičnije je koristiti integrisane A/D konvertore žrtvujući određen broj pinova za očitavanje podataka iz njih. Tipični predstavnici integrisanih A/D konvertora su ADC0831, LTC1298, MAX 190 ili MAX 191. Ponekad je potrebno meriti veliki dinamički opseg napona. Većina integrisanih A/D konvertora sposobna je meriti jedino napone od 0 do +5V. MAX134 je specijalno namenjen za ugradnju u mernim instrumentima, pa se njegov opseg merenja može menjati u širokim granicama, omogućavajući na taj način merenje napona u opsezima od 0 do 399,9mV rezolucijom od 0,1mV, pa sve do 0 do 399,9V rezolucijom od 0,1V.

146

67. Kompenzacija nelinearnih karakteristika Senzori koje upotrebljavate pri merenju obično nemaju linearnu karakteristiku. Na primer NTC otpornik će pri 10oC imati otpornost od 1kΩ, pri 20oC 2kΩ, pri 30oC 4kΩ i pri 40oC 8kΩ. Očigledno je da on umesto linearne ima logaritamsku karakteristiku. Iako se matematičkim formulama (npr. Steinhart-Hart ili metodom linearizacije kao u AN942) može ispraviti njegov opseg, često razni drugi faktori utiču na pogoršanje linearnosti. Te faktore izaziva princip A/D konverzije, promena temperature oscilatora, kablova do senzora ili upotrebljenog VCO konvertora. Da bi se dobila što tačnija merenja potrebno je na odgovarajući način kompenzovati nelinearna izobličenja kako upotrebljenog senzora tako i svih ostalih činilaca. Jedan od načina kompenzacije nelinearnosti je crtanje grafika izmerenih vrednosti. Na X osi postavlja se redni broj merenja koji će na odgovarajući način biti prikazan mikrokontrolerom (npr. 0 do 50 rezolucijom od 1oC ili 0 do 100 rezolucijom od ½oC za temperaturni opseg od 0oC do 50oC), a na Y osi vrednost fizičke veličine izmerene mikrokontrolerom i kalibrisane instrumentom veće klase preciznosti. Dalje je potrebno softverski svakoj vrednosti sa X ose pridružiti (najčešće preko tabele) odgovarajuću vrednost sa Y ose. Očigledno je da je radi bolje preciznosti grafika neophodno da merenja budu što preciznija, i sa što više mernih tačaka. Kako bi smanjili broj potrebnih merenja, dipl. ing. Lazar Pančić i dipl. ing. Bojan Mitić su Vam pripremili program za interpolaciju merenih vrednosti. On na osnovu par zadatih tačaka računa vrednosti preostalog broja potrebnih tačaka. Izlazni .txt fajl programa možete editovati prema svojim potrebama i iskopirati ga u sopstveni program. Pri tome niste ograničeni samo na upotrebu PIC mikrokontrolera.

Program je ispitan pod Win98 i Win2000, a dostupna je i njegova Linux verzija. Besplatan je (dat je čak i izvorni kod) i nalazi se na mom sajtu čiji link možete naći na kraju ovog uputstva. 147

68. Datalodger Datalodger predstavlja uređaj koji snima semplovane podatke (obično u eksterni EEPROM) i iz koga je potrebno povremeno spolja iščitavati podatke. U ranijim primerima videli ste kako se može meriti nivo reke. U međuvremenu ste naučili i upotrebu A/D konvertora, I2C i RS232 komunikacionog protokola. Sada i nije teško zamisliti meteorološku stanicu sa anemometrom (meračem brzine vetra), hidrometrom (meraćem vlažnosti vazduha), termometrom i meračem smera vetra. U slučaju da se sve ove veličine dobijaju u analognom obliku, dovoljno je dovesti ih u A/D konvertor i nakon toga u PIC. Semplovi svih konvertovanih napona povremeno se snimaju u eksternu EEPROM memoriju preko I2C veze, a ona se periodično prazni preko RS232 veze u kompjuter. Kompjuter bi onda mogao analizirati dobijene podatke i predvideti na primer pojavu suše ili kiše. Uz više istovremeno povezanih sistema (više udaljenih merača) mogla bi se sa priličnom tačnošću predvideti mikroklima određenih područja.

148

69. Kontrola temperature Ništa lakše. Dovoljno je povezati senzor na A/D kontroler, i zadati mikrokontroleru graničnu vrednost rezultata A/D konverzije. Ukoliko na primer senzor kao rezultat A/ D konverzije broj manji od .175 uključiće se relej grejača, a za broj .175 (ili veći) koji odgovara temperaturi od 25oC isključiće se relej. Ilustracija ovoga mogla bi ovako izgledati: movlw subwf btfss goto goto

.175 AD,W STATUS,C Ukljuci Iskljuci

; Zadata vrednost temperature ; W = AD - .175 ; Testiraj prekoračenje ; AD < .175 ; AD >= .175

Da li je ovo dobar način kontrole? Nije! Svi senzori podložni su smetnjama. Šta može izazvati te smetnje? Za početak, tu je sam mikrokontroler. Njegov takt oscilatora proizvešće malo smanjenje i povećanje napona napajanja. Dalje, tu su uređaji koji se kontrolišu mikrokontrolerom. Pri multipleksu LED displeja najviše struje trošiće displej na kome se prikazuje broj 8 (tada su sve pojedinačne LED uključene), a najmanje onaj sa brojem 1 (uključena samo dve LED). Ne mora to obavezno biti LED displej. Isti efekat prouzrokovaće i relej grejača. Sledeća je vaša komšinica sa svojim (made in China) usisivačem. Iako će dekapling kondenzator u dobroj meri eliminisati ove smetnje, jedan deo će se svakako preneti i do senzora, i tu će proizveti šum. Upravo je taj šum poguban za uspešnu kontrolu temperature. Sa njim će pri istoj temperaturi rezultat A/D konverzije jednom biti 170, a drugi put 180, što će mikrokontroler shvatiti kao odgovarajuću promenu temperature, i brzo će uključivati i isključivati relej. Kontakti običnih releja jednostavno nisu namenjeni za takav rad, i relej će posle par nedelja stradati. Šta je rešenje? Reći mikrokontroleru da promeni stanje jedino ukoliko se izmerena temperatura dovoljno (npr. za .10) udaljila od zadate vrednosti (.175), slično kao što to šmitov okidač radi hardverski. Znači, da uključi grejač ukoliko je očitana vrednost 165 i manja, i da ga isključi ukoliko je očitana vrednost 185 i veća. Ovde je najbolje radi što manjeg variranja temperature podesiti granične vrednostzi, tako da se postigne kompromis između češćeg rada releja i spoljnih smetnji. Da li je sada sve u redu? I dalje ne mora da bude. Ukoliko je senzor temperature postavljen u blizini grejača, umesto merenja temperature prostorije, meriće se temperatura grejača. Tako će pri uključenju grejača rezultat A/D konverzije veoma brzo postati .255, odnosno, i dalje će se relej previše brzo uključivati i isključivati. Ovo se može rešiti udaljavanjem senzora na mesto gde neće direktno osećati temperaturu grejača. Ovo bi moglo biti dovoljno dobro rešenje za ON/OFF (uključi/isključi) kontrolu grejača (relejom). Međutim, nekada ON/OFF kontrola jednostavno nije dovoljna. U 149

tim situacijama koristi se kontinualna regulacija snage, faznim pomakom triaka (slično kao PWM za jednosmerni napon). Uzmimo za primer da želite u dvorištu napraviti inkubator za jaja. Ovde je radi što manjih oscilacija temperature poželjno koristiti kontinualnu regulaciju. Međutim, šta sa situacijom kada napolju počne da pada kiša (odjednom zahladni)? Uz dovoljno dobro toplotno izolovan inkubator, neće biti nikakvih problema. Ali nekada jednostavno nemamo dovoljno stiropora (i opet je sneg iznenadio naše putare). U ovom slučaju potrebno je mikrokontroleru dodati još malo logike. Osim temperature potpuno isti principi primenjuju se za kontrolu bilo koje fizičke veličine. Više o ovim kontrolnim procesima imate u časopisima Circuit Cellar br. 17 i 19.

150

70. Rotacioni enkoder Verovatno Vam je poznata uloga potenciometra u analognoj elektronici. On menja svoju otpornost u zavinosti od položaja osovine, pomeranjem kontakta klizača preko otporne površine. Na taj način realizovano je na primer pojačanje zvuka na kasetofonu. Analogni potenciometri imaju par mana. Kao prvo njihovi kontakti nisu večni. Oni su kao i kontakti mehaničkih prekidača podložni varničenju (eng. Bouncing). Otuda krčanje pri pojačavanju i smanjenju zvuka. Još gore, ukoliko upotrebite A/D konvertor da prevedete stanje analognog potenciometra u digitalni oblik, moguće je da kontakti potenciometra baš u trenutku merenja usled lošeg spoja budu odvojeni od otporne površine, što će prouzrokovati očitavanje maksimalne otpornosti. Sledeća mana analognog potenciometra odnosi se na položaj njegove osovine pri graničnim vrednostima. Koliko puta ste morali menjati gumicu na slavini jer je neko previše zavrnuo? Isto je i sa analognim potenciometrom. Ne možete očekivati od korisnika da će biti „nežan“ prema svojim uređajima. Bolje stavite manju kapicu na osovini. Neće se moći previše jako pritisnuti. Postoji više vrsta rotacionih enkodera. Po načinu konstrukcije mogu biti mehanički, optički i magnetski. Mehanički imaju najviše nedostataka zbog varničenja svojih kontakata i manje rezolucije. Po obliku signala koji se može dobiti na izlazu digitalnih potenciometra postoje enkoderi sa apsolutnim adresiranjem koji na svom izlazu direktno daju binarni kod (4bitni, 6-bitni, 8-bitni), ili koji koriste malo drugačiji format brojanja (tzv. sivi eng. Grey code) i enkoderi sa relativnim adresiranjem. U daljem opisu biće opisana jedino upotreba rotacionih enkodera sa relativnim adresiranjem (eng. relative rotary encoder, incremental rotary encoder ili quadrature encoder). Za detaljniji opis posetite http://en.wikipedia.org/wiki/Rotary_encoder. Relativni rotacioni enkoder treba sprovesti odgovarajuće obrtno kretanje osovine u mikrokontroler. Međutim, za razliku od apsolutnog enkodera PIC ne mora znati kolika je njegova trenutna vrednost u svakom trenutku. Čemu to. Ionako će je inicijalizovati po uključenju (npr. čitanjem iz EEPROM-a). Dovoljno je dati mu podatak u kom smeru se okreće osovina enkodera (kao kod običnih taster prekidača – levo-desno), a mikrokontroler će to stanje softverski uporediti sa prethodnim i na osnovu rezultata izvršiti predviđenu operaciju. Ovo uvodi značajnu prednost rotacionih enkodera u tome što kod njih nema graničnih položaja. Drugim rečima, možete okretati njihovu osovinu koliko god želite, kao kod Nautilus slavina. Signal dobijen sa relativnog rotacionog enkodera u jednom trenutku može imati stanja prikazana u sledećoj tabeli: --> Rotacija u smeru kazaljke na satu --> 00

01

11

10

00

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF