Ploter driver za m6803
1.Uvod
2.Osnovni koncept
3.Zasnova programa
4.Opis strojne kode
Ploter driver je napisan za realtime operacijski sistem za m6803 pri vajah v okviru predmeta Mikoroprocesorji v elektroniki na smeri Elektronika v 5. letniku. Namenjen je risanju ravnih črt poljubnih dolžin in naklonov. Sestavljen je iz dveh delov. En del je izračun in priprava vseh parametrov, ki jih nato uporablja program v urniku za izris črte. Vhodni podatek je relativna ali absolutna koordinata drugega krajišča premice, prvo krajišče je trenutna pozicija ploterja. Dodana je rutina za dvigovanje in spuščanje svinčnika.
Ko hočemo narisati ravno črto poljubne dolžine in naklona, ni večjega problema. Vzame se ravnilo in potegne črto s svinčnikom. Stvar se zelo zakomplicira, če imamo na voljo le diskretne pomike svinčnika v X in Y smeri (korake). Vzemimo, da je začetna točka vedno (0,0). Koordinate cilj točke so DesX in DesY in so pozitivna cela števila. To pomeni da se nahajamo v prvem kvadrantu. Če je količnik K=DesX/DesY ali K=DesY/DesX druge koordinate celo število, potem ni težav. Do te točke lahko pridemo z celimi koraki in sicer: DesX=K*DesY (korakY=1, korakX=K) ali DesY=K*DesX (korakX=1, korakY=K). Če pa količnik K ni celo število, potem ne moremo narediti npr. 1.23 koraka v eni smeri, da bi po določenem1 številu korak prispeli točno do končne točke. Ena rešitev se takoj ponuja in sicer: Po vsakem koraku naj se na novo izračuna K in naj se upošteva njegova cela vrednost. Če je K=1.23, potem se z koraki korakX=1 in korakY=1 sčasoma veča K in slejkoprej pridemo do točke kjer se K prevesi v 2. Na ta način vedno pridemo do prave končne točke. Vendar po kateri poti? Po ravni črti že ne, razen v redkih izjemah, saj se K med risanjem spremeni. Lomljena črta se najbolj opazi pri prehodu iz K=1 na 2. Pri višjih K se to ne pozna več toliko, vendar je še vedno opazno. Torej taka rešitev ni ravno najboljša, zato je pametno poiskati drug koncept.
Druga
rešitev bazira na naslednjem principu: Ravna črta pod poljubnim kotom se
lahko nariše tako, da začnemo z osnovnim količnikom. Nato na vsake toliko
korakov v X in Y smer dodamo kakšen popravek proti ciljni točki, odvisno
v katero smer se oddaljujemo. Če je potrebno nato na vsake toliko popravkov
kakšnega izpustimo itd...
Ko
delimo koordinati ciljne točke, dobimo celoštevilčen K in ostanek. Ta ostanek
sedaj razdelimo enakomerno po manjši koordinati ( delimo koordinato z ostankom).
Dobimo vrednost, ki pove na koliko korakov naj se doda eden korak v smeri
proti cilju. Ker pri zadnjem deljenju spet dobimo ostanek, ga lahko spet
razdelimo po manjši koordinati itd...
Matematično
to lahko zapišemo: predpostavimo da je Y>X
Sedaj lahko ciljno koordinato Y zapišemo po korakih kot:K=DesY/DesX + ost
K1=DesX/ost + ost1
K2=DesX/ost1 + ost2
K3=DesX/ost2 + ost3
itd...
Zadeva je podobna bisekciji. Kako izgleda risanje črte na podlagi teh količnikov?Y=K*DesX <= DesY
Y=K*DesX + DesX/ost >= DesY
Y=K*DesX + DesX/ost - DesX/(ost*ost1) <=DesY
Y=K*DesX + DesX/ost - DesX/(ost*ost1) + DesX/(ost*ost1*ost2) >= DesY itd...
Podobno bi lahko razvili vrsto za X, če bi predpostavili X>Y.
Poglejmo si en primer:
Izkušnje so pokazale, da so za vrednosti ciljnih koordinat do nekaj tisoč dovolj trije popravki, napake niso večje od 2 korakov.DesX=805 DesY=1032
K=1, ost=227
K1=3, ost1=124
K2=6, ost2=61
K3=13, ost3=12Y=1*805=805 < 1032
Y=1*805+805/3=1073 >1032
Y=1*805+805/3-805/(3*6)=1028 < 1032
Y=1*805+805/3-805/(3*6)+805/(3*6*13)=1031
Driver je zasnovan modularno, tako da se da uporabiti katerkoli njegov zaključen del. Komunikacija med driverjem in ostalimi programi, ki ga uporabljajo poteka preko treh registrov:
UKAZX in UKAZY sta 16 bitni spremenljivki, ki vsebujeta
relativni ali absolutni ciljni koordinati X in Y
UKAZ je 8 bitna kontrolno-statusna spremenljivka, pri
kateri ima vsak bit svoj pomen (podobno kot statusni register)
Sestava registra UKAZ:
X | BUSY | X | X | X | UP/DWN* | R/A* | STOP |
BUSY predstavlja komunikacijo z driverjem v urniku. Driver se ne izvaja, dokler ni BUSY=1. Potem predpostavlja, da so vse njegovi parametri izračunani in začne z delom. Črta se riše, medtem morajo ostali uporabniki driverja počakati, kar lahko storijo z preverjanjem busy signala. Ko se risanje črte zaključi, se BUSY postavi na 0, in driver je prost za naslednji ukaz.
R/A* je bit, ki indicira tip koordinat X in Y. Če je R/A*=1, potem je koordinata, podana v UKAZX in UKAZY spremenljivkah relativna, če ne je pa absolutna, in jo driver sam pretvori v relativno tako, da jo odšteje od trenutne pozicije.
STOP bit pomeni brezpogojno prekinitev risanja. To stori driver tako, da postavi BUSY na 0. Če se potem z nekim zunanjim programom postavi busy na 1 bo driver nadaljeval tam, kjer je končal, če njegovi parametri ne bodo spremenjeni.
UP/DWN* bit indicira stanje svinčnika. Če je UP/DWN* =1 je svinčnik dvignjen, če ne je spuščen. Ta bit testira rutina za kontrolo svinčnika in driver v urniku, ki v primeru dvignjenega svinčnika ne računa ravne črte, temveč izvede najprej ukaz po X in na to še po Y. To je pomembno zaradi boljše natančnosti risanja.
Primer uporabe driverja:
stanje
registra UKAZ:
x | 0 | x | x | x | 0 | 0 | 0 |
BUSY=0
STOP=0
UP/DWN*=0
R/A*
<== 0
UKAZX=120
UKAZY=230
JSR
NALOZI
pokličemo
del driverja v main, ki izračuna vse potrebne parametre in na koncu postavi
BUSY <== 1
nato
se začne izvajati del driverja v urniku in ploter nariše črto od trenutne
pozicije do točke od nje oddaljene za (120,230).
Če
bi uporabili absolutno koordinato, bi ploter narisal črto od trenutne pozicije
do koordinate, ki predstavlja absolutno točko (120,230), to je koordinata
glede na absolutno izhodišče (0,0)
Orientacija
risanja je postavljena glede na osnovni koordinatni sistem. Torej, če sta
vrednosti UKAZX in UKAZY pozitivni potem ležita v prvem kvadrantu, če je
UKAZX negativen, UKAZY pa pozitiven, potem je točka v drugem kvadrantu
itd...
Negativna
števila se predstavljajo z dvojiškim komplementom 16 bitnega števila.
Driver v main (NALOZI):
Najprej pogleda, če je slučajno postavljen BUSY bit, ker
ta indicira, da prejšnja operacija še ni končana. Ko je BUSY=0 naloži ukaz.
Če je ukaz absoluten, ga odšteje od trenutne pozicije, tako prestavi izhodišče
koordinatnega sistema v točko trenutne pozicije. Nato glede na predznak
koordinat določi smeri risanja, ki ji opotem uporablja driver v urniku.
To naredi z postavljanjem določenih bitov v spremenkljivki SMER. Nato izvede
računanje koeficientov K, K1, itd ... Poseben primer je, ko je ena od koordinat
enaka 0. Na koncu postavi BUSY in konča. V tem trenutku stopi v akcijo
driver v urniku, ki je ves čas dotlej samo preverjal BUSY in vsakič takoj
končal.
Driver v urniku (PLOT):
Najprej pogleda STOP bit, in če je ta postavljen takoj
postavi BUSY=0 in konča. Če ne, potem testira BUSY in če je postavljen
(z funkcijo NALOZI), potem začne z izvajanjem, če ne pa konča. Najprej
preveri če je ena od koordinat enaka nič, tedaj pač ni potrebno komplicirati.
Nariše toliko korakov v tisti smeri. Če sta obe koordinati različni od
nič, tedaj glede na Dx in Dy spremenljivki nariše toliko posebej v X (Dx
korakov) in posebej v Y (Dy korakov) smeri. DX in DY se zmanjšujeta in
ko sta enaki 0 je narisal eno stopnico. Nato se mora glede na koeficiente
K, K1, ... odločiti ali bo narisal dodatek (to je 1 korak) ali ne, in v
kateri smeri, glede na vrednost BASEX, ki pove, katera ciljna koordinata
je večja (DESX ali DESY). Nato se z K določita nova Dx in Dy (Dy = K*Dx
ali obratno, glede na BASEX) in cela zgodba se ponovi. Tako gre do konca.
Nizkonivojski driver za koračna motorčka: (PLOTX, PLOTY)
Krmiljenje motorčkov poteka preko PIE in sicer enega na
spodnjih 4 bitih in enega na zgornjih 4 bitih porta B. Tako je potrebno
voditi ločeno stanje bitov za izhode motorčkov v spremenljivkah MOTX in
MOTY. Začetno stanje MOTX in MOTY je 00110011.
Potem se pa lokacijo glede na smer vrtenja motorčka rotira
levo ali desno. Treba je detektirati prenos in ga upoštevati, da se struktura
ne podre (00110011 -> 10011001 -> 11001100 itd...). Ob vsaki spremembi
se vrednost prenese na PIA izhod B in sicer se maskira tako, da se spremenijo
samo pravi štirje biti, glede na to kateri motorček se vrti.
Ob vsakem koraku se spremeni vrednost Xt ali Yt, ki določata trenutno koordinato položaja svinčnika.
Avtor:
Marko Jankovec
24. Marec 1999