Nikada nisam radio sa 8051, ali iz koda je ocigledno sledece:
Svaka asemblerska instrukcija trosi odredjeno vreme za izvrsavanje.
Isto je i kod mikroprocesora i kod mikrokontrolera.
To vreme zavisi iskljucivo od takta oscilatora. Buduci da nisam
upoznat sa 8051 arhitekturom, pretpostavicu da on ima eksterni
kristalni oscilator. Ukoliko je taj kristal 1MHz, 8051 ce izvrsavati
instrukcije deset puta sporije nego da je upotrebljen kristal od
10MHz. Kod skoro svih asemblera mikrokontrolera i mikroprocesora
instrukcija koja ne radi nista korisno je NOP i ona trosi jedan jedini
instrukcijski ciklus, odnosno izvrsava se za minimalno moguce vreme.
Ovo vreme ipak, ne mora biti direktno vezano za takt, jer neki
mikrokontroleri izvrsavaju instrukciju za jedan takt oscilatora, neki
za 4, neki za 12. Jos gore, neki imaju promenljivo vreme u zavisnosti
od upotrebljene instrukcije. Na primer, pretpostavljam da za 8051 NOP
traje krace nego LCALL instrukcija, odnosno trosi manje instrukcijskih
ciklusa.
Ceste su i instrukcije koje nemaju fiksan broj instrukcijskih ciklusa,
vec ce trajati 1, 2 ili vise instrukcijska ciklusa ukoliko je
odredjeni uslov ispunjen. Pretpostavlkjam da je kod 8051 DJNZ upravo
takva instrukcija.
Broj upotrebljenih instrukcijskih ciklusa dat je za svaku instrukciju
u datasheetu mikrokontrolera i mikroprocesora.
Kada je ovo jasno, lako je pretpostaviti sta program dalje radi.
Po skoku na potprogram Delay u registre R0, R1 i R2 inicijalizuju se
neke vrednosti. Pretpostavljam da instrukcija DJNZ R0,$ smanjuje
(dekrementuje) vrednost R0 registra, sve dok ovaj ne dodje do 0. Tek
kada dodje, nastavlja se od sledece instrukcije.
'$' u ovom slucaju predstavlja adresu na kojoj se trenutno nalazi
instrukcija koja se izvrsava. Umesto njega, moglo se pisati i
Code:
F00: DJNZ R0,F00
Sta radi ovaj potprogram? Najpre smanjuje vrednost R0 sve dok ne dodje
do 0. Znaci vrednost R0 bice 230, 229, 228, 227...
Kao brojanje u zmurkama. Kada R0 dodje do 0, prelazi se na sledecu
instrukciju, i ona pocinje da smanjuje R1, ali nakon njenog smanjenja
poinovo inicijalizuje R0 na 230. Sledece smanjivanje R1 nastupice tek
nakon sto R0 ponovo odbroji do 0. To Vam je kao kada R0 predstavite
sekundama, R1 minutima a R2 satima, a zatim smanjujete vreme sekundu
po sekundu.
Na osnovu komentara 25mS ocigledno je da smanjenje R0 i R1 traje ravno
25mS (uz upotrebljeni takt oscilatora). Da bi se doslo do pauze od
500mS potrebno je samo ovaj deo koda ponoviti 20 puta, a to je
realizovano smanjenjem R2 od 20 do 0. 25mS * 20puta = 500mS.
Uz malo logike, lako se moze proracunati i trajanje krace petlje
(za smanjenje R1) buduci da je ista 0,5mS * 50puta = 25mS.
Prilikom ovakvih pocetnickih programa, uglavnom nije data bas tacna
vrednost (tacno 500mS), vec priblizna, npr. 500,00008S, tako da nemoj
da Vas to preterano buni.
Da biste lakse shvatili rad ovog i slicnih programa preporucio bih Vam
da na netu probate da pronadjete softverski simulator za 8051
(proguglajte sa 8051 simulator) i da sa njim simulirate rad programa
instrukciju po ionstrukciju. Ukoliko dovoljno ovladate mogucnostima
simulatora, bicete u stanju da veoma brzo pravite pauze proizvoljne
duzine jednostavnom metodom pokusaja, simuliranja i prepravke
inicijalnih parametara.
Uzgred, prilicno me cudi komentar uz sledecu instrukciju:
Code:
MOV P1,#0FFh ;Sve pinove definisi kao ulaze
LED bi trebala biti povezana na izlaz, a ne na ulaz.
Licno smatram da je pauza najgora moguca stvar koju moze raditi ijedan
mikrokontroler ili mikroprocesor. Sto veca, to gora. Nadam se da cete
vremenom shvatiti razlog. Za sada, samo napred. Jasno mi je da je za
proces ucenja ipak neophodna.