Entdecken Sie eBooks
Kategorien
Entdecken Sie Hörbücher
Kategorien
Entdecken Sie Zeitschriften
Kategorien
Entdecken Sie Dokumente
Kategorien
Elektrotehnicki fakultet
Odsjek za automatiku i elektroniku
SADRZAJ
1
1
1.2
1.3
Arhitektura mikrokontrolera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.4
1.5
Organizacija memorije . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.5.1
FLASHROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.5.2
RAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.6
1.7
11
2.1
O modulima . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
2.2
11
2.2.1
12
2.2.2
13
2.2.3
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
2.2.4
17
2.3
19
2.4
24
2.5
30
2.6
31
2.7
36
2.8
. . . . . . . . . . . . . . .
39
2.9
42
46
48
iii
3 Prekidi
51
3.1
51
3.2
52
3.3
53
3.4
Visestruki prekidi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
55
4 Serijska komunikacija
59
4.1
59
4.2
61
4.3
63
65
69
75
77
87
iv
POGLAVLJE
1.1
su mikrokontroleri?
Sta
Nagli razvoj i eksploatacija mnogih tehnickih oblasti poput elektronike i racunarske tehnike omogucili
su proizvodnju jeftinih integriranih kola performansi nekadasnjih racunara. U takva kola spadaju
i mikrokontroleri1 , uredaji koji se od racunara opce namjene razlikuju po tome sto posjeduju dodatne elektronske module koji ih cine pogodnim za primjenu u tzv. ugradbenim sistemima (eng.
Embedded System). Ugradbeni sistemi predstavljaju racunarske sisteme namijenjene da izvrsavaju
specifican zadatak za koji su dizajnirani i gotovo svi danasnji elektronski uredaji, poput audio i
video uredaja, raznih modula u automobilima, modema, ves masina, raznih industrijskih regulatora
i drugih, predstavljaju ugradbene sisteme.
Jedan vrlo interesantan aspekt pri dizajnu ugradbenog sistema je cinjenica da pored softverskog
dizajna ukljucuje i hardverski dizajn, koji zna biti vrlo kompliciran iz razloga sto, pored elektronskih komponenti, sadrzi razne elektricne i mehanicke komponente koje su potrebne za ispravan
rad uredaja. Otezavajucu cinjenicu u softverskom dizajnu ugradbenog sistema moze predstavljati
i ogranicenje da on mora raditi u realnom vremenom (eng. Real-Time Computing), sto je zahtjev
kod vecine takvih sistema.
Klasifikaciju mikrokontrolera moguce je napraviti prema raznim kriterijima. Jedna od najosnovnih klasifikacija mikrokontrolera jeste prema proizvodacima, a najzastupljeniji proizvodaci
mikrokontrolera (u 2008. godini) su Intel, Renesas, Freescale, Microchip, ARM, NEC, ST Microeletronics, Atmel i Infineon, respektivno.
Druga klasifikacija bi bila po duzini memorijskih registara nad cijim sadrzajima se odvijaju
racunarske operacije. Najcesce se susrecu 8-bitni mikrokontroleri (sa otprilike 55% zastupljenosti
na trzistu u 2008. godini), ali takoder postoje 16-bitni i 32-bitni mikrokontroleri.
Postoje cak mikrokontroleri koji sadrze mnogo mikroprocesorskih jedinica sto ih cini pogodnim
za razvoj aplikacija koje moraju raditi u realnom vremenu, a isto nije moguce postici na jednom
mikroprocesoru.
U sklopu ovog rada ce se analizirati mikrokontroler PIC16F877A (proizvodaca Microchip) koji
predstavlja 8-bitni mikrokontroler iz vrlo zastupljene 16F serije. PIC predstavlja engleski akronim
za termin programabilni interfejs kontroler (eng. Programmable Interface Controller ), koji vrlo
1
Koji se cesto nazivaju MCU, engleski akronim za termin mikrokontrolerska jedinica (eng. MicroController
Unit).
1.2
PIC16F877A
20 MHz
POR i BOR
8192
368
256
15
A, B, C, D i E
3
2
MSSP i USART
PSP
8 kanala
2
35
40-pinski PDIP
44-pinski PLCC
44-pinski TQFP
44-pinski QFN
1.3
Arhitektura mikrokontrolera
1
fosc
(1.3.1)
a period izvrsavanja instrukcija (koje nisu instrukcije grananja) Ti je sa periodom oscilatora Tosc
4
vezan relacijom
PIC16F87XA
T = 4T .
i
(1.3.2)
osc
FIGURE 1-1:
Program
Bus
PORTA
RA0/AN0
RA1/AN1
RA2/AN2/VREF-/CVREF
RA3/AN3/VREF+
RA4/T0CKI/C1OUT
RA5/AN4/SS/C2OUT
RAM
File
Registers
8 Level Stack
(13-bit)
14
Data Bus
Program Counter
RAM Addr(1)
Addr MUX
Instruction reg
Direct Addr
Indirect
Addr
PORTB
RB0/INT
RB1
RB2
RB3/PGM
RB4
RB5
RB6/PGC
RB7/PGD
FSR reg
Status reg
8
3
Power-up
Timer
Instruction
Decode &
Control
Oscillator
Start-up Timer
Timing
Generation
Watchdog
Timer
Brown-out
Reset
In-Circuit
Debugger
OSC1/CLKI
OSC2/CLKO
Power-on
Reset
MUX
ALU
8
PORTC
RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
RC2/CCP1
RC3/SCK/SCL
RC4/SDI/SDA
RC5/SDO
RC6/TX/CK
RC7/RX/DT
W reg
Low-Voltage
Programming
MCLR
VDD, VSS
Timer0
Timer1
Timer2
10-bit A/D
Data EEPROM
CCP1,2
Synchronous
Serial Port
USART
Device
Slika
Comparator
Voltage
Reference
PIC16F873A
4K words
192 Bytes
128 Bytes
PIC16F876A
8K words
368 Bytes
256 Bytes
1.4
PIC16F8
Raspored pinova na ku
ci
stu
Pin Diagrams
Na sljedecoj slici je prikazan
raspored(Continued)
pinova mikrokontrolera PIC16F877A u 40-pinskoj PDIP
izvedbi.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
40
39
38
37
36
35
34
33
32
31
30
29
28
27
26
25
24
23
22
21
RB7/PGD
RB6/PGC
RB5
RB4
RB3/PGM
RB2
RB1
RB0/INT
VDD
VSS
RD7/PSP7
RD6/PSP6
RD5/PSP5
RD4/PSP4
RC7/RX/DT
RC6/TX/CK
RC5/SDO
RC4/SDI/SDA
RD3/PSP3
RD2/PSP2
RA3/AN3/VREF+
RA2/AN2/VREF-/CVREF
RA1/AN1
RA0/AN0
MCLR/VPP
NC
RB7/PGD
RB6/PGC
RB5
RB4
NC
MCLR/VPP
RA0/AN0
RA1/AN1
RA2/AN2/VREF-/CVREF
RA3/AN3/VREF+
RA4/T0CKI/C1OUT
RA5/AN4/SS/C2OUT
RE0/RD/AN5
RE1/WR/AN6
RE2/CS/AN7
VDD
VSS
OSC1/CLKI
OSC2/CLKO
RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
RC2/CCP1
RC3/SCK/SCL
RD0/PSP0
RD1/PSP1
PIC16F874A/877A
40-Pin PDIP
RA4/T0CKI/C1OUT
6
5
4
3
2
1
44
43
42
41
40
13
OSC1/CLKI
14 se mo
Osnovni pin je Vpp preko kojeg se vrsi programiranje. ResetovanjeOSC2/CLKO
mikrokontrolera
ze
15
RC0/T1OSO/T1CK1
vrsiti spajanjem Vpp na masu.
16
NC
18
19
20
21
22
23
24
25
26
27
282
17
Svi pinovi digitalnih ulaza i izlaza imaju prefiks R u imenu. Tako, primjera radi, RA4 predstavlja 4. bit porta A.
RC6/TX/CK
RC5/SDO
RC4/SDI/SDA
RD3/PSP3
RD2/PSP2
RD1/PSP1
RD0/PSP0
RC3/SCK/SCL
RC2/CCP1
RC1/T1OSI/CCP2
NC
39
38
37
36
35
34
33
32
31
30
9
RC1/T1OSI/CCP2
RC2/CCP1
RC3/SCK/SCL
RD0/PSP0
RD1/PSP1
RD2/PSP2
RD3/PSP3
RC4/SDI/SDA
RC5/SDO
RC6/TX/CK
NC
Svi kanali modula za analogno - digitalnu konverziju imaju prefiks AN u imenu. Tako, primjera
radi, AN2 predstavlja 2. kanal modula za analogno - digitalnu konverziju. Drugi vazni pinovi za
analogno - digitalni modul su Vref+ i Vref- preko kojih se podesava ulazni opseg modula.
44-Pin TQFP
Pinovi CLKIN i CLKOUT
se respektivno koriste kao ulaz i izlaz za frekventni oscilator.
44
43
42
41
40
39
38
37
36
35
34
1.5
RD6/PSP6
RD7/PSP7
VSS
VDD
RB0/INT
RB1
RB2
mikrokontroler
RB3/PGM
30
4
29
5
PIC16F874A
28
6
PIC16F877A
27
7
26
8
9
25
24
10
PIC16F877A
ima programsku
23
11
Organizacija memorije
OSC1/CLKI
VSS
VDD
RE2/CS/AN7
RE1/WR/AN6
RE0/RD/AN5
RA5/AN4/SS/C2OUT
(FLASHROM),
RA4/T0CKI/C1OUT podatkovnu
FLASHROM
NC
NC
RB4
RB5
RB6/PGC
RB7/PGD
MCLR/VPP
RA0/AN0
RA1/AN1
RA2/AN2/VREF-/CVREF
RA3/AN3/VREF+
1.5.1
12
13
14
15
16
17
18
19
20
21
22
DS39
at 0004h.
FIGURE 2-1:
FIGURE 2-2:
PIC16F873A/8
PIC16F876A/877A
PROGRAM ME
PROGRAM
MEMORY
MAP
Arhitektura i hardver mikrokontrolera PIC16F877A
AND STACK
AND STACK
PC<12:0>
PC<12:0>
Stack Level 1
Stack Level 1
Stack Level 2
Stack Level 2
Stack Level 8
Stack Level 8
Reset Vector
0000h
Interrupt Vector
0004h
Reset Vector
Interrupt Vector
0005h
Page 0
07FFh
0800h
On-Chip
Program
Memory
13
CALL, RETURN
RETFIE, RETLW
13
CALL, RETURN
RETFIE, RETLW
Page 0
On-Chip
Program
Memory
Page 1
Page 1
0FFFh
1000h
Page 2
17FFh
Page 3
1800h
1FFFh
1.5.2
RAM
DS
PIC16F87XA
banci.
FIGURE 2-3:
Indirect addr.(*)
TMR0
PCL
STATUS
FSR
PORTA
PORTB
PORTC
PORTD(1)
PORTE(1)
PCLATH
INTCON
PIR1
PIR2
TMR1L
TMR1H
T1CON
TMR2
T2CON
SSPBUF
SSPCON
CCPR1L
CCPR1H
CCP1CON
RCSTA
TXREG
RCREG
CCPR2L
CCPR2H
CCP2CON
ADRESH
ADCON0
00h
01h
02h
03h
04h
05h
06h
07h
08h
09h
0Ah
0Bh
0Ch
0Dh
0Eh
0Fh
10h
11h
12h
13h
14h
15h
16h
17h
18h
19h
1Ah
1Bh
1Ch
1Dh
1Eh
1Fh
20h
File
Address
Indirect addr.(*)
OPTION_REG
PCL
STATUS
FSR
TRISA
TRISB
TRISC
TRISD(1)
TRISE(1)
PCLATH
INTCON
PIE1
PIE2
PCON
SSPCON2
PR2
SSPADD
SSPSTAT
TXSTA
SPBRG
CMCON
CVRCON
ADRESL
ADCON1
*
Note 1:
2:
TMR0
PCL
STATUS
FSR
PORTB
PCLATH
INTCON
EEDATA
EEADR
EEDATH
EEADRH
General
Purpose
Register
16 Bytes
accesses
70h-7Fh
Bank 1
100h
101h
102h
103h
104h
105h
106h
107h
108h
109h
10Ah
10Bh
10Ch
10Dh
10Eh
10Fh
110h
111h
112h
113h
114h
115h
116h
117h
118h
119h
11Ah
11Bh
11Ch
11Dh
11Eh
11Fh
120h
Indirect addr.(*)
OPTION_REG
PCL
STATUS
FSR
FFh
accesses
70h-7Fh
Bank 2
PCLATH
INTCON
EECON1
EECON2
Reserved(2)
Reserved(2)
General
Purpose
Register
16 Bytes
1A0h
80 Bytes
80 Bytes
EFh
F0h
TRISB
180h
181h
182h
183h
184h
185h
186h
187h
188h
189h
18Ah
18Bh
18Ch
18Dh
18Eh
18Fh
190h
191h
192h
193h
194h
195h
196h
197h
198h
199h
19Ah
19Bh
19Ch
19Dh
19Eh
19Fh
General
Purpose
Register
General
Purpose
Register
80 Bytes
96 Bytes
7Fh
Indirect addr.(*)
A0h
General
Purpose
Register
General
Purpose
Register
Bank 0
80h
81h
82h
83h
84h
85h
86h
87h
88h
89h
8Ah
8Bh
8Ch
8Dh
8Eh
8Fh
90h
91h
92h
93h
94h
95h
96h
97h
98h
99h
9Ah
9Bh
9Ch
9Dh
9Eh
9Fh
File
Address
File
Address
16Fh
170h
17Fh
accesses
70h - 7Fh
Bank 3
1EFh
1F0h
1FFh
DS39582B-page 17
Odabir banke vrsimo upotrebom bitova RP0 i RP1 iz STATUS registra prema sljedecoj tabeli.
RP1
0
0
1
1
RP0
0
1
0
1
Memorijska banka
0
1
2
3
1.6
Za ispravan rad bilo kojeg mikrokontrolera potrebna je osnovna periferna elektronika kao sto su
napajanje i frekventni oscilator. Na slici 1.6.1 je prikazana shema sa minimalnom elektronikom
potrebnom za ispravan rad mikrokontrolera PIC16F877A.
IN
OUT
GND
2 7805
10uF
100nF
10K
11
Vdd
RC0/T1OSO/T1CKI
15
32
Vdd
RC1/T1OSI/CCP2
16
RC2/CCP1
17
100uF
MCU
PIC16F877A
RESET
MCLR/VPP
RA0/AN0
RC3/SCK/SCL
18
RA1/AN1
RC4/SDI/SDA
23
RA2/AN2/Vref/CVref
RC5/SDO
24
RA/AN3/Vref+
RC6/TX/CK
25
RA4/TOCKI/C1OUT
RC7/RX/DT
26
RA5/AN4/SS/C2OUT
RD0/PSP0
19
13
OSC1/CLKIN
RD1/PSP1
20
14
OSC2/CLKOUT
RD2/PSP2
21
33
RB0/INT
RD3/PSP3
22
34
RB1
RD4/PSP4
27
35
RB2
RD5/PSP5
28
36
RB3/PGM
RD6/PSP6
29
37
RB4
RD7/PSP7
30
38
RB5
RE2/CS/AN7
10
39
RB6/PGC
RE1/WR/AN6
40
RB7/PGD
Vss
12
RE0/RD/AN5
Vss
31
8MHz
33pF
33pF
Kod spajanja frekventnog oscilatora vrlo je bitno postaviti kondenzatore koji omugucavaju
ispravan rad oscilatora. U suprotnom se nece izvrsavati program koji je ucitan u programsku
memoriju mikrokontrolera.
Pored potrebne elektronike za napajanje i frekventnog oscilator na istoj shemi je spojen taster
koji omogucava resetovanje mikrokontrolera. Naime, rad mikrokontroler je omogucen ako je pin
Vpp spojeno na 5V, a u slucaju da se on spaja na masu desi se resetovanje mikrokontrolera.
Otpornik je spojen na taster iz razloga da se pritiskom na isti ne desi spajanje izlaza iz regulatora
napona 7805 na masu sto bi izazvalo njegovo ostecenje.
1.7
Na slici 1.6.1 je prikazana shema koja je potrebna da bi mikrokontroler mogao izvrsavati program
koji je snimljen u njegovoj programskoj memorij. Medutim, za programiranje mikrokontrolera
potreban je poseban elektronski interfejs koji je prikazan na slici 1.7.1. Na slici vidimo da se
programiranje mikrokontrolera vrsi preko cesto susretanog konektora DB9 koji se spaja na serijski
port racunara. Pored ovakvog hardverskog programatora potreban je jos i softverski programator,
9
koji ce komunikacijom preko serijskog porta poslati isprogramirani kod na mikrokontroler. Detaljno
uputstvo za upotrebu uobicajenih softverskih programatora dato je u prilogu ovog rada.
DB9
10K
PIC16F877A
V
1
OUT
GND
2 7805
10uF
100nF
2
8MHz
33pF
11
Vdd
RC0/T1OSO/T1CKI
15
32
Vdd
RC1/T1OSI/CCP2
16
RC2/CCP1
17
4K7
100uF
IN
4K7
MCU
33pF
MCLR/VPP
RA0/AN0
RC3/SCK/SCL
18
RA1/AN1
RC4/SDI/SDA
23
RA2/AN2/Vref/CVref
RC5/SDO
24
RA/AN3/Vref+
RC6/TX/CK
25
RA4/TOCKI/C1OUT
RC7/RX/DT
26
RA5/AN4/SS/C2OUT
RD0/PSP0
19
13
OSC1/CLKIN
RD1/PSP1
20
14
OSC2/CLKOUT
RD2/PSP2
21
33
RB0/INT
RD3/PSP3
22
34
RB1
RD4/PSP4
27
35
RB2
RD5/PSP5
28
36
RB3/PGM
RD6/PSP6
29
37
RB4
RD7/PSP7
30
38
RB5
RE2/CS/AN7
10
39
RB6/PGC
RE1/WR/AN6
40
RB7/PGD
Vss
12
RE0/RD/AN5
Vss
31
TITLE
FILE:
10
PAGE
OF
POGLAVLJE
2
OSNOVNI MODULI MIKROKONTROLERA PIC16F877A
2.1
O modulima
Mikrokontroleri, kao sto je vec ranije receno, se od racunara opce namjene, izmedu ostalog, razlikuju po tome sto posjeduju dodatne elektronske module za razne namjene. Moduli mogu biti
interfejsni, sto znaci da mogu predstavljati digitalni, analogni ili komunikacijski interfejs prema ostaloj elektronici, a mogu imati i druge namjene poput memorijskih i pomocnih modula za precizno
tajmiranje koda i signala.
U sklopu ovog poglavlja obradit ce se rad sa sljedecim osnovnim modulima:
moduli za rad sa digitalnim ulazima i izlazima,
moduli za tajmeriranja,
modul za analogno - digitalnu konverziju,
modul za sirinsku - impulsnu modulaciju,
EEPROM modul.
2.2
Prije no sto se pristupi realizaciji bilo kakvog projekta na mikrokontroleru, potrebno je nauciti
programski jezik u kojem se on moze programirati. Preporucjivo je prvo nauciti asemblerski jezik
mikrokontrolera1 , jer se kroz njega veoma dobro moze nauciti i arhitektura samog mikrokontrolera.
Termini asemblerski jezik i asembler nisu sinonimi. Asemblerski jezik predstavlja niz pravila (specifikacija jezika) prema kojim pisemo programe za konkretne mikrokontrolere, dok asembler predstavlja aplikaciju koja prevodi napisani asemblerski kod u masinski jezik (datoteka koju
posaljemo na mikrokontroler).
Svaka asemblerska naredba ima svoj konkretni ekvivalent u radu hardverskih jedinica unutar
mikrokontrolera, tako da je preduslov za pisanje programa u asemblerskom jeziku dobro poznavanje
samog hardvera, sto je nas primarni cilj.
1
Svaki proizvodac ima svoj asemblerski za svoje porodice mikrokontrolera pa je najpogodnije koristiti mikrokontrolere jednog proizvodaca.
2.2.1
Na samom nivou asemblerskog jezika ne postoji nesto sto bi se moglo nazvati formalnim mehanizmom deklaracije, ali postoji metoda koji simulira takvo ponasanje. Posmatrajmo sljedeci iskaz
koji ilustrira deklaraciju varijable u programskom jeziku C.
int x = 5 ;
Ovim iskazom se zauzme memorijski prostor velicine int tipa podataka u memoriji, u njega
upisuje vrijednost 5 dok x postaje sinomim za isti. Za razliku od programskog jezika C, asemblerski
jezik ne poznaje tipove podataka nego iskljucivo 8-bitnu vrijednost koja se jednoznacno tumaci.
Pored toga, u asemblerskom jeziku nije moguce automatski generirati adrese memorijskog prostora
koji se koristi kao varijabla, vec ga je potrebno eksplicitno navesti. Sljedeci fragment koda pokazuje
deklaraciju varijabli u asemblerskom jeziku.
x equ 0 x21
y equ 0 x06
z equ 0 x11
12
Ovi iskazi uvode respektivno sinonime x, y i z za memorijske lokacije 21h, 06h i 11h u programskoj memoriji. Medutim, ranije je receno da ove adrese nisu jednoznacne vec da zavise od toga koja
je memorijska banka trenutno odabrana. Posmatrajuci sliku 1.5.2.1 vidimo da je x sinonim za 4
registra opce namjene, y sinonim za PORTB i TRISB registre, a z sinonim za 2 registra opce namjene kao i TMR2 i SSPCON2 registre. Iz ovog primjera vidimo da upotreba direktive equ, cije ime
inace potjece od engleskog termina za rijec poistovijeti (eng. Equate), nosi ivicni efekat koji je vrlo
opasan. Ta opasnost se ogleda u cinjenici da slucajno pogresno odabranom memorijskom bankom
podatke mozemo upisati u pogresnu memorijsku lokaciju, a da stvari budu jos gore tom greskom
mozemo promijeniti sadrzaj nekog specijalnog funkcijskog registra i neposredno time nepozeljno
promijeniti nacin rada nekih od modula mikrokontrolera. Radi toga se programeru preporucuje da
obraca mnogo paznje na odabrane memorijske banke, jer u suprotnom mogu nastati greske koje
cak mogu dovesti do ostecenja nekih modula mikrokontrolera.
2.2.2
Tokom programiranja cesto se javlja potreba promjene sadrzaja neke varijable. Najjednostavniji
primjer takve situacije prikazan je sljedecim fragmentom koda u programskom jeziku C gdje je u
varijabli x upisana konstanta 23.
x = 23 ;
Ako se isto zeli uraditi u asemblerskom jeziku, izvedba je moguca na jedan od sljedeca tri
nacina.
; Dekadni u p i s
movlw 23
movwf x
; Heksadecimalni upis
movlw 0 x17
movwf x
; Binarni upis
movlw B 00010111
movwf x
Takoder je cesto potrebno izvrsiti kopiranje sadrzaja jedne u drugu varijablu, sto je u programskom jeziku C prikazano sljedecim fragmentom koda u kojem se varijabli y dodjeluje vrijednost
13
varijable x.
y = x;
Ono sto se moze primijetiti u prethodnom fragmentu je da se instrukcija movf koristi drugacije
od instrukcija movlw i movwf. Instrukcija movf pored argumenta nad kojim izvrsava instrukciju
posjeduje jos jedan argument koji se odnosi na to gdje se smijesta rezultat operacije. Naime, ako
je taj argument w onda se rezultat smijesta u W registar, a ako je taj argument f onda se rezultat
smijesta u registar nad kojim se izvrsava instrukcija. U ovom konkretnom primjeru na instrukciji
movf nema smisla koristiti argument f, ali postoje instrukcije kod kojih je to veoma korisno.
Dosadasnje instrukcije su mijenjale sadrzaj registra kao cjeline, ali isto tako postoje instrukcije
koje mijenjaju sadrzaj jednog bita nekog registra. Takve instrukcije kao argument, pored registra
nad kojim se treba obaviti ta operacija, imaju i argument koji oznacava nad kojim se bitom obavlja
operacija. Upotreba instrukcija bsf i bcf je prikazana sljedecim fragmentom koda.
; P o s t a v l j a 0 . b i t v a r i j a b l e x na 1
bsf x , 0
; P o s t a v l j a 5 . b i t v a r i j a b l e x na 0
bcf x ,5
2.2.3
Nemoguce je zamisliti kod koji nema uslovne iskaze pa je prirodno ocekivati da asemblerski jezik
ima takve instrukcije. Koristenje uslovnih iskaza u asemblerskom jeziku nije toliko jednostavno i
direktno kao u programskom jeziku C i zahtijeva izvrsenje nekih numerickih manipulacija. Posmatrajmo sljedeci fragment koda koji pokazuje tri moguce varijante uslovnih iskaza.
// V a r i j a b l a x j e d n a k a 27
i f ( x == 2 7 ) {
// K o r i s n i kod
}
// V a r i j a b l a x veca od 27
i f ( x > 27) {
// K o r i s n i kod
}
// V a r i j a b l a x manja od 27
i f ( x < 27) {
// K o r i s n i kod
}
14
; U p i s i v a n j e v r i j e d n o s t i 27 u W
movlw 27
; W x , rezultat u W
subwf x , w
; T e s t i r a n j e z b i t a , ako j e 1 onda j e x j e d n a k o 27 i s k a c e na l a b e l u k o r i s n i K o d 1
b t f s c STATUS, z
goto korisniKod1
; P o s t a v l j a n j e c b i t a STATURS r e g i s t r a na 0
b c f STATUS, c
; U p i s i v a n j e 229 u W
movlw 229
; W + x , rezultat u W
addwf x , w
; T e s t i r a n j e c b i t a , ako j e 1 onda j e x > 27 i s k a c e s e na l a b e l u k o r i s n i K o d 2
b t f s c STATUS, c
goto korisniKod2
; P o s t a v l j a n j e c b i t a STATURS r e g i s t r a na 0
b c f STATUS, c
; U p i s i v a n j e 229 u W
movlw 229
; W + x , rezultat u W
addwf x , w
; T e s t i r a n j e c b i t a , ako j e 0 onda j e x < 27 i s k a c e s e na l a b e l u k o r i s n i K o d 3
b t f s s STATUS, c
goto korisniKod2
korisniKod1
; K o r i s n i kod
korisniKod2
; K o r i s n i kod
korisniKod3
; K o r i s n i kod
Na prvi pogled je uocljivo koliko i najjednostavniji kod u programskom jeziku C postaje velik
u asemblerskom jeziku. U svim iskazima je koristen STATUS registar koji je veoma koristan pri
upravljanju tokom programa. Bit z STATUS registra se koristi pri provjeri da li je neka aritmeticka
ili logicka operacija jednaka nuli. Ova osobina je iskoristena na nacin da se formira iskaz 27 x
i ako je on jednak nuli, onda se z bit postavlja na logicku jedinicu. Medutim, samo formiranje
ovog iskaza zahtijeva mnostvo instrukcija. Prvo se bit z postavlja na logicku nulu, jer je moguce
15
da je prethodno upisana logicka jedinica. Zatim se u radni registar W kopira 27 nakon cega
se instrukcijom subwf od radnog registra W oduzima vrijednost varijable x. Bit z se postavlja
na logicku jedinicu u slucaju da je x jednak 27. Na kraju se instrukcijom btfsc zapravo ispituje
uslov. Instrukcija btfsc provjerava bit nekog registra; ako je on jednak logickoj jedinici onda se
izvrsava sljedeca instrukcija, a u slucaju da je on jednak logickoj nuli preskace se izvrsavanje
sljedece instrukcije. U ovom slucaju, ako je z jednak logickoj jedinici izvrsi se skakanje na labelu
korisniKod1 koja obraduje taj uslov.
Za drugi i treci uslov koristen je bit c STATUS registra koji se postavlja na logicku jedinicu
ako je rezultat neke aritmeticke operacije veci od 255, sto predstavlja prenos u sabiranju. Ova
osobina je iskoristena na nacin da se formira iskaz 229 + x i u slucaju da je x veci ili jednak 27
rezultat ovog sabiranja ce biti veci od 255 i posljedicno ce se c bit postaviti na logicku jedinicu; u
suprotnom ce ostati na logickoj nuli. Za testiranje uslova x > 27 koristena je instrukcija btfsc koja
ce preskociti narednu instrukciju u slucaju da je c jednak logickoj nuli, a u slucaju da je jednak
logickoj jedinici skace se na labelu korisniKod2. Za testiranje uslova x < 27 koristena je instrukcija
btfss koja predstavlja dualnu instrukciju instrukcije btfsc. Naime, ako je c bit na logickoj jedinici
onda se preskace izvrsavanje sljedece instrukcije, a u slucaju da je jednak logickoj nuli izvrsava se
sljedece instrukcija i skace se na labelu korisniKod3.
Pored tri osnovna uslovna iskaza postoje i dva izvedena koja su prikazana sljedecim fragmentom
koda u programskom jeziku C.
// V a r i j a b l a x veca od 26
i f ( x >= 2 7 ) {
// K o r i s n i kod
}
// V a r i j a b l a x manja od 28
i f ( x <= 2 7 ) {
// K o r i s n i kod
}
Umjesto direktnog svodenja ovih iskaza u asemblerski kod pogodnije je indirektno svodenje na
nacin da se prethodni fragment koda u programskom jeziku C svodi na sljedeci fragment koda u
programskom jeziku C.
// V a r i j a b l a x veca od 26
i f ( x > 26) {
// K o r i s n i kod
}
// V a r i j a b l a x manja od 28
i f ( x < 28) {
// K o r i s n i kod
}
Prethodni fragment je napisan primjenom cinjenica da su iskazi x >= 27 i x > 26, kao i iskazi
x <= 27 i x < 28 medusobno ekvivalentni u cjelobrojnoj aritmetici. Svodenje ovakvog fragmenta
koda iz programskog jezika C u asemblerski jezik pokazano je na prethodnim primjerima .
Pored uslovnih koraka u programiranju, cesto postoji potreba za petljama kao sto su petlje
prikazane sljedecim fragmentom koda u programskom jeziku C.
while ( x > 10) {
// K o r i s n i kod
}
16
f o r ( i = 0 ; i < 2 0 ; i ++) {
// K o r i s n i kod
}
Prethodne petlje se mogu transformirati u asemblerski jezik kao sto je prikazano sljedecim
fragmentom koda.
; Upisivanje v ri j ed n o st i 0 u varijablu x
movlw 0
movwf x
petlja1
; K o r i s n i kod
; Uvecanje x
incf x, f
; P o s t a v l j a n j e c b i t a STATUS r e g i s t r a na 0
b c f STATUS, C
; W x , rezultat u W
movlw 10
subwf x , w
; T e s t i r a n j e c b i t a ako j e 0 s k a c e s e na l a b e l u p e t l j a 1 , a ako j e 1 onda s e
; preskace goto i n s t r u k c i j a
b t f s s STATUS, c
goto p e t l j a
; U p i s i v a n j e v r i j e d n o s t i 20 u v a r i j a b l u i
movlw 20
movwf i
petlja2
; K o r i s n i kod
; Umanji v r i j e d n o s t i v a r i j a b l e i za j e d a n 1 ako j e i j e d n a k o 0 p r e s k a c e s e
; g o t o i n s t r u k c i j a ( u suprotnom s e s k a c e na l a b e l u p e t l j a 2 )
decfsz i , f
goto p e t l j a 2
Transformacija while petlje bi trebala biti ocita. Jedina nova instrukcija je incf koja je
iskoristena za uvecanje varijable x. Iz koda se vidi da je mnogo laksa transformacija for petlje
u odnosu na while petlju jer je koristena decfsz instrukcija. Ova instrukcija prvo umanji vrijednost
nekog registra za jedan, a zatim provjerava da li je njegova vrijednost jednaka nuli. U slucaju
da je jednaka nuli preskace se izvrsavanje sljedece instrukciju; u suprotnom se izvrsava sljedeca
instrukcija.
2.2.4
Dobar dizajn koda podrazumijeva da se svaki zaseban dio koda enkapsulira u posebnu funkciju koja
se zatim po potrebi poziva u glavnoj funkciji. Ovakav pristup dizajnu se preporucuje iz razloga sto
17
kod tada postaje pregledan, sto ujedno olaksava promjene u istom. Posmatrajmo sljedeci fragment
koda napisan u programskom jeziku C.
void f u n k c i j a 1 ( ) {
// K o r i s n i kod
}
int f u n k c i j a 2 ( ) {
return 2 ;
}
int main ( ) {
funkcija1 () ;
int x = f u n k c i j a 2 ( ) ;
return 0 ;
}
U njemu je prikazan program kod kojeg se iz glavne funkcije pozivaju funkcije funkcija1 i
funkcija2. Funkcija funkcija1 predstavlja funkciju koja ne prima argumente i nema povratnu
vrijednost, dok funkcija funkcija2 predstavlja funkciju koja vraca konstantnu vrijednost. Ovakve
funkcije je moguce simulirati u asemblerskom jeziku kao sto je prikazano u sljedecem fragmentu
koda.
main
; Poziv f u n k c i j e f u n k c i j a 1
call funkcija1
; Poziv f u n k c i j e f u n k c i j a 2
call funkcija2
movlw 2
movwf temp
; Dodjela povratne v r i j e d n o s t i f u n k c i j e funkcija2
funkcija1
; K o r i s n i kod
; Povratak i z f u n k c i j e f u n k c i j a 1
return
funkcija2
; P o v r a t a k i z f u n k c i j e f u n k c i j a 2 sa 2 u W
retlw 2
Nije moguce formirati funkciju koja prima argumente, vec je argument potrebno prenositi preko
globalnih varijabli u kodu (sto su, igrom slucaja, sve varijable u asemblerskom jeziku radi samog
nacina simuliranja deklaracije varijabli).
18
2.3
Na mikrokontroleru PIC16F877A je moguce koristiti 33 pina kao digitalni ulaz ili digitalni izlaz.
Uobicajeno je da se govori o skupinama digitalnih ulaza ili izlaza koji se nazivaju portovima.
Mikrokontroler PIC16F877A posjeduje 5 portova: PORTA, PORTB, PORTC, PORTD i PORTE.
PORTA je sestobitan, PORTB, PORTC i PORTD su osmobitni, a PORTE je trobitan.
Sljedeci fragment koda demonstrira upotrebu digitalnog izlaza.
; Odabir banke 1
bsf STATUS, RP0
b c f STATUS, RP1
; U p i s i v a n j e 0 u TRISB
movlw 0 x00
movwf TRISB
; Odabir banke 0
b c f STATUS, RP0
; I s p i s i v a n j e 33 na PORTB
movlw 0 x11
movwf PORTB
Iz listinga se vidi da smo prvo odabrali banku 1 preko bitova RP0 i RP1 STATUS registra,
zatim upisali vrijednost 0 u TRISB registar pa smo se vratili u memorijsku banku 0 i upisali
vrijednost 33 u PORTB registar. Ovim smo generirali logicku jedinicu na pinovima RB0 i RB0
PORTB. Ova logicka jedinica se moze mjeriti instrumentom i iznosi 5V, jer su izlazi mikrokontrolera
PIC16F877A u TTL (eng. Transistor transistor logic) izvedbi, sto znaci da su nivoi za logicku
jedinicu i logicku nulu 5V i 0V, respektivno.
Funkcija pinova na portovima se podesava tzv. TRIS 2 registrima. Svaki port posjeduje svoj
TRIS registar. Tako se npr. putem TRISA registra podesavaju funkcije pinova na portu A. Svaki
TRIS registar ima isti broj bita kao njemu pripadajuci port. Postavljanje svakog bita nekog TRIS
registra na nulu proglasava svaki pin njemu pripadajuceg porta kao izlazni, a ako se svaki bit nekog
TRIS registra postavlja na jedan, onda se svaki pin njemu pridajuceg porta proglasava ulaznim.
Tako se prethodnim fragmentom koda svaki bit PORTB postavio kao digitalni izlaz a zatim se u
isti zapisala odredena vrijednost.
Sljedecim fragmentom koda se vrijednost digitalnog ulaza prepisuje sa PORTD u radni registar.
; Odabir banke 1
bsf STATUS, RP0
b c f STATUS, RP1
; U p i s i v a n j e 255 u TRISD
movlw 0xFF
movwf TRISD
; Odabir banke 0
b c f STATUS, RP0
; P r e p i s i v a n j e PORTD u W
movf PORTD, w
2
Skracenica TRIS inace stoji za tristate, sto su zapravo sklopovi koji na svom izlazu mogu zauzeti tri razlicita
stanja.
19
Ovaj kod je interesantan jer ce se sadrzaj radnog registra W promijeniti samo ako se fizicki
mijenja naponska vrijednost na pinovima PORTD.
Moguce je cak neke pinove porta proglasiti digitalnim ulazom, a neke digitalnim izlazom, kao
sto je prikazano sljedecim fragmentom koda.
; Odabir banke 1
bsf STATUS, RP0
b c f STATUS, RP1
; Pola p i n o v a PORTD cu u l a z i , a o s t a l i p o l a su i z l a z i
movlw B 01010101
movwf TRISD
T RISD6
1
T RISD5
0
T RISD4
1
T RISD3
0
T RISD2
1
T RISD1
0
T RISD0
1
RD7
izlaz
RD6
ulaz
RD5
izlaz
RD4
ulaz
RD3
izlaz
RD2
ulaz
RD1
izlaz
RD0
ulaz
Potrebno je strogo izbjegavati dovodenje napona na pinove koji su deklarirani kao izlazni, jer
ce u tom slucaju doci do unistenje tog pina.
Postavka primjera 2.3.1: Potrebno je napisati program koji ce citati vrijednosti digitalnih
ulaza porta D te ispisati te vrijednosti na pinovima porta B. Ispis vrsiti na nacin da tezinska
pozicija bitova na PORTB odgovara tezinskim pozicijama bitova na PORTD. Tako npr. na RB0
treba ispisati vrijednosti RD0 3
Rje
senje primjera 2.3.1: Shema spajanja nije potrebna, jer u samom primjeru nije potrebno
spajati periferni hardver na razvojno okruzenje.
Listing 2.3.1: Rje
senje postavljenog primjera
list
#include
p=16f877A
; Lista d i r e k t i v a koja d efinira procesor
<p 1 6 f 8 7 7 A . i n c > ; D e f i n i c i j a v a r i j a b l i v e z a n i h za p r o c e s o r
; CONFIG s e k o r i s t i da s e u k l j u c e p o d a c i o h a r d v e r u na kojem
; ce s e p o s t a v i t i hex
CONFIG CP OFF & WDT OFF & BODEN OFF & PWRTE OFF & HS OSC
& WRT OFF & LVP OFF & CPD OFF
;
org
0 x000
; Procesor r e s e t v e k t o r
nop
goto
main
; nop p o t r e b a n z b o g In C i r c u i t Debuggera
; I d i na g l a v n i program
main
; Odabir banke 1
3
Ovakvi kodovi su inace vrlo korisni, jer se preko njih veoma brzo moze testirati ispravnost hardvera koji se
koristi. Takoder je vrlo zgodno koristiti PORTB kao port za ispis, jer su na njemu spojene LED.
20
Prethodni kod je prepravljen iz templatea koji dolazi u sklopu MPLAB razvojnog okruzenja, a
razlika u odnosu template je da su izbaceni nepotrebni dijelovi i da je podesana konfiguracijska rijec
(koja cuva podatke o hardveru, poput vrste oscilatora i drugih). Ukljucivanjem mikrokontrolera se
krene izvrsavati instrukcija adrese 000h iz programske memorije (lokacije tzv. reset vektora). Prva
linija koda koja se izvrsava je nop (eng. No operation) koja doslovno ne radi nista, a vecinom se
upotrebljava za neka precizna vremenska uskladivanja. U ovom slucaju je postavljena iz razloga
da podrzava tzv. ICD (eng. In Circuit Debugger ).
Kod se krene izvrsavati skokom na labelu main gdje se prvo bira memorijska banka 1 a zatim se
PORTD postavi kao digitalni ulaz, a PORTB kao digitalni izlaz. Zatim se bira memorijska banka
0 i u petlji se vrsi kopiranje sadrzaja PORTD u PORTB.
Postavka primjera 2.3.2: Potrebno je realizirati sistem na bazi mikrokontrolera PIC16F877A
koji ima taster spojen na RD0, a LED spojen na RD1. Pritiskom na taster se LED, u slucaju da
je bila iskljucena, ukljuci i obratno.
Rje
senje primjera 2.3.2: Shema spajanja je prikazana na slici 2.3.1. Sa slike vidimo da je
jedan kraj tastera spojen na masu, dok je drugi kraj spojen na RD0 preko predotpora Rp na 5V.
Zakljucujemo da taster radi u negativnoj logici, sto znaci da ce se promjena stanja desiti svaki
put kada se taster spaja na masu, odnosno kada se logicka nula dovede na RD0. Predotpor Rp
je stavljen iz razloga da se ogranici ulazna struja u digitalni ulaz. Maksimalna struja koja smije
ulaziti u pin digitalnog ulaza iznosi 20mA pa cemo vrijednost predotpora Rp odrediti prema relaciji
5
< 20mA Rp > 250,
Rp
(2.3.1)
(2.3.2)
list
#include
p=16f877A
; Lista d i r e k t i v a koja d efinira procesor
<p 1 6 f 8 7 7 A . i n c > ; D e f i n i c i j a v a r i j a b l i v e z a n i h za p r o c e s o r
; CONFIG s e k o r i s t i da s e u k l j u c e p o d a c i o h a r d v e r u na kojem
; ce s e p o s t a v i t i hex
CONFIG CP OFF & WDT OFF & BODEN OFF & PWRTE OFF & HS OSC
& WRT OFF & LVP OFF & CPD OFF
;
org
0 x000
; Procesor r e s e t v e k t o r
nop
goto
main
; nop p o t r e b a n z b o g In C i r c u i t Debuggera
; I d i na g l a v n i program
promjenaStanja
; Ako j e RD1 j e d n a k 1 i d e na l a b e l u promijeniNaNulu
b t f s c PORTD, 1
g o t o promijeniNaNulu
; Ako j e RD1 j e d n a k 0 i d e na l a b e l u promijeniNaJedan
b t f s s PORTD, 1
22
g o t o promijeniNaJedan
krajPromjenaStanja
return
promijeniNaNulu
; P r o m i j e n i RD1 na 0 i v r a c a s e na k r a j f u n k c i j e p r o m j e n a S t a n j a
b c f PORTD, 1
goto krajPromjenaStanja
promijeniNaJedan
; P r o m i j e n i RD1 na 1 i v r a c a s e na k r a j f u n k c i j e p r o m j e n a S t a n j a
bsf PORTD, 1
goto krajPromjenaStanja
main
; Odabir banke 1
bsf STATUS, RP0
b c f STATUS, RP1
; P o s t a v l j a n j e RD0 kao u l a z n i p i n
bsf TRISD , 0
; P o s t a v l j a n j e RD1 kao u l a z n i p i n
b c f TRISD , 1
; Odabir banke 0
b c f STATUS, RP0
petlja
; P r o v j e r a v a n j e da l i j e RD0 j e d n a k 0 ,
; ako j e s t p o z i v a f u n k c i j u za promjenu s t a n j a
b t f s s PORTD, 0
c a l l promjenaStanja
goto p e t l j a
end
; Kraj g l a v n e f u n k c i j e
Iz listinga se vidi koliko je zapravo tesko kreirati visestruke uslove u asemblerskom jeziku.
Naime, u glavnoj funkciji se prvo podesavaju TRIS registri pa se zatim u jednoj petlji provjerava
da li je RD0 na logickoj nuli. U slucaju da jeste, poziva se funkcija promjenaStanja u kojoj se
provjerava koje je trenutno stanje. U slucaju da je RD1 jednak jedinici skace se na labelu promijeniNaNulu u kojoj se RD1 postavi na jedan i zatim se skace na labelu krajPromjenaStanja poslije
koje se vracamo iz funkcije promjenaStanja na mjesto poziva u glavnoj funkciji. Slicno se desava
i u slucaju da je RD1 bio jednak nuli, samo se u tom slucaju umjesto funkcije promijeniNaNulu
poziva funkcija promijeniNaJedan, a ostali tok grananja je isti.
23
2.4
Softversko generiranje ka
snjenja
Prethodni primjeri su demonstrirali upotrebu digitalnih ulaza i izlaza iz asemblerskog jezika. Zamislimo da zelimo napraviti kod koji ce izazvati blinkanje LED na RB0. Tako bismo, prema
dosadasnjem iskustvu, napisali petlju kao u sljedecem fragmentu koda.
petlja
; P o s t a v l j a n j e RB0 na 1
bsf PORTB, 0
; p o s t a v l j a n j e RB0 na 0
b c f PORTB, 0
goto p e t l j a
Nazalost, ovo nece dovesti do zeljenog efekta, bar ne prividno. Problem je u tome sto se ovo
desava toliko brzo da ljudsko oko nije u stanju pratiti promjenu na LED (pored cinjenice da je i
LED sam po sebi trom i ne moze pratiti toliko brze promjene).
Interesantan podatak je da se vrijeme izvrsavanje svakog dijela koda programa napisanog u
asemblerskom jeziku za mikrokontroler PIC16F877A moze tacno izracunati. Naime, trajanje jedne
instrukcije (osim instrukcija granana) je odredeno relacijom
Ti =
4
fosc
= 4Tosc ,
(2.4.1)
gdje je fosc frekvencija oscilatora spojenog na mikrokontrolera. Za konkretno koristeno razvojno okruzenje u sklopu vjezbi vrijedi fosc = 8M hz, sto znaci da trajanje jedne instrukcije (osim
instrukcija grananja) iznosi 0.5s. Instrukcije grananja poput goto, call, return i drugih traju
2Ti = 1s.
Prema prethodno recenom, prvim ulaskom u petlju se RB0 postavi na logicku jedinicu, sto
traje 0.5s jer je to vrijeme potrebno da se izvrsi bcf instrukcija koja ce RB0 postaviti na logicku
nulu. RB0 ce biti na logickoj nuli sve dok se ne izvrsava ponovo bsf instrukcija koja ce RB0
ponovo vratiti na logicku jedinicu. Naime, vrijeme potrebno da se RB0 ponovo postavi na logicku
jedinicu iznosi 1.5s, jer se 1s potrosi na goto a preostalih 0.5s se potrosi na bsf. Prema tome,
ako bismo osciloskopom mjerili signal na RB0 dobili bismo signal kao na sljedecoj slici.
6
RB0 [V]
4
5
Vrijeme [s]
Prethodni fragment koda se lahko da prepraviti da generira simetricnu cetvrtku sa poluperiodom od 2s kao sto je prikazano na sljedecoj slici.
6
RB0 [V]
8
10
Vrijeme [s]
12
14
16
Vidimo da se ovaj kod, u odnosu na prethodni, razlikuje za cetiri nop instrukcije. Svrha nop
instrukcija je da se potrose instrukcijski ciklusi na cekanje, jer nop instrukcija sama po sebi ne radi
nista.
Vidimo da ova metoda povecavanja cekanja sama po sebi ima smisla samo ako zelimo generirati
relativno kratka kasnjenja, dok je za, recimo, relativno veliko kasnjenje kao sto je to 100s potrebno
200 nop instrukcija. Veca kasnjenja se mogu efikasnije generirati sljedecim fragmentom koda.
; U p i s u j e 5 u b r o j a c = 1 us
movlw 5
movwf b r o j a c
petlja
decfsz brojac , f
goto p e t l j a
varijable i provjerava da li je ona jednaka nuli. U slucaju da nije jednaka nuli izvrsi se sljedeca
instrukcija, dok se u slucaju da je ona jednaka nuli preskace izvrsavanje sljedece instrukcije. Umanjivanje bez grananja (bez preskakanja sljedece instrukcije) traje jedan instrukcijski ciklus, dok kod
posljednjeg umanjivanja sa grananjem izvrsavanje instrukcije traje dva instrukcijska ciklusa. Prema
tome, smanjivanje varijable brojac sa 5 na 1 traje 4 3Ti = 6s, jer se u svakom prolasku kroz
petlju potrosi jedan instrukcijski ciklus na decfsz, a dva instrukcijska ciklusa na goto. U posljednjem prolasku se potrose dva instrukcijska ciklusa na decfsz, jer se varijabla brojac umanji na 0
i preskace se izvrsavanje sljedece goto instrukcije (cime se i zavrsi petlja). Prema tome, ukupno
kasnjenje koje se generiralo ovim fragmentom koda iznosi 2Ti +12Ti +2Ti = 16Ti = 8s. Ako bismo
u opcem slucaju inicijalizirali varijablu brojac brojem n (0 n 255), kasnjenje td prethodnog
fragmenta dato je izrazom
td = 4Ti + 3 (n 1)Ti .
(2.4.2)
(2.4.3)
Dodavanje dvije nop instrukcije usporava svaki prolaz petlje za dva dodatna instrukcijska ciklusa. Prema tome, ako bismo ponovno, u opcem slucaju, inicijalizirali varijablu brojac brojem n
(0 n 255), onda je kasnjenje td prethodnog fragmenta dato izrazom
td = 4Ti + 5 (n 1)Ti .
(2.4.4)
Kombinirajuci nop instrukcije unutar i izvan petlje moguce je podesiti proizvoljno kasnjenje
(pod pretpostavkom da ne prelazimo maksimalni broj instrukcija mikrokontrolera PIC16F877A).
Medutim, najefikasniji pristup povecavanja kasnjenja ukljucuje upotrebu visestrukih petlji kao sto
je prikazano sljedecim fragmentom koda.
; I n i c i j a l i z a c i j a brojaca
movlw 10
movwf b r o j a c a
L0
movlw 10
movwf b r o j a c b
L1
; Umanjivanje b r o j a c a
d e c f s z brojacb , f
g o t o L1
de cf sz brojaca , f
g o t o L0
26
Iz prethodnog fragmenta vidimo da smo uveli dvije brojacke varijable koje se zovu brojaca i
brojacb. Prvo se vrsi inicijalizacija obje varijable pa se zatim umanjuje varijabla brojacb u petlji
sa labelom L1 sve dok brojacb ne postaje jednak nuli. U tom slucaju se vrsi umanjivanje varijable
brojaca i izvrsava jedna iteracija petlje sa labelom L0. U petlji sa labelom L0 se vrsi ponovna
inicijalizacija varijable brojacb i ponovno se smanjuje vrijednost varijable brojacb prema petlji sa
labelom L1. Ovaj proces se nastavlja sve dok varijabla brojaca ne dostigne vrijednost nula. U tom
slucaju se zavrsava izvrsavanje koda. Tacno vrijeme izvrsavanja u opcem slcaju je tezo odrediti,
ali se isto moze priblizno odrediti uz pretpostavku da se varijable brojaca i brojacb incijaliziraju
istim brojem n u skladu sa relacijom
td 3n2 Ti ,
(2.4.5)
list
#include
p=16f877A
; Lista d i r e k t i v a koja d efinira procesor
<p 1 6 f 8 7 7 A . i n c > ; D e f i n i c i j a v a r i j a b l i v e z a n i h za p r o c e s o r
; CONFIG s e k o r i s t i da s e u k l j u c e p o d a c i o h a r d v e r u na kojem
; ce s e p o s t a v i t i hex
CONFIG CP OFF & WDT OFF & BODEN OFF & PWRTE OFF & HS OSC
& WRT OFF & LVP OFF & CPD OFF
priv
equ 0 x28
b r o j a c equ 0 x29
;
org
0 x000
; Procesor r e s e t v e k t o r
nop
goto
main
; nop p o t r e b a n z b o g In C i r c u i t Debuggera
; I d i na g l a v n i program
main
bsf STATUS, RP0
27
list
#include
p=16f877A
; Lista d i r e k t i v a koja d efinira procesor
<p 1 6 f 8 7 7 A . i n c > ; D e f i n i c i j a v a r i j a b l i v e z a n i h za p r o c e s o r
; CONFIG s e k o r i s t i da s e u k l j u c e p o d a c i o h a r d v e r u na kojem
; ce s e p o s t a v i t i hex
CONFIG CP OFF & WDT OFF & BODEN OFF & PWRTE OFF & HS OSC
& WRT OFF & LVP OFF & CPD OFF
b r o j a c equ 0 x20
b r o j a c 1 equ 0 x21
b r o j a c 2 equ 0 x22
;
org
0 x000
; Procesor r e s e t v e k t o r
nop
goto
main
main
bsf STATUS, RP0
b c f STATUS, RP1
movlw B 00000000
movwf TRISB
b c f STATUS, RP0
28
; nop p o t r e b a n z b o g In C i r c u i t Debuggera
; I d i na g l a v n i program
c l r f PORTB
L0
movlw
movwf
movlw
bovwf
0xFF
brojac
0 x04
brojac2
L
bsf PORTB, 0
movf b r o j a c , 0
movwf b r o j a c 1
L1
de cs fz brojac1 ,1
g o t o L1
b c f PORTB, 0
movf b r o j a c , 0
ovwf b r o j a c 1
L2
i n c f s z brojac1 ,1
g o t o L2
b c f STATUS, C
r r f brojac ,1
b c f STATUS, C
r r f brojac ,1
de cf sz brojac2 ,1
goto L
g o t o L0
end
29
2.5
Mikrokontroler PIC16F877A, kao sto je i ranije receno, posjeduje 3 tajmerska modula. U ovom
dijelu cemo razmatrati tajmer TMR0. TMR0 ne predstavlja nista drugo nego 8-bitni registar iz
kojeg se moze citati sadrzaj i u koji se moze pisati sadrzaj. Vrijednost TMR0 se simultano povecava
izvrsavanjem instukcija, tj. prati povecavanje programskog brojaca (eng. Program counter ). Preko
skupine bitova koji se nazivaju preskaler (eng. Prescaler ) moze se utjecati na brzinu brojanja. Ako
sa n oznacimo vrijednost preskalera, onda se uvecavanje TMR0 registra vrsi svakih n instrukcija4 .
Pored podesavanja vrijednosti preskalera bitno je dodijeliti preskaler TMR0 modulu a ne
WDT 5 , jer je preskaler zajednicki za module TMR0 i WDT. Ova dodjela se vrsi preko PSA
bita OPTION REG registra i u slucaju da je on jednak nuli preskaler se odnosi na TMR0 ; u
suprotnom se odnosi na WDT.
U sljedecoj tabeli je data ovisnost vrijednosti preskalera i bitova PS2, PS1 i PS0 iz OPTION REG registra.
PS2
PS1
PS0
Preskaler
0
0
0
0
1
1
1
1
0
0
1
1
0
0
1
1
0
1
0
1
0
1
0
1
2
4
8
16
32
64
128
256
Tabela 2.5.1: Ovisnost vrijednosti preskalera i bitova PS2, PS1 i PS0 iz OPTION REG registra
Posto je TMR0 8-bitni registar to znaci da je najveci broj kojeg moze pamtiti broj 255, odnosno
da se nakon 256 koraka brojanja vrati u pocetno stanje (sto je 0). Ovo se moze iskoristiti na nacin
da, umjesto ranije razmatranih petlji za kasnjenje sa nop instrukcijama, koristimo jednostruku
petlju sa TMR0, kojom je moguce preciznije generirati nesto duza kasnjenja. Naime, pretpostavimo
da zelimo generirati kasnjenje od 50s. Ovo kasnjenje odgovara brojanju od 100 instrukcijskih
ciklusa mikrokontrolera PIC16F877A na taktu od 8MHz. Ovo se moze priblizno implementirati
upotrebom sljedeceg fragmenta koda6 .
; B r i s a n j e TMR0
c l r f TMR0
petlja
; U p i s i v a n j e 206 u W
movlw 206
; O b r i s a n j e C b i t a STATUS r e g i s t r a
4
30
b c f STATUS, C
; W + TMR0, r e z u l t a t u W
addwf TMR0, w
; T e s t i r a n j e da l i j e d o v o l j n o vremena p r o t e k l o
b t f s s STATUS, C
goto p e t l j a
U prethodnom fragmentu koda se prvo asemblerskom instrukcijom clrf obrise sadrzaj TMR0
registra, kao i njegovog preskalera7 . Zatim smo formirali petlju koja provjerava da li je TMR0
odbrojao 50, sto pri preskaleru od 2 znaci da je prebrojao 100 instrukcijskih ciklusa koji su bili
potrebni za zeljeno kasnjenje od 50s.
Prema tome, upotrebom TMR0 modula moguce je generirati kasnjenja td maksimalnog trajanja
odredenog relacijom
td = 256 256 0.5s = 32.768ms.
(2.5.1)
Postavka zadatka 2.5.1 za samostalni rad: Potrebno je napisati program na mikrokontroleru PIC16F877A koji implementira sistem za mjerenje frekvencije cetvrtaskog signala upotrebom TMR0 modula. Mjerenu frekvenciju treba prikazati na PORTB. Koja je maksimalna frekvencija signala koja se moze izmjeriti? Kakva dodatna elektronika bi bila potrebna ukoliko se zeli
mjeriti frekvencija sinusnog signala amplitude 10V?
Postavka zadatka 2.5.2 za samostalni rad: Potrebno je upotrebom TMR1 modula generirati
kasnjenje od 1s. TMR1 modul je po svojoj prirodi 16-bitni modul i radi toga omogucava veci opseg
brojanja. Implementirano kasnjenje testirati upotrebom brojaca na PORTB te izmjeriti apsolutno
i relativno odstupanje izmjerenog vremena od zeljenog vremena.
Postavka zadatka 2.5.3 za samostalni rad: Potrebno je implementirati sistem za dvopozicionu regulaciju istosmjernog motora sa nominalnim naponom od 24V i nominalnom brzinom od
3000ob/min. Motor se treba iskljuciti cim dostigne brzinu od 2000ob/min, a ukljuciti cim padne na
brzinu od 500ob/min. Mjerenje brzine vrtnje implementirati upotrebom TMR0 modula i enkodera.
2.6
Mikrokontroleri se cesto susrecu u obradi signala raznih senzora pa je zbog toga nezamislivo imati
mikrokontroler bez modula za analogno - digitalnu konverziju. Mikrokontroler PIC16F877A posjeduje jedan 10-bitni modul za analogno - digitalnu konverziju, sto znaci da se rezultat konverzije
upisuje u digitalnu rijec duzine 10 bita.
Opseg analogne ulazne velicine je razlika maksimalne i minimalne vrijednosti ulazne velicine,
odnosno vrijedi relacija
F SR = Vulmax Vulmin = Vref + Vref .
(2.6.1)
Primijetimo da su preskaler i tajmer TMR0 nista drugo nego dva kaskadno vezana brojaca. Cim
preskalerski
brojac odbroji broj impulsa na ulazu koji su zadani brojem preskalera on posalje brojacu TMR0 impuls da se i on
povecava za jedan. Radi toga je za korektno generiranje kasnjenja potrebno resetovati i preskaler, pogotovo ako je
on podesen na neku vecu vrijednost
31
F SR
5
= 10 4.88mV.
2n
2
(2.6.2)
Kvatni nivo se moze shvatiti kao najmanja vrijednost promjene ulaznog signala pri kojoj se desi
promjena digitalne rijeci u koju smijestamo rezultat. Ako sa Vul oznacimo vrijednost signala na
ulazu modula za analogno - digitalnu konverziju, onda je ekvivaletna digitalna rijec koja predstavlja
rezultat analogno - digitalne konverzije odredena relacijom
a = int(
Vul
),
q
(2.6.3)
H7
H6
H5
H4
H3
H2
H1
H0
L7
L6
L5
L4
L3
L2
L1
L0
Za detaljniji opis nacina promjene ulaznog opsega pogledajte poglavlje posveceno modulu za analogno - digitalnu
konverziju u dokumentaciji mikrontrolera PIC16F877A.
9
Za detaljniji opis o trajanju analogno - digitalne konverzije pogledajte poglavlje posveceno modulu za analogno
- digitalnu konverziju u dokumentaciji mikrontrolera PIC16F877A.
10
Posebno treba obratiti paznju na cinjenicu da se registri ADRESH i ADCON0 nalaze u nultoj memorijskoj
banci, a registri ADRESL i ADCON1 se nalaze u prvoj memorijskoj banci.
11
U tabeli se H odnosi na registar ADRESH, a L se odnosi na registar ADRESL
32
Medutim, ako koristimo lijevo poravnanje rezultata, onda se rezultat smijesta u registre ADRESH
i ADRESL prema sljedecoj tabeli.
H7
H6
H5
H4
H3
H2
H1
H0
L7
L6
L5
L4
L3
L2
L1
L0
AN 7
AN 6
AN 5
AN 4
AN 3
AN 2
AN 1
AN 0
Vref +
Vref
0000
0001
0010
0011
0100
0101
011x
1000
1001
1010
1011
1100
1101
1110
1111
A
A
D
D
D
D
D
A
D
D
D
D
D
D
D
A
A
D
D
D
D
D
A
D
D
D
D
D
D
D
A
A
D
D
D
D
D
A
A
A
A
D
D
D
D
A
A
A
A
D
D
D
A
A
A
A
A
D
D
D
A
A
A
A
D
D
D
A
A
A
A
A
A
D
A
A
A
A
A
A
D
D
A
A
A
A
A
A
D
A
A
A
A
A
A
A
A
VDD
AN 3
VDD
AN 3
VDD
AN 3
VDD
AN 3
VDD
AN 3
AN 3
AN 3
AN 3
VDD
AN 3
VSS
VSS
VSS
VSS
VSS
VSS
VSS
AN 2
VSS
VSS
AN 2
AN 2
AN 2
VSS
AN 2
Vref +
A
Vref +
A
Vref +
D
Vref +
A
Vref +
Vref +
Vref +
Vref +
D
Vref +
Vref
A
A
Vref
Vref
Vref
D
Vref
Tabela 2.6.1: Podesavanje analognih ulaza od bitovima PCFG0, PCFG1, PCFG2 i PCFG3.
Da bi neki pin bio analogni ulaz moramo odabrati takvu konfiguraciju bitova PCFG0, PCFG1,
PCFG2 i PCFG3 da je taj pin oznacen oznakom A u tabeli.
Da bi se uopce mogla vrsiti analogno - digitalna konverzija potrebno je ukljuciti modul za
analogno - digitalnu konverziju, a on se ukljucuje ADON bitom ADCON0 registra. Ako je
ADON jednak jedinici onda je modul za analogno - digitalnu konverziju ukljucen, a u suprotnom je iskljucen.
Pokretanje konverzije se vrsi pomocu bita GO iz ADCON0 registra. Naime, ako je on jednak
jedan, onda se pokrece konverzija, tj. vrsi se analogno - digitalna konverzija trenutno odabranog
kanala. GO bit se hardverski postavlja na nulu kada je zavrsena digitalno - analogna konverzija.
Sljedecim fragmentom koda je ilustrirano kako se pokrece analogno - digitalna konverzija, a rezultat
konverzije se prepisuje u varijablu.
; Pokretanje konverzije
bsf ADCON0,GO
33
; P e t l j a s e v r t i s v e dok s e h a r d v e r s k i ne z a v r s i p r o c e s k o n v e r z i j e
petlja
b t f s c ADCON0,GO
goto p e t l j a
; P r e p i s i v a n j e r e z u l t a t e analogno d i g i t a l n e k o n v e r z i j e
; i z ADRESH r e g i s t r a u v a r i j a b l u r e z u l t a t
movf ADRESH, w
movwf r e z u l t a t
Prethodni fragment koda je vrlo interesantan jer on prvo pokrece konverziju, a zatim u petlji
ceka dok se konverzija hardverski zavrsi, tj. dok se hardverski GO bit spusti na nulu. Zatim se
vrijednost registra ADRESH prepisuje u varijablu Rezultat. Ovo je uobicajeno u slucaju da nije
potrebna velika preciznost digitalno - analogne konverzije jer se, u slucaju lijevog poravnanja, samo
ocitanjem vrijednosti ADRESH registra dobija 8-bitna konverzija.
Medutim, prethodni fragment koda uzima vrijednost analognog signala na trenutno aktivnom
kanalu analogno - digitalnog konvertora. U slucaju da se zeli vrsiti uzastopna konverzija vise
kanala potrebno je promijeniti kanal pri svakom novom pokretanju analogno - digitalne konverzije.
Trenutno aktivni kanal se bira upotrebom bitova CHS0, CHS1 i CHS2 registra ADCON0, prema
sljedecoj tabeli.
CHS < 2 : 0 >
Aktivni kanal
000
001
010
011
100
101
110
111
AN 0
AN 1
AN 2
AN 3
AN 4
AN 5
AN 6
AN 7
34
; Ovdje j e p o t r e b n o i m p l e m e n t i r a t i k a s n j e n j e
; P e t l j a s e v r t i s v e dok s e h a r d v e r s k i ne z a v r s i p r o c e s k o n v e r z i j e
petlja2
b t f s c ADCON0,GO
goto p e t l j a 2
; P r e p i s i v a n j e r e z u l t a t e analogno d i g i t a l n e k o n v e r z i j e
; i z ADRESH r e g i s t r a u v a r i j a b l u r e z u l t a t 1
movf ADRESH, w
movwf r e z u l t a t 2
Prethodni kod je sasvim jasan osim komentara u kojem se navodi da je potrebno implementirati
kasnjenje. Naime, kako su sami kanali modula za analogno - digitalnu konverziju multipleksirani na
modulu, to znaci da je izmedu dvije konverzije potrebno sacekati dok se ne zavrsi prelazni proces
prebacivanja sa jednog kanala na drugi, odnosno dok se analogni ulaz modula napuni na vrijednost
napona novog kanala12 . Ovim je zavrseno izlaganje o modulu za analogno - digitalnu konverziju13 .
Postavka zadatka 2.6.1 za samostalni rad: Potrebno je implementirati kod u asemblerskom
jeziku koji konstantno vrsi analogno - digitalnu konverziju na kanalu 014 . Rezultat analogno digitalne konverzije treba ispisati na PORTB. Pored toga, potrebno je provjeriti rezultat analogno
- digitalne konverzije za napone: 0V, 0.1V, 0.2V, 0.5V, 1V, 1.3V, 1.9V, 2.4V, 3.1V, 3.6V, 4.4V,
4.9V i 5.5V.
Postavka zadatka 2.6.2 za samostalni rad: Potrebno je napisati kod u asemblerskom jeziku
koji konstantno vrsi sukcesivnu analogno - digitalnu konverziju na kanalima 0 i 1. Prilikom implementacije koristiti se dokumentacijom za mikrokontroler PIC16F877A za odredivanje minimalnog
vremena kasnjenja potrebnog da se zavrsi prelazni proces tokom prebacivanja aktivnog kanala
na modulu za analogno - digitalnu konverziju. Pored teoretskog minimalnog vremena kasnjenja
potrebno je i eksperimentalno odrediti isto kasnjenje te uporediti ta dva rezultata. Upotrebom
pina RD1 omoguciti odabir kanala koji se prikazuje na PORTB.
Postavka zadatka 2.6.3 za samostalni rad: Na bazi mikrokontrolera PIC16F877A potrebno
je implementirati dvopozicioni regulator temperature koji koristi NTC termistor kao temperaturni
senzor. U slucaju da temperatura dostigne 50 C potrebno je iskljuciti grijac i ukljuciti ventilator,
a u slucaju da temperatura dostigne 30 potrebno je iskljuciti grijac i ukljuciti ventilator. Pri
tome je na temperaturi od 50 C izmjeren otpor NTC termistora 817, a pri temperaturi od 30
izmjeren otpor NTC termistora 3726. Nacrtati kompletnu elektronsku shemu spajanja perifernog
hardvera proizvoljno odabranih realnih karakteristika.
Postavka zadatka 2.6.4 za samostalni rad: Potrebno je implementirati kod u asemblerskom jeziku koji realizira brojac na PORTB. Period brojanja brojaca treba zavisiti od vrijednosti
analognog kanala 0 na nacin da je rezultat 8-bitne konverzije proporcionalan 1 sekundi.
12
Vise detalja o potrebnom kasnjenju za analogno - digitalnu konverziju dato je u poglavlju posvecenom modulu
za analogno - digitalnu konverziju u dokumentaciji mikrokontrolera PIC16F877A.
13
Ovo izlaganje nije obuhvatilo podesavanje takta konverzija; detaljnije o tome se moze procitati u poglavlju
posvecenom modulu za analogno - digitalnu konverziju u dokumentaciji mikrokontrolera PIC16F877A.
14
Ovdje posebno obratiti paznju na postavke modula za analogno - digitalnu konverziju koje nisu detaljno razmatrane u prethodnom dijelu teksta.
35
2.7
Rad sa modulima za
sirinsko - impulsnu modulaciju
Sirinsko
- impulsna modulacija (eng. Pulse Width Modulation) predstavlja metodu moduliranja
signala na nacin da se informacija prenosi duzinom njegove logicke jedinice ili logicke nule pri
fiksiranom periodu. Jedan takav signal je prikazan na sljedecoj slici.
Ton
100[%].
T
(2.7.1)
Sirinsko
- impulsno modulirani signali se najcesce koriste pri upravljanju pozicionih servomotora, upravljanju nekim energetskim konvertorima, kao i pri projektiranju modula za digitalno analognu konverziju.
Modul za sirinsko - impulsnu modulaciju po nacinu rada dosta lici na modul za analogno digitalnu konverziju sa razlikom da se kod analogno - digitalne konverzije signal cita na nacin da
se njegova amplituda kvantizira, a kod sirinsko - impulsne modulacije se signal generira na nacin
da se njegov period kvantizira.
Mikrokontroler PIC16F877A, kao sto je i ranije receno, posjeduje dva sirinsko - impulsna
(PWM) modula koji se nazivaju CCP1 i CCP2. Oba modula se sastoje od dva 8-bitna registra (slicno kao i kod rezultata analogno - digitalne konverzije). Ti registri se nazivaju CCP1H i
CCP1L, odnosno CCP2H i CCP2L.
Upravljanje radom modula CCP1 i CCP2 vrsi se preko registara CCP1CON i CCP2CON,
respektivno. Kod konfiguracije ovih modula je bitno obratiti paznju na njihovu medusobnu zavisnost15 . Period T sirinsko - impulsne modulacije zavisi, izmedu ostalog, od vrijednosti preskalera
tajmerskog modula TMR2 (koji moze imati vrijednosti 1, 4 i 16). Period T sirinsko - impulsne
modulacije je dat relacijom
T = (P R2 + 1) Ti P,
(2.7.2)
gdje je PR2 namjenski 8-bitni registar za podesavanje perioda sirinsko - impulsnog signala, Ti
trajanje jednog instrukcijskog ciklusa mikrokontrolera, a P vrijednost preskalera tajmera TMR2.
Faktor popunjenosti se podesava upotrebom 10-bitne digitalne rijeci koja se formira kombinacijom CCP1L registra i dva bita (5. i 4. bit) CCP1CON registra na nacin da biti CCP1L
15
Detaljnije informacije o ovome mozete pronaci u poglavlju posvecenom sirinsko - impulsnim modulima u sklopu
dokumentacije mikrokontrolera PIC16F877A.
36
imaju najvecu tezinu, dok biti CCP1CON registra imaju najmanju tezinu. Primjera radi, ako je
digitalna rijec jednaka decimalnom broju 549 koji odgovara binarnom broju 1000100101, onda su
biti CCP1L i CCP1CON registra podeseni prema sljedecoj tabeli16 .
P 1L7
P 1L6
P 1L5
P 1L4
P 1L3
P 1L2
P 1L1
P 1L0
P 1CON5
P 1CON5
Ako digitalnu 10-bitnu digitalnu rijec koju formiraju registar CCP1L i CCP1CON oznacimo
sa n, onda se period logicke jedinice Ton sirinsko - impulsnog signala moze podesiti prema relaciji
Ton = n Tosc P,
(2.7.3)
list
#include
p=16f877A
; Lista d i r e k t i v a koja d efinira procesor
<p 1 6 f 8 7 7 A . i n c > ; D e f i n i c i j a v a r i j a b l i v e z a n i h za p r o c e s o r
; CONFIG s e k o r i s t i da s e u k l j u c e p o d a c i o h a r d v e r u na kojem
; ce s e p o s t a v i t i hex
CONFIG CP OFF & WDT OFF & BODEN OFF & PWRTE OFF & HS OSC
& WRT OFF & LVP OFF & CPD OFF
;
org
0 x000
; Procesor r e s e t v e k t o r
nop
goto
main
; nop p o t r e b a n z b o g In C i r c u i t Debuggera
; I d i na g l a v n i program
main
; I z b o r banke 1
bsf STATUS, RP0
b c f STATUS, RP1
; P o s t a v l j a n j e PORTC kao i z l a z n o g p o r t a
c l r f TRISC
; P o s t a v l j a n j e PORTD kao u l a z n o g p o r t a
movlw 0xFF
16
37
Postavka zadatka 2.7.2 za samostalni rad: Potrebno je implementirati driver koji pretvara analognu vrijednost maksimale rezolucije iz opsega od 0V do 5V u sirinsko - impulsni signal
frekvencije 180kHz. Naponu 0V odgovara faktor popunjenosti 0%, a naponu 5V odgovara faktor
popunjenosti 100%.
38
2.8
I1
2R
I2
4R
I3
V1
V2
0V
V3
Vout
0V
Vout = - V1 +
I1 + I2 + I3
V2 V3
+
2
4
odgovarajuci spektar diskretan, sto je zapravo posljedica periodicnosti povorke sirinskih impulsa.
Takoder vrijedi relacija
f=
1
.
T
(2.8.1)
list
#include
p=16f877A
; Lista d i r e k t i v a koja d efinira procesor
<p 1 6 f 8 7 7 A . i n c > ; D e f i n i c i j a v a r i j a b l i v e z a n i h za p r o c e s o r
; CONFIG s e k o r i s t i da s e u k l j u c e p o d a c i o h a r d v e r u na kojem
; ce s e p o s t a v i t i hex
CONFIG CP OFF & WDT OFF & BODEN OFF & PWRTE OFF & HS OSC
& WRT OFF & LVP OFF & CPD OFF
priv
equ 0 x28
;
org
0 x000
; Procesor r e s e t v e k t o r
nop
goto
main
main
bsf STATUS, RP0
b c f STATUS, RP1
movlw B 00000000
movwf TRISD
b c f STATUS, RP0
c l r f PORTD
c l r f priv
L1
movlw 0 x10
40
; nop p o t r e b a n z b o g In C i r c u i t Debuggera
; I d i na g l a v n i program
addwf p r i v , 1
movf p r i v , 0
movwf PORTD
g o t o L1
end
Postavka zadatka 2.8.2 za samostalni rad: Napisati program u asemblerskom jeziku koji
generira signal kao na sljedecoj slici (s tim da treba nastojati da se dobije sto bolja linearna
aproksimacija signala). Takt oscilatora iznosi 4MHz, a signal se generira na PORTD na kome je
spojen 8-bitni digitalno - analogni konverter.
41
2.9
R=
5 2.5V
= 250.
10 103
(2.9.1)
Otpor Rp , kao sto je u nekom od prethodnih primjera vec receno, kod prekidaca p ima dvije
svrhe. Jedna svrha je da ogranici struju koja ulazi u pin mikrokontrolera (vrijede ista strujna
ogranicenja kao i kod digitalnih izlaza) kada je prekidac otvoren, a druga je da se napajanje ne
spoji sa masom kada je prekidac zatvoren. Otpor Rp onda mozemo birati prema relaciji
Rp >
5
= 500,
10 103
(2.9.2)
Cifra
G
RD6
F
RD5
E
RD4
D
RD3
C
RD2
B
RD1
A
RD0
Hex kod
0
1
2
3
4
5
6
7
8
9
0
0
1
1
1
1
1
0
1
1
1
0
0
0
1
1
1
0
1
1
1
0
1
0
0
0
1
0
1
0
1
0
1
1
0
1
1
0
1
1
1
1
0
1
1
1
1
1
1
1
1
1
1
1
1
0
0
1
1
1
1
0
1
1
0
1
1
1
1
1
0x3F
0x06
0x5B
0x4F
0x66
0x6D
0x7D
0x07
0x7F
0x6F
void i n i c i j a l i z a c i j a ( ) {
// P o s t a v l j a n j e s v i h p i n o v a p o r t a D kao i z l a z n i h
TRISD = 0 ;
// P o s t a v l j a n j e s v i h p i n o v a p o r t a B kao u l a z n i h
TRISB = 2 5 5 ;
}
// F u n k c i j a k o j a u n o s i k a s n j e n j e od n 5ms
void d e l a y 5 ( char n ) {
char i ;
OPTION = 7 ;
do {
c l r w d t ( ) ; // o n l y i f watchdog e n a b l e d
i = TMR0 + 3 9 ; / 128 m i c r o s e c 39 = 5 ms /
while ( i != TMR0) ;
} while (n > 0 ) ;
}
// F u n k c i j a k o n v e r z i j e n a p r a v l j e n a u s k l a d u sa t a b e l o m k o r e s p o n d e n c i j e
char lookup ( char c i f r a ) {
i f ( c i f r a == 0 ) return 0x3F ;
17
44
Heksadecimalni zapis odgovarajuce cifre je formiran pod pretpostavkom da je RD7 na vrijednosti logicko 0.
i f ( c i f r a == 1 ) return 0 x06 ;
i f ( c i f r a == 2 ) return 0x5B ;
i f ( c i f r a == 3 ) return 0x4F ;
i f ( c i f r a == 4 ) return 0 x66 ;
i f ( c i f r a == 5 ) return 0x6D ;
i f ( c i f r a == 6 ) return 0x7D ;
i f ( c i f r a == 7 ) return 0 x07 ;
i f ( c i f r a == 8 ) return 0x7F ;
i f ( c i f r a == 9 ) return 0x6F ;
// Podrazumijevana v r i j e d n o s t
return 0 x00 ;
}
// Glavna f u n k c i j a
void main ( ) {
// P o z i v f u n k c i j e za i n i c i j a l i z a c i j u
inicijalizacija ();
// D e k l a r a c i j a v a r i j a b l e k o j a ce c u v a t i t r e n u t n u v r i j e d n o s t c i f r e
char c i f r a = 0 ;
// Beskonacna p e t l j a
while ( 1 ) {
// Uvecavanje b r o j a c a svakim p rolasko m k r o z p e t l j u
cifra = cifra + 1;
// O s i g u r a n j e da c i f r a o s t a n e u o p s e g u od 0 do 9
c i f r a = c i f r a % 10;
// B r o j a n j e prema g o r e
i f (PORTB. 0 == 0 ) PORTD = lookup ( c i f r a ) ;
// B r o j a n j e prema d o l j e
e l s e PORTD = lookup ( 9 c i f r a ) ;
// K a s n j e n j e od 1 s e k u n d e do s l j e d e c e i t e r a c i j e
delay5 ( 2 0 0 ) ;
}
}
Vidimo se se prethodni kod sastoji od nekoliko funkcija. Prva je funkcija inicijalizacija koja,
kao sto joj i samo ime kaze, inicijalizira sve postavke modula koje su nam potrebne u kodu. U
skladu sa postavkama zadatka PORTD proglasi izlaznim, a PORTB ulaznim. Mogli smo samo
jedan bit PORTB postaviti kao ulazni, ali proglasavanjem svih pinova porta B kao ulaznih ne
mijenjamo sustinski nista, jer i onako ne koristimo njegove preostalo pinove.
Druga funkcija koju susreceemo je funkcija delay5 ciji je zadatak da unese kasnjenje od n
5[ms]18 . Ova funkcija zapravo koristi tajmerski modul TMR0 na isti nacin kako smo ga ranije
koristili u asemblerskom jeziku. Naime, prvo se preskaler tajmerskog modula TMR0 postavlja na
256, sto znaci da je za jedno uvecanje tajmera TMR0 potrebno 128s. Zatim se u jednoj petlji
provjerava da li je proteklo 39 ciklusa brojanja, sto odgovara kasnjenju od 5ms. Jos jedna zanimljivost funkcije delay5 je sto ona prima argument tipa char ; razlog tome je sto se u programskom
jeziku C varijabla tipa char (osim u funkcijama ispisa) interpretira kao unsigned int od 8 bita.
Funkcija lookup implementira tabelu korespondencije za sedmosegmentni display a vidimo da
se rezultat vraca u obliku heksadecimalnog broja (slicno kao u ranijim primjerima sa asemblerskim
18
Ova
funkcija
je
inace
modificirana
http://www.bknd.com/files/delay.txt.
verzija
funkcije
delay10(char
n)
preuzeta
sa
45
jezikom).
Glavna funkcija poziva funkciju za inicijalizaciju na samom pocetku, a zatim se u svakoj iteraciji
petlje varijabla cifra uvecava za 1, s tim da se vodi racuna da varijabla uzima samo vrijednosti
iz skupa {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}. Na osnovu stanja pina RB0 (kojem mozemo direktno pristupati
kao sto smo to mogli u asemblerskom jeziku) vrsi se odluka da li se ispisuje vrijednost varijable
cifra ili njena komplementarna vrijednost (u dekadnoj bazi) 9 cif ra19 .
Takoder je zanimljiva linija koja poziva funkciju za kasnjenje. Naime, ona obezbjeduje da se
brojanje vrsi svake sekunde, a razlog tome je da ljudsko oko moze percipirati cifre na displayu.
Postavka zadatka 2.9.1 za samostalni rad: Potrebno je implementirati sistem kao u primjeru
2.9.1, s tim da sedmosegmentni display treba raditi u negativnoj logici.
Postavka zadatka 2.9.2 za samostalni rad: Potrebno je implementirati sistem kao u primjeru
2.9.1, s tim da se smjer brojanja bira pinom RD7. Diskutirati eventualne probleme koji se javljaju
takvim pristupom te dati detaljna rjesenja istih.
2.10
Uzimajuci u obzir ogranicenja poput lose podrske naprednijih tipova podataka kao tipova sa
pomicnim zarezom i samim ogranicenjem u brzini izvrsavanja slozeznih algebarskih izraza, gotovo
bilo kakav simbolicki pristup za mapiranje karakteristika senzora upotrebom raznih algebarskih
funkcija ne moze se koristiti. Umjesto toga, veoma je popularna metoda sekvencijalne pretrage
(eng. Sequential search) koja se sastoji od dva niza. Jedan niz je unaprijed sortiran i u sebi
(2.10.1)
Funkcija f po svojoj prirodi mapira beskocan skup tacaka iz V u X. Kao takva, koristi se pri
potrebi da se za proizvoljnu vrijednost v V proracuna odgovarajuce x X u svakom naprednijem
senzorskom sistemu koji ima jaku procesorsku moc. Medutim, ako se iz skupa tacaka X odabere
konacan broj tacaka (koje zelimo i mozemo mjeriti) i za taj skup tacaka se nade odgovarajuci skup
tacaka u koji se iste preslikavaju prema relaciji
v = f 1 (x).
(2.10.2)
Od skupa tacaka v se formira niz v prema nekom kriteriju od kojih su najcesci rastuci ili
opadajuci poredak. Pored niza sa v formira se niz x sa elementima iz x, pri cemu uredeni parovi
(v, x) odredeni funkcionalnim preslikavanjem f u nizovima imaju iste pozicije.
19
Primijetimo da je ispisivanje komplementarne vrijednosti cifre u dekadnom brojnom sistemu ekvivalentno brojanju unazad.
46
Sada za proizvoljno izmjereno v vrsimo pretragu po nizu v dok ne nademo izmedu koja dva
susjedna clana lezi ili je jednak v. Za pronadenu vrijednost v iz niza ocita se samo njemu pripadajuci
x cime dobivamo vrijednost mjerene velicine.
Ovaj pristup se oslanja na unaprijed izracunate vrijednosti nizova v i x pa umjesto vremena
potrebnog za racunanje f on potrosi memorijske resurse za potrebe cuvanja ovih nizova.
Pretpostavimo da proizvoljnim termickim senzorom mjerimo temperaturu na opsegu od 20C
do 30 C rezolucijom od 0.1 C i da znamo zavisnost napona od temperature. Podijelili bismo
interval [20, 30] na 100 jednakih intervala, odnosno za 101 vrijednost temperature u tom opsegu
odredili koliki je napon. Zatim bismo sortirali uredene parove prema nekom kriteriju poretka
napona. U ovom slucaju cemo pretpostaviti da je u pitanju opadajuci poredak napona. U tom
slucaju za izmjereni napon Vul odredimo temperaturu T prema sljedecem fragmentu koda.
// Podrazumijevana v r i j e d n o s t
Rezultat = 0 ;
f o r ( i = 0 ; i < 1 0 1 ; i ++)
i f ( Vul < V[ i ] ) R e z u l t a t = T [ i ] ;
e l s e break ;
Vidimo da se sekvencijalno pretrazivanje elemenata vrsi sve dok se ne dode do napona u nizu
od kojeg je ulazni napon manji, jer smo u tom slucaju pretragom pronasli odgovarajucu poziciju
naponu Vul s obzirom da je niz unaprijed sortiran. Za pronadeni indeks i se vraca odgovarajuca
vrijednost temperature T [i] koja odgovara trenutno izmjerenoj temperaturi.
Kod samog odredivanja vrijednosti u nizu v najefikasnije je naponske vrijednosti preskalirati u
ekvivalentnu digitalnu rijec koja ce biti upisana u ADRESH registar prilikom analogno - digitalne
konverzije tog napona. Ovo se moze postici relacijom
5
,
256
uz ranije spomenuta ogranicenja na vrijednost koju moze poprimati registar ADRESH.
ADRESH = Vul
(2.10.3)
47
2.11
Osnovni problem FLASHROM i RAM memorije je cinjenica da same po sebe nisu prikladne za
skladistenje nekih podataka koji ce ostati ocuvani poslije gubitka napajanja. Tacnije, FLASHROM
se moze iskoristiti u tu svrhu jer njegov sadrzaj ostaje nepromijenjen iskljucivanjem napajanja,
samo sto je taj pristup vrlo kompliciran i zahtijeva pisanje posebnog softvera za mikrokontroler
koji se naziva Bootloader. Za ovu svrhu se koristi EEPROM memorija koje na mikrokontroleru
PIC16F877A ukupno ima 256 bajta.
Citanje
EEPROM memorije se vrsi sljedecim koracima:
1. U EEADR registar se upise adresa EEPROM iz koje se zeli citati
2. Bit EEPGD iz EECON1 registra se postavi na 0 kako bi se naredne operacije odnosile na
EEPROM memoriju
3. Bit RD iz EECON1 registra se postavi na 1 kako bi poceo proces citanja
4. Procitani sadrzaj se smijesta u EEDATA registar
EEADR registar odreduje sa koje se memorijske lokacije unutar EEPROM - a vrsi citanje. S
obzirom da imamo 256 memorijskih lokacija i da je EEADR 8 - bitni registar, njegov sadrzaj se
zapravo odnosi na adrese izmedu 0 i 255.
EECON1 je registar kojim se upravlja citanje i pisanje EEPROM. EEPGD bit EECON1 registra govori da li se operacije citanja i pisanja odnose na FLASHROM ili EEPROM memoriju20 .
20
48
Postavka zadatka 2.11.1 za samostalni rad: Potrebno je napisati program koji cita sadrzaj
EEPROM memorije i ispisuje ga na portu B. Sadrzaj EEPROM - a treba rucno unijeti u programator prije procesa programiranja mikrokontrolera. Sadrzaj se cita sekvencijalno do pojave
vrijednosti 0xF F , nakon koje treba ispocetka poceti citanje. U svrhu bolje vizualizacije koristiti
kasjenje od 1s pri svakom osvjezavanju prikaza.
Postavka zadatka 2.11.2 za samostalni rad: Potrebno je implementirati program koji primjenom TMR0 modula vrsi peridicno ocitanje analogne vrijednosti na analognom kanalu AN0 svake
3ms i smijesta je u EEPROM memoriju. U slucaju popunjenja EEPROM memorije prepisati stare
vrijednosti.
Postavka zadatka 2.11.3 za samostalni rad: Potrebno je realizirati sistem koji generira
diskretnu sinusoidu proizvoljne konstantne amplitude na portu D. Vrijednosti sinusoide treba citati
iz EEPROM memorije, a vrijeme izmedu dva uzorka treba generirati upotrebom TMR0 modula. U
programu treba predvidjeti upravljanje vremena izmedu dva uzorka upotrebom nekog od analognih
ulaza. Pored toga je potrebno nacrtati i proracunati potpunu elektronicku shemu ovakvog sistema.
21
Slicno kao i kod GO bita koji se koristi prilikom analogno - digitalne konverzije.
49
POGLAVLJE
3
PREKIDI
3.1
U dosadasnjem radu je obraden sekvencijalni pristup razvoju aplikacije za mikrokontroler, ali takav
pristup povlaci ozbiljne poteskoce pri razvoju komplikovanih i modularnih aplikacija. Primjera
radi, da bismo ustanovili da li je doslo do promjene vrijednosti na nekom digitalnom ulazu mi
moramo periodicno vrsiti provjeru nekom petljom, sto samo po sebi nije efikasno iz razloga sto se
postoji mogucnost da se desi
svako kasnjenje unutar petlje manifestira na period provjeranja. Cak
promjena digitalnog ulaza unutar dvije provjere, sto bi rezultovalo cinjenicom da nismo obradili
taj ulaz. Ovakav pristup komunikacije sa perifernim uredajima se naziva prozivanje (eng. Polling)
i ne preporucuje se kod implementacije ozbiljnijih projekata radi izlozenog nedostatka.
U razvoju profesionalnijih aplikacija se koriste prekidi (eng. Interrupt), koji po nacinu programiranja dosta lice na razvoj aplikacije sa grafickim interfejsom (eng. Graphical user interface).
Prekid, kao sto i samo ime kaze, vrsi prekidanje trenutnog dijela koda i skace na poseban
dio programske memorije koji se zove prekidne rutina (eng. Interrupt service routine). Prekidna
rutina obraduje prekid, a zatim se nastavlja izvodenje koda sa mjesta u programskoj memoriji na
kojoj se desio prekid. To skakanje se vrsi na sljedeci nacin:
1. Desi se prekid
2. Zavrsava se izvrsavanje trenutne instrukcije
3. Sljedeca instrukcija se postavlja na stack memoriju (eng. Stack memory)
4. U programski brojac se postavlja adresa 0x04 (memorijska lokacija prekidne rutine)
5. Obraduje se prekid
6. Nakon obradenog prekida se vraca adresa sljedece instrukcije sa stack memorije
7. Nastavlja se izvrsavanje koda tamo gdje je stao prije prekida
Mikrokontroler PIC16F877A posjeduje 15 razlicitih tipova prekida koji se sve mogu razvrstati
na eksterne i interne prekide. Eksterne prekide izazivaju eksterni procesi koji imaju interakciju
sa mikrokontrolerom preko njegovih pinova, dok interne prekide izazivaju interni procesi samog
mikrokontrolera.
3.2
Kao predstavnika eksternih prekida analizirati cemo rad prekida na pinu RB0. Ovaj prekid se desi
kada se mijenja stanje ovog pina sa logicke 1 na logicku 0 ili obrnuto. Za podesavanje ovog prekida
se koristi OPTION REG i INTCON registri mikrokontrolera.
Bitom GIE iz INTCON registra se vrsi omogucavanje prekida, sto znaci ako je on jednak 1 onda
su prekidi omoguceni, a u suprotnom su prekidi onemoguceni. Preko bita PEIE iz istog registra
se ukljucuju eksterni prekidi, sto znaci ako je on jednak 1 onda su periferni prekidi omoguceni, a
u suprotnom su onemoguceni eksterni prekidi. Da bi se omogucio prekid na pinu RB0, onda je
potrebno bit RBIE postaviti na 1, u suprotnom je onemogucen.
Pored navedenih postavki se moze podesiti ivica na koju se aktivira prekid, pa postoji detekcija
rastuca i detekcija padajuce ivice. Ako se bit INTEDG postavi na 1 onda se vrsi detekcija rastuce
ivice, a u suprotnom se vrsi detekcija padajuce ivice.
Postavka zadatka 3.2.1 za samostalni rad: Dat je sljedeci listing koda. Potrebno je analizirati
ponasanje ovog koda na mikrokontroleru, s tim da se na RB0 izmjenicno mijenja vrijednost sa
logicke 0 na logicku 1 i obrnuto. Nacrtati odgovarajuci dijagram toka koji ilustrira rad ovog
programa.
Listing 3.2.1: Kod kojeg treba analizirati
#i n c l u d e int16CXX .H
#pragma o r i g i n 4
interrupt ir () {
int save registers ;
i f (INTF == 1 ) {
i f (PORTB == 2 5 5 ) PORTB = 0 ;
else {
#asm
b c f STATUS, 0
r l f PORTB, f
#endasm
}
}
INTF = 0 ;
int restore registers ;
}
void i n i c i j a l i z a c i j a ( ) {
TRISB = 1 ;
GIE = 1 ;
PEIE = 1 ;
INTE = 1 ;
INTEDG = 1 ;
PORTB = 0 ;
}
void main ( ) {
inicijalizacija ();
while ( 1 ) ;
}
52
Prekidi
Postavka zadatka 3.2.2 za samostalni rad: Zadatak upravljanja elektronicke strukture (prikazanoj
na slici 3.2.1) na bazi mikrokontrolera je da broji objekte na pokretnoj traci (koristeci fotopar) i
prikazuje na 2 sedmosegmentna displeja sa zajednickom katodom. Nakon 35 izbrojanih objekata
potrebno je iskljuciti DC motor i zaustaviti traku.
Postavka zadatka 3.2.3 za samostalni rad: Potrebno je analizirati assemblerski kod kojeg
generise prevodilac nad kodom iz primjera 3.2.11 . Na osnovu datog koda napisati kod koji ilustrira
upotrebu eksternog prekida na pinu RB0. Nacrtati obavezno dijagram toka ovog koda sa detaljnim
opisom promjene sadrzaja svih relevantnih registara.
3.3
Ovo je najlakse nad lst fajlom unutar direktorija projekta koji daje uporedo pregled assemblerskog koda i koda
iz programskog jezika C.
53
// U k l j u c i v a n j e p o t r e b n o g h e a d e r a za p r e k i d e
#i n c l u d e int16CXX .H
// D e k l a r a c i j a b r o j a c k e v a r i j a b l e
char b r o j a c ;
// Prekidna r u t i n a
#pragma o r i g i n 4
interrupt ir () {
// S p a s a v a n j e s a d r z a j a b i t n i h r e g i s t a r a
int save registers ;
//Da l i j e p r e k i d i z a z v a n pretekom TMR0 r e g i s t r a
i f ( T0IF == 1 ) {
b r o j a c ++;
}
// S p u s t a n j e TMR0 i n t e r r u p t f l a g a na 0
T0IF = 0 ;
// Vracanje s a d r z a j a b i t n i h r e g i s t a r a
int restore registers ;
}
void i n i c i j a l i z a c i j a ( ) {
// P o s t a v l j a n j e s v i h p i n o v a p o r t a B kao i z l a z n e
TRISB = 0 ;
// U k l j u c i v a n j e p r e k i d a
GIE = 1 ;
// U k l j u c i v a n j e Tajmerskog p r e k i d a
T0IE = 1 ;
// P o s t a v l j a n j e v r i j e d n o s t i p r e s k a l e r a na 256
OPTION = 7 ;
// P o s t a v l j a n j e b r o j a c a na p o c e t n u v r i j e d n o s t
brojac = 0;
}
// Glavna f u n k c i j a
void main ( ) {
inicijalizacija ();
// Beskonacna p e t l j a
while ( 1 ) {
PORTB = b r o j a c ;
}
}
Rje
senje primjera 3.3.1: Prethodni kod ilustrira upotrebu TMR0 prekida. Naime, u glavnoj
funkciji se poziva inicijalizacijska funkcija koja postavlja PORTB kao izlazni port, podesava tajmerski prekid i inicijalizira brojacku varijablu. U beskonacnoj petlji se vrsi prepisivanje vrijednosti
brojacke varijable na PORTB. Uvecanje brojacke varijable se vrsi unutar prekidne rutine. U
prekidnoj rutini se provjerava izvor prekida i obraduje se TMR0 prekid, te se spusta bit T0IF na
0, sto znaci da je obraden prekid. Medutim, ako ne spustimo taj bit na 0, onda program zaglavi
54
Prekidi
u prekidnoj rutini. Makroi int save registers i int restore registers 2 sluze za spasavanje sadrzaja
bitnih varijabli da bi se kod normalno mogao nastaviti nakon zavrsetka prekidne rutine. S obzirom
da je preskaler namjesten na 256 u prekidnu rutinu se ulazi svakih
256 256 0.5 106 s = 32.768ms.
(3.3.1)
Postavka zadatka 3.3.1 za samostalni rad: Potrebno je realizirati stopericu koja posjeduje
Postavka zadatka 3.3.2 za samostalni rad: U teoriji signala se cesto susrece filter za usrednjavanje uzoraka (eng. Moving average filter ), koji sluzi za eliminaciju suma cija je srednja vrijednost
jednaka nuli. Na bazi mikrokontrolera je potrebno implementirati filter za usrednjavanje uzoraka
opisan relacijom
10
y(k) =
1 X
x(k i); k, i N0 ,
10
(3.3.2)
i=0
uz nulte pocetne uslove. Vrijednost x(k) se ucitava sa analognog kanala AN0 svakih 0.5ms, a
vrijednosti y(k) se prikazuje na PORTB.
3.4
Vi
sestruki prekidi
Moguce je imati rjesenja koja koriste vise prekida istovremeno, sto se dalo naslutiti iz prethodnog
primjera s obzirom da smo provjerali izvor prekida. Upotreba visestrukih prekida se najlakse shvata na nekom realnom primjeru. Naime, zamislimo uobicajeni problem mjerenja brzine obrtanja
motora upotrebom inkrementalnog enkodera i fotopara. Neko opste prihvaceno mikrokontrolersko
rjesenje se temelji na brojanju cetvrtki koje se generisu na fotoparu presjecanjem enkodera u nekom
unaprijed poznatom vremenskom intervalu3 . Ovakvo ponasanje se lahko moze postici upotrebom
kombinacije TMR0 tajmerskog i eksternog prekida na pinu RB0. Prije nego sto nastavimo razmatranje, konkretizirajmo problem na nacin da pretpostavimo da na jednom punom obrtaju enkoder
2
3
55
(3.4.2)
s obzirom da enkoder na jednom punom obrtaju generise 10 cetvrtki, znaci da je u jednoj sekundi
potrebno izbrojati maksimalno 500 cetvrtki. Prema tome bi se mogla kreirati aplikacija koja
upotrebom prekida na pinu RB0 broji impulse, sve dok se ne desi tajmerski prekid (koji je podesen
na 1s). Kada se desi tajmerski prekid prirodno je osvjeziti prikaze trenutne frekvencije fm na
indikatoru.
Prethodnim pristupom se javljaju nekoliko problema. Prvi problem sto mi osvjezavamo prikaz
na indikatoru svake sekunde sto je relativno sporo, narocito kada se frekvencija brzo mijenja4 .
Drugi problem se temelji na cinjenici da tajmerski modul TMR0 moze najvise izbrojati 32.768ms,
sto je visestruko manje od zeljenog vremena. Drugi problem se moze izbjeci brojanjem pristupa,
koji se svodi na to da brojimo koliko puta smo puta usli u tajmerski prekidnu rutinu. Na osnovu
tog brojanja i pogodno odabrane vremenske baze za prekid, kao npr. 20ms, je moguce podesiti
zeljeno vrijeme. Svejedno ostaje problem sa osvjezavanjem indikatora, koji se moze izbjeci jednim
drugim pristupom. Naime, frekvenciji od 50Hz odgovara brojanju od 500 cetvrtki u jednoj sekundi.
Ovo se moze transformisati u izjavu da frekvenciji od 50Hz odgovara brojanju od 250 cetvrtki u
0.5 sekundi. Ovaj proces se moze nastavljati sve dok se ne postigne neka inherentno hardverski
podrzana vremenska baza, s tim da se mora voditi racuna o tome da zadrzi cijeli broj cetvrtki.
Ovaj pristup ima i svoj nedostatak koji i nije toliko ocit na prvi pogled. U prvom slucaju mi
procijenjujemo frekvenciju od 50Hz na rasponu od 500 koraka, sto daje neku efektivnu rezoluciju
od 0.1Hz, dok u drugom slucaju procijenjujemo istu frekvenciju na rasponu od 250 koraka, sto
daje efektivnu rezoluciju od 0.2Hz. Prema tome, za brzu mjernu dinamiku zrtvujemo rezoluciju,
pa je radi toga vazno naci kompromis izmedu rezolucije i mjerne dinamike. Alternativan pristup
kompenzaciji ove negativne pojave bi bila zamjena postojeceg enkodera sa enkoderom sa vecim
brojem koraka5 .
Na prethodnoj slici je prikazan dijagram toka za razmatrano rjesenje. Sa dijagrama se vidi
da se prvo vrsi inicijalizacija brojacke varijable, indikatora, kao i koristenih prekida. Zatim se u
ulazi u beskonacnu petlju iz koje se samo izlazi prekidima. Ako se desi eksterni prekid, onda se
skace u njegovu prekidnu rutinu koja uvecava brojacku varijablu za jedan. U slucaju tajmerskog
prekida vrsi se osvjezavanje prikaza na indikatoru, kao i resetovanje brojaca. Dok je jedan prekid
aktivan, podrazumjeva se da drugi prekid ne moze biti aktivan, sto se moze najlakse preko bita
GIE regulisati6 .
Postavka zadatka 3.4.1 za samostalni rad: Na bazi dijagrama toka prikazanog na slici
3.4.1 je potrebno implementirati sistem za mjerenje frekvencije motora cija je maksimalna brzina 12000ob/min. Indikaciju je potrebno vrsiti na rezoluciji od 0.1Hz.
4
Drugi primjer bi bila regulacija brzine vrtnje motora, s tim da bi ovakvo mjerenje unosili kasnjenje od jedne
sekunde, radi koje bi se sistem nestabilno ponasao.
5
Podesavanjem eksternog prekida na nacin da detektuje obje ivice je moguce udvostruciti rezoluciju bez promjene
enkodera.
6
Alternativan pristup bi podrazumijevao iskljucivanje svih ostalih prekida ponaosob.
56
Prekidi
Inicijalizacija
brojaca na nulu
Inicijalizacija
prekida i indikatora
Eksterni prekid
Uvecanje brojaca
za jedan
Beskonacna
petlja
Timerski prekid
Osvjeavanje
prikaza na
indikatoru
Reset brojaca
Slika 3.4.1: Dijagram toka aplikacije koja mjeri brzinu vrtnje motora.
Postavka zadatka 3.4.2 za samostalni rad: Potrebno je implementirati sistem stoperice iz
primjera 3.3.1 upotrebom dva tajmerska prekida. Jedan tajmerski prekid upravlja displejima koji
su zajedno multipleksirani, dok drugi tajmerski modul osvjezava trenutno vrijeme.
Postavka zadatka 3.4.3 za samostalni rad: Potrebno je implementirati sistem za upravljanje
brzine cirkularne pile cija je prenosna funkcija data kao
G(s) =
(s)
200
=
,
V (s)
0.125s + 1
(3.4.3)
gdje je (s) Laplaceova transformacija brzine obrtanja (ob/min) cirkularne pile, a V (s) Laplaceova
transformacija ulaznog napona u drajver cirkularne pile. Sistem treba imati mogucnost zadavanja
referetne brzine upotrebom potenciometra koji je spojen na analogni kanal AN0, regulaciju brzine
vrtnje vrsiti PI regulatorom. Takoder je potrebno predvidjeti taster za hitno zaustavljanje pile.
57
POGLAVLJE
4
SERIJSKA KOMUNIKACIJA
U prethodnom poglavlju razmatran je dizajn profesionalnih aplikacija na mikrokontrolerima koristeci vec ranije objasnjene module. Naime, najvecu upotrebnu vrijednost mikrokontrolerima kao
ugradbenim uredajima daju moduli za komunikaciju, koji ce biti razmatrani u ovom poglavlju.
Mikrokontroler PIC16F877A, kao sto je vec ranije receno, posjeduje module za paralelnu i serijsku komunikaciju. U ovom poglavlju ce se posmatrati serijska komunikacija s obzirom na to da
se cesce susrece u odnosu na paralelnu komunikaciju. Osnovni razlog tome je sto su za serijsku
komunikaciju u osnovnoj formi samo potrebne dvije linije preko kojih se vrsi komunikacija.
4.1
Topologija spajanja od tacke do tacke (eng. Point to point topology) moze se smatrati osnovnom
topologijom spajanja, jer je najjednostavnija za razumjeti. Blok shema takve topologije prikazana
je na sljedecoj slici.
Rx
Mikrokontroler 1
Tx
Tx
Mikrokontroler 2
Rx
To ne moraju nuzno biti mikrokontroleri, vec bilo kakva elektronska struktura s kojom je moguce realizirati
serijsku komunikaciju.
2
Ovaj modul je odabran jer se s njim moguce upostaviti komunikaciju izmedu racunara i mikrokontrolera.
void i n i c i j a l i z a c i j a K o m u n i k a c i j e ( ) {
// High baud r a t e
BRGH = 0 ;
//Za o s c i l a t o r od 8MHz j e p o t r e b n o 12 da s e p o d e s i 9600 baud
SPBRG = 1 2 ;
// Asinhrona k o m u n i k a c i j a
SYNC = 0 ;
// Omogucavanje p r e d a j e
TXEN = 1 ;
// Omogucavanje p r i j e m a
CREN = 1 ;
// U k l j u c i v a n j e s e r i j s k o g p o r t a
SPEN = 1 ;
}
void main ( ) {
// I n i c i j a l i z a c i j a d i g i t a l n i h u l a z a i i z l a z a
TRISB = 0 ;
TRISD = 2 5 5 ;
PORTB = 0 ;
TRISC . 0 = 0 ;
// I n i c i j a l i z a c i j a k o m u n i k a c i j e
inicijalizacijaKomunikacije ();
// Beskonacna p e t l j a
while ( 1 ) {
// C i t a n j e i z u l a z n o g spremnika
i f (RCIF == 1 ) {
PORTB = RCREG;
}
// S l a n j e p o r uk e sa PORTD
3
60
Serijska komunikacija
i f (PORTC. 0 == 1 ) {
TXREG = PORTD;
while (TRMT == 0 ) ;
}
}
}
Postavka zadatka 4.1.1 za samostalni rad: Problem pristupa u prethodnom primjeru predstavlja cinjenica da nije izvrsena prilagodba standarda, tj. mikrokontroleri razgovaraju TTL naponskim nivoima, a ne nivoima predvidenim RS232 standardom4 . Potrebno je nacrtati elektronsku
strukturu prilagodbe ova dva standarda koristeci proizvoljno integrirano kolo predvideno za tu
svrhu.
4.2
Komunikacija vi
se mikrokontrolera na jednoj sabirnici
Osnovni nedostatak prethodne topologije je cinjenica da je samo moguce povezati dva mikrokontrolera. Ovaj nedostatak je moguce zaobici upotrebom sabirnicke topologije, koja omogucava da
vise mikrokontrolera istovremeno koristi dijeljenu sabirnicu, a prikazana je na sljedecoj slici. Sa
slike vidimo da svaki mikrokontroler posjeduje prilagodbu za RS485 standard, kao i da su izlazi
iz prilagodbi medusobno spojeni. Razlog ovome je da se logicki nivoi u konfiguraciji komunikacije
definiraju preko naponske razlike TX i RX. RS485 protokol je namjenski odabran, jer omogucava
zadavanje naredbi preko racunara.
Tx
RS485
Prilagodba
Rx
Mikrokontroler 1
Rx
Rx
Tx
Tx
RS485
Prilagodba
Tx
Tx
Mikrokontroler 2
Rx
Rx
Tx
Tx
RS485
Prilagodba
Mikrokontroler 3
Rx
Rx
61
Posmatrajmo primjer gdje je potrebno razviti protokol koji realizira dvije komande preko sabirnice. Prva komanda ce biti postavljanje poslate vrijednosti na PORTB, bez odgovora od mikrokontrolera, a druga ce biti citanje zadatog analognog ulaza uz odgovor trenutne ocitane vrijednosti sa
tog ulaza. Poruke ce biti u formatu od 4 bajta formatirana na nacin #-ADRESA-KOMANDAARGUMENT, tako npr. naredba #ASA znaci na modulu adrese A postavi PORTB na vrijednost
A (sto odgovara ASCII vrijednosti od 65), dok bi naredba #BR0 znacila na modulu sa adrese B
ocitaj analognu vrijednost na kanalu 0.
Dijagram stanja ovakvog protokola je prikazan na sljedecoj slici.
b8
S4
b6
b5
b4
b2
b1
S1
S2
b3
S3
b7
b9
S5
Slika 4.2.2: Dijagram stanja protokola.
Stanja sa slike su definirana kao:
S1 : cekanje pocetka poruke
S2 : cekanje adrese
S3 : cekanje komande
S4 : cekanje parametra
S5 : cekanje parametra
Dok su signali definirani kao:
b1 : pocetak poruke (#)
b2 : pogresan format poruke
b3 : adresa modula (0 255)
b4 : pogresan format poruke
b5 : pogresan format poruke
b6 : ispis na PORTB (S)
62
Serijska komunikacija
4.3
Spajanjem sabirnice sa slike 4.2.1 na serijski port racunara omogucava softversko upravljanje iste. U
opcem slucaju ne mora to ni biti sabirnica, nego bilo kakav uredaj koji ima serijski drajver. Sljedeci
listing koda daje primjer koristenja serijskog porta COM15 upotrebom skripte iz programskog
paketa MATLAB.
Listing 4.3.1: Upravljanje sabirnicom iz MATLAB-a
%D e k l a r a c i j a o b j e k t a k o j i k o m u n i c i r a p r e k o s e r i j s k o g p o r t a COM1
s e r i j s k i P o r t = s e r i a l ( COM1 ) ;
%P o s t a v l j a n j e b r z i n e p r e n o s a
set ( s e r i j s k i P o r t , BaudRate , 9 6 0 0 ) ;
% U p o s t a v l j a n j e v e z e sa s a b i r n i c o m
fopen ( s e r i j s k i P o r t ) ;
%Naredba za p o s t a v l j a n j e v r i j e d n o s t i 65 na PORTB
f p r i n t f ( s e r i j s k i P o r t , %s , #ASA ) ;
%Naredba za o c i t a v a n j e v r i j e d n o s t i sa AN0
f p r i n t f ( s e r i j s k i P o r t , %s , #AR0 ) ;
%C i t a n j e v r i j e d n o s t i AN0 u formatu c i j e l o g b r o j a
f s c a n f ( s e r i j s k i P o r t , %d %);
Iz koda vidimo da je prvo napravljen objekat koji rukuje serijskom komunikacijom. Zatim je
podesena brzina prenosa a upotrebom funkcije fprintf poslate su dvije naredbe. Ocitanje povratne
vrijednosti posljednje naredbe izvrseno je upotrebom fscanf funkcije.
Postavka zadatka 4.3.1 za samostalni rad: Potrebno je u MATLAB-u implementirati aplikaciju sa grafickim okruzenjem, koja ce upravljati sabirnicom iz primjena 4.2.1 za samostalni
rad.
5
Ime serijskog uredaja zavisi od konkretnog hardvera racunara, kao i instaliranog operativnog sistema.
63
64
PRILOG
65
66
67
PRILOG
Proces instalacije razvojnog okruzenja MPLAB sekvencijalno prati sljedece korake, prikazane na
slikama ispod.
69
70
71
72
73
74
PRILOG
C
LISTA INSTRUKCIJA MIKROKONTROLERA PIC16F877A
PIC16F87XA
Mnemonic,
Operands
Description
Cycles
14-Bit Opcode
MSb
LSb
Status
Affected
Notes
f, d
f, d
f
f, d
f, d
f, d
f, d
f, d
f, d
f, d
f
f, d
f, d
f, d
f, d
f, d
Add W and f
AND W with f
Clear f
Clear W
Complement f
Decrement f
Decrement f, Skip if 0
Increment f
Increment f, Skip if 0
Inclusive OR W with f
Move f
Move W to f
No Operation
Rotate Left f through Carry
Rotate Right f through Carry
Subtract W from f
Swap nibbles in f
Exclusive OR W with f
1
1
1
1
1
1
1(2)
1
1(2)
1
1
1
1
1
1
1
1
1
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0111
0101
0001
0001
1001
0011
1011
1010
1111
0100
1000
0000
0000
1101
1100
0010
1110
0110
dfff
dfff
lfff
0xxx
dfff
dfff
dfff
dfff
dfff
dfff
dfff
lfff
0xx0
dfff
dfff
dfff
dfff
dfff
ffff
ffff
ffff
xxxx
ffff
ffff
ffff
ffff
ffff
ffff
ffff
ffff
0000
ffff
ffff
ffff
ffff
ffff
00bb
01bb
10bb
11bb
bfff
bfff
bfff
bfff
ffff
ffff
ffff
ffff
111x
1001
0kkk
0000
1kkk
1000
00xx
0000
01xx
0000
0000
110x
1010
kkkk
kkkk
kkkk
0110
kkkk
kkkk
kkkk
0000
kkkk
0000
0110
kkkk
kkkk
kkkk
kkkk
kkkk
0100
kkkk
kkkk
kkkk
1001
kkkk
1000
0011
kkkk
kkkk
C,DC,Z
Z
Z
Z
Z
Z
Z
Z
Z
C
C
C,DC,Z
Z
1,2
1,2
2
1,2
1,2
1,2,3
1,2
1,2,3
1,2
1,2
1,2
1,2
1,2
1,2
1,2
f, b
f, b
f, b
f, b
Bit Clear f
Bit Set f
Bit Test f, Skip if Clear
Bit Test f, Skip if Set
1
1
1 (2)
1 (2)
01
01
01
01
1,2
1,2
3
3
2:
3:
k
k
k
k
k
k
k
k
k
1
1
2
1
2
1
1
2
2
2
1
1
1
11
11
10
00
10
11
11
00
11
00
00
11
11
C,DC,Z
Z
TO,PD
Z
TO,PD
C,DC,Z
Z
When an I/O register is modified as a function of itself ( e.g., MOVF PORTB, 1), the value used will be that value present
on the pins themselves. For example, if the data latch is 1 for a pin configured as input and is driven low by an external
device, the data will be written back with a 0.
If this instruction is executed on the TMR0 register (and where applicable, d = 1), the prescaler will be cleared if
assigned to the Timer0 module.
If Program Counter (PC) is modified, or a conditional test is true, the instruction requires two cycles. The second cycle is
executed as a NOP.
Additional information on the mid-range instruction set is available in the PICmicro Mid-Range MCU
Family Reference Manual (DS33023).
75
PRILOG
IC-Prog je softverski programator koji podrzava siroku paletu mikrokontrolera razlicitih proizvodaca.
Drugim rijecima, koristi se za prebacivanje koda sa racunara na mikrokontroler putem serijske komunikacije preko serijskog porta racunara.
Aplikaciju IC-Prog je moguce preuzeti sa http://www.ic-prog.com . U nastavku je opisan postupak programiranja mikrokontrolera PIC16F877A koristenjem pomenutog programatora. Prilikom
prvog pokretanja aplikacije, na formi prikazanoj na slici ispod, potrebno je podesiti opcije hardvera
koji ce se koristiti za komuniciranje sa mikrokontrolerom. Preciznije receno, potrebno je, pod dijelom Programmer (oznaceno na slici brojem 1), izabrati opciju JDM Programmer te odgovarajuci
serijski komunikacioni port (oznaceno na slici brojem 2).
78
79
81
Izborom opcije Browse moguce je odabrati folder za instalaciju okruzenja MPLAB ili, ipak,
ostaviti defaultnu lokaciju C:/Program Files/ WinPic800. Po izboru foldera za instalaciju izabrati
opciju Start.
82
Prlikom pojave sljedece forme, izabrati opciju Next kako bi se izvrsila instalacija potrebnih
drivera.
83
Prilikom prvog pokretanja WinPic800 aplikacija ima izgled prikazan na slici ispod.
84
85
PRILOG
Na web stranici http://www.bknd.com/cc5x/download.shtml je dostupna studentska verzija kompajlera CC5x. Proces instalacije istog sekvencijalno prati korake prikazane na sljedecim slikama.
88
Nakon pokretanja MPLAB okruzenja, s ciljem kreiranja C projekta, potrebno je pratiti sljedece
korake.
Izabrati opciju Project-Project Wizard.
89
Podesiti lokacije za CC5X C kompajler, MPASM i MPLINK izborom opcije Browse za svaku
od komponenti respektivno, kao sto je prikazano na slikama ispod:
90
91
92
U novokreirani projekat moguce je dodati neke postojece fileove, ali nije i obavezno.
93
94
U nastavku je potrebno kreirati C file i isti dodati u direktorij Source Files kreiranog projekta,
prateci sljedece korake.
Otvoriti tekstualni editor i sacuvati file kao imeFilea.c (ekstenziju c je obavezno navesti)
u direktorij u kojem se nalazi kreirani projekat, pri cemu je za tip filea u Save dijalogu potrebno
izabrati opciju All Files , kao sto je prikazano na slici ispod.
95
U MPLAB okruzenju izabrati opciju Add Files za direktorij Source Files, kao na slici ispod.
96
97