Vezérlés
az LPT - porton Alfától Omegáig. IV.
Az előző részben megismerkedtünk az egyszerű hardverünk
megsokszorozásával, illetve kis hardveres ízelítőt kaptunk a portra
kapcsolható legegyszerűbb kijelzőkről. Természetesen ez
korántsem jelenti azt, hogy optoelektronikai alkalmazásaink végére értünk
volna, azonban jelenleg az alapismeretek stabil elsajátítása a cél, így nagyobb
sebességgel haladhatunk majd előre. Az „omega” felé vezető utunk ezen
állomása a működtető programokra mutat be néhány példát.
Minden hardveres
legnagyobb öröme, ha a kínkeservvel összerakott szerkezet élesztését megkezdi.
Ezt a szót a szakma az orvostudománytól vette át, s arra utal, amikor frissen
összerakott berendezésünket először bekapcsoljuk, vagyis életet lehelünk a
technikába. J
A konstruktőr
végre kényelmesen maga elé rakja a szerkezetet, csatlakoztatja a számítógéphez,
bekapcsolja azt, majd nekilát az első működtető program
megírásához. Miközben a kívülálló misztikus kábeldzsungelt lát, a hardveres
számára csodálatos a formálódó anyag „szépsége” az ember keze között. Most ezt
a csodát élhetjük át, első „igazi” hardverünkkel!
Sávkijelzőnk programozása:
Először készítsünk
egy olyan programot, amivel kényelmesen küldhetünk ki számokat az adatportra,
mert így az egyes ötleteinket azonnal tudjuk tesztelni:
10 input a:if a<-1 or a>255 then 10: REM
Szabálytalan adatot nem fogadunk el.
20 if a= -1 then end: REM
Ha mínusz egyet adunk meg, akkor kilépünk.
30 out &H278,a:out &H378,a: out &H3BC,a: REM Minden létező LPT-re kiküldjük.
40 goto 10: REM
Kéri a következő adatot.
Program
1.
Ez funkciójában
megegyezik a DEBUG esetén megismert direkt módszerrel, csak kényelmesebb és
gyorsabb. Próbáljunk is ki vele rögtön pár jellegzetes kombinációt:
1., Sorban „lépkednek” a
fények: 1,2,4,8,16,32,64,128
2., Fésűfogszerű
mintázat váltakoztatása oda-vissza: 170,85,170,185….
3., Kettő pont egyszerre
lépked: 3,6,12,24,48,96,192
Példa1.
A példákat próbálgatva
megfigyelhetjük a bináris logika jellegzetes működését. Még egy
számítástechnikai alapfokú tanfolyamon se lehet „megúszni” a bináris
számrendszerrel, illetve a logikai operátorokkal való ismerkedést.
(AND,OR,XOR,NOT,NAND,NOR. Nézzünk utána egy alapkönyvben, ha bizonytalanok
lennénk!) való műveletvégzést. Oka egyszerű: így működik
számítógépünk. J A hardverprogramozó ezt
tehát végképp nem kerülheti ki. Későbbi programpéldák jól demonstrálják,
hogy milyen hihetetlen programozási munkát, illetve gépies adatbevitelt lehet
megspórolni, ha az alapvető logikai függvényekkel, illetve alkalmazásukkal
tisztában vagyunk. Ennek tükrében vizsgáljuk meg a fenti számsorokat kicsit
közelebbről:
Az első példában
nem teszünk mást, mint kettő hatványait állítjuk be sorban. Nem csoda
tehát, ha a fénysávunk, - vagyis a bináris kijelzőnk - mindig egyetlen
aktív bitet jelez növekvő sorrendben, vagyis egy fénypont „végigfut”.
(Fordított sorrend: irányváltás)
A második példában a
digitálistechnika két kedvencével, az 10101010b (AA hexa, vagyis 170
decimálisan) illetve az 01010101b (55 hexa, vagy 85 decimálisan) mintázatokkal
ismerkedünk.
Egyrészt igen
látványosak a fésűszerűen egymásba ugró fények. Azonban több ennél:
remek tesztelési minták a hardverelemek ellenőrzésére. Ugyanis az
„összeragadt”, (zárlatos) illetve valamerre kiakadt bitek e két kombináció
egyszeri váltásával hatékonyan felderíthetők. Ki gondolta volna? J Jegyezzük hát meg
alaposan! Jól jöhet majd a fejlesztéseink alatt, ha tesztelni kell
vezetékkötegek között áttekinthetetlenül megbúvó, kusza áramköreinket, nincs –e
zárlat, vagy érintkezési hiba, esetleg elkötés. A módszert előszeretettel
alkalmazzák még pl. hálózatoknál, soros átvitel szinkronizálására is.
A harmadik példa még
izgalmasabb: itt a cél, hogy mindig két szomszédos pont világítson, vagyis két
bit legyen egymás mellett logikai egy, amíg az összes többi nulla!
Ez is jól mutat.
Azonban túl ezen, tovább tanulmányozhatjuk a kettes számrendszer sajátosságát.
Vagyis a szükséges bekapcsolni kívánt biteket külön – külön kettő N-edik
hatványa szerint felírjuk, majd összeadjuk. Így is lehet egyszerre több bitet
bekapcsolni, de itt ezzel egyenértékű lesz -végeredményét tekintve- a
logikai OR művelet. (Látunk hamarosan mindkét megoldásra példát!)
Általában elmondható, hogy ott ahol gép számol, egyértelműen az OR gyorsabb,
rövidebb, áttekinthetőbb kódot eredményez. Viszont ahol ember számol,
zömmel nem bináris számrendszerben történik. Tehát összeadni könnyebb, gyorsabb
fejben. Az OR mellett ráadásul nem kell foglalkoznunk a túlcsordulások
kezelésével, mivel csak másik számértékkel, mint „maszkmintával” megadott, 1-es
értékű bitek kapcsolódnak be. Összeadás esetén ki vagyunk szolgáltatva a
programnyelv sajátosságainak, vagyis tudnunk kell, mikor várható túlcsordulás,
illetve milyen a számábrázolás. Pl. C
nyelv esetén nem sokat kell pepecselni bájtos, karakteres változók esetén, ott
a nyelv „leharapja” a túlcsordulást és kész. A PASCAL már finnyásabb, ott a
fordító beállításától függően a figyelmeztetés letiltható, de alapesetben
panaszáradat fogadhat fordítás, futás közben. BASIC esetén is típustól függ, mi
fog történni, de a nyelv rugalmasan szokta lekezelni ezeket a bajokat.(„Sunyi”
módon, a háttérben konvertálgat, mi meg elsőre nem értjük, mi lehet a
bibi... J) Vagyis nem árt mindkét módszert alaposan begyakorolni,
s megtanulni a megoldásokat szinte folyamatosan „olvasni” a kódban. A
programjainkban mindkettő bőven, illetve vegyesen fog
előfordulni. Nem azért, mert itt-ott logikusabban, egyszerűbben nem
lehetne megcsinálni ,hanem azért, hogy a gyakorlást, tanulást segítse. Ha
gondolkodunk, s magunk megyünk végig valamin, az sokkal többet ér, mint a világ
legeslegjobb szakkönyve.
Ha ezeket az
összefüggéseket tisztán értjük, akkor a következő programpéldák se fognak
nagy meglepetést okozni:
5 CLS
10 PRINT"Jobbrol balra fut vegig..."
11 FOR C=0 TO 7:A=2^C
12 OUT &H278,A:OUT &H378,A: OUT &H3BC,A
13 SOUND 15000,1:NEXT
20 PRINT"Balrol jobbra fut vegig..."
21 FOR C=0 TO 7:A=2^(7-C)
22 OUT &H278,A:OUT &H378,A: OUT &H3BC,A
23 SOUND 15000,1:NEXT
30 PRINT"Kozepre ossze, majd szet..."
31 FOR C=0 TO 7:A=2^(7-C) XOR 2^C
32 OUT &H278,A:OUT &H378,A: OUT &H3BC,A
33 SOUND 15000,1:NEXT
40 PRINT"Inverz balra..."
41 FOR C=0 TO 7:A=2^C XOR 255
42 OUT &H278,A:OUT &H378,A: OUT &H3BC,A
43 SOUND 15000,1:NEXT
50 PRINT"Inverz jobbra..."
51 FOR C=0 TO 7:A=2^(7-C) XOR 255
52 OUT &H278,A:OUT &H378,A: OUT &H3BC,A
53 SOUND 15000,1:NEXT
60 PRINT"SHIFT jobbra, folyamatos
1-utantoltessel..."
61 A=0:FOR C=0 TO 7:A=A+2^(7-C)
62 OUT &H278,A:OUT &H378,A: OUT &H3BC,A
63 SOUND 15000,1:NEXT
70 PRINT"SHIFT balra, folyamatos
1-utantoltessel..."
71 A=0:FOR C=0 TO 7:A=A+2^C
72 OUT &H278,A:OUT &H378,A: OUT &H3BC,A
73 SOUND 15000,1:NEXT
80 PRINT"Ketpontos SHIFT balra, a kifutott pontok
visszaforgatasaval..."
81 FOR K=1 TO 254:LOCATE 10,1:PRINT "A forgatott
bitkombinacio:";K
82 A=K:FOR C=1 TO 32:OUT &H278,A:OUT &H378,A: OUT
&H3BC,A
83 B=(A*2 AND 256)/256
84 A=(A*2 AND 255)+B:SOUND 15000,1:NEXT:NEXT
90 PRINT"Ketpontos SHIFT jobbra, a kifutott pontok
visszaforgatasaval..."
91 FOR K=1 TO 254:LOCATE 15,1:PRINT "A forgatott
bitkombinacio:";K
92 A=K:FOR C=1 TO 32:OUT &H278,A:OUT &H378,A: OUT
&H3BC,A
93 A=A/2:IF INT(A)<>A THEN A=INT(A) OR 128
94 SOUND 15000,1:NEXT:NEXT
100 LOCATE 21,1:PRINT"Veletlenszeruen egyetlen pont
villogtatasa..."
101 A=0:FOR C=0 TO 100:A=2^INT(RND*8)
102 OUT &H278,A:OUT &H378,A: OUT &H3BC,A
103 SOUND 15000,1:NEXT
1000 A=0:OUT &H278,A:OUT &H378,A: OUT &H3BC,A
Program2
Az, aki egyben
lefuttatja a teljes programot, egy kb. 5 percig tartó, nem ismétlődő,
változatos fényorgiát láthat. Gyakorlatilag szinte minden trükk megtalálható a
példákban, amit csak a villogókkal, futófényekkel el szoktak követni. J
Rutinosabb
programozóknak azonnal szemet szúr, hogy a példaprogram nem strukturált, sok
redundáns, felesleges részt tartalmaz. Azonban így az egyes, önálló
részegységek szépen, a keretek jelöléseinek megfelelően
elkülöníthetők, önálló programként futtathatók, vagy éppen az egyes
modulok sorrendje ízlés szerint csereberélhető. A program a BASIC nyelv
sajátságaira épít kifejezetten. Pascalban, C-ben számos bitforgató,
léptető, illetve közvetlen bitkezelési lehetőség van, amiket itt most
nem alkalmazunk, de a szemfüles programozó természetesen azonnal átültetheti a
saját nyelvére.
Az egyszerűség
ellenére számos, magyarázatot igénylő „praktikát”, - vagyis
„hardverközeli” fogást - használtam fel benne. Tekintsük át ezeket röviden:
10-13, illetve 20-23
sorok: Egy szem fénypont lépked jobbra, illetve balra. A portra kettőnek a
ciklusváltozó értékére emelt hatványát írjuk ki. (Pontosabban mindhárom adatportra… A technika ismerős lesz a többi
példánál. A megoldás általában hasznos. Hiszen ahány gép, annyi helyre teszik
azt az egy szem LPT portot. Kettő, vagy több port egy gépben ritkán fordul
elő úgy, hogy mindkettőn aktív periféria is legyen. Ráadásul e
címeken más eszköz nem szokott lenni. Vagyis ettől az eljárástól csak
akkor érdemes eltérni, ha a gépben több portot kívánunk egyszerre használni,
vagy programunkat másoknak is írjuk, ahol programunkkal kellemetlenségeket
okozhatnánk. J)
A példára visszatérve:
egyszerű, de látványos effektus. A fénytechnikán kívül alkalmazzák a
léptetéses vezérlést elektronikus kommutációjú motorok vezérlésére a
gyakorlatban. Ezek pl. floppy-k, HDD-k, videofejek forgatómotorjaiban
gyakoriak. Ha később ilyeneket is szeretnénk vezérelni, akkor érdemes
emlékezni rá.
A 30-33 sorok érdekes
kis programrészt takarnak. Ez a híres „Knight Rider effektussorozat” egyik
népszerű tagja, vagyis két szélről megindul egy-egy pont középre, s
amikor a két fény találkozik, akkor visszahúzódik. A „2^(7-C) XOR 2^C” rész a
lelke programnak. A XOR logikai
műveletet úgy is fel lehet fogni, hogy az első paraméterben azokat a
biteket fordítja ellentettjére, ahol a második paraméterben az azonos
helyiértékű bitek 1-et képviselnek. Vagyis, ha pl. egy kijelzőnél
szeretnénk a kijelzett képet inverzre fordítani, akkor csupa egyes kódú
maszkkal (255-el) kell „át-XOR-olni”. Ha emlékszünk az előző cikkben
a közös anódú, illetve katódú kijelző fordított vezérlésére, akkor adódik
a pofonegyszerű megoldás: Csak az egyik kódkombinációit kell
megterveznünk, a másikat egyszerű XOR 255 művelettel számíthatjuk is!
Fontos megjegyezni, hogy ez egy általános megoldás. Helyette a legtöbb nyelvben
van egy célutasítás a NOT, ami ugyanezt teszi, csak elegánsabban. Azonban a
számábrázolás miatt (erre most nem kívánok kitérni) ennek jóval több a
kötöttsége. Pl. BASIC-ben a „NOT 0” hatására mínusz egyet kapunk. Különféle
trükkökkel megkerülhető a probléma, pl. „NOT 0 AND 255”, ahol csak a
bennünket érdeklő biteket „kimaszkoljuk” az eredményből. Azonban
akkor már ott a jó öreg XOR. J
Ráadásul
univerzálisabban alkalmazható, mint ez a példa is mutatja. Itt vesszük a
két szemben lévő elempárt, s XOR
után a kívánt eredményt kapjuk. A sors iróniája, hogy ebben az esetben a
XOR akár egy egyszerű összeadással, vagy akár OR művelettel is
helyettesíthető. Más okból, de itt (speciális eset, mert szimmetrikus a
bitminta!) ugyanazt a végeredményt adja mindegyik. Érdemes
fejben átgondolni, mi is történik a ciklus egyes lépései után mindhárom
variációnál, s ekkor rögtön belátjuk: az állítás valós.
A 40-43, 50-53 sorok
már a fentiekre építenek, az első példában látható lépkedést „sötétre”
fordítjuk át, több magyarázat már nem szükséges.
A 60-63, illetve 70-73
soroknál egy fénysáv úszik elénk balról, illetve jobbról. Voltaképpen nem
teszünk mást, mint a fénypontnál a részeredményeket tároljuk és az új értékhez
hozzáadjuk. Emlékeztetőül: természetesen a logikai OR művelet szintén
alkalmazható az összeadás helyett. Itt csak ízlés kérdése, de ASM program, vagy
sebességkritikus alkalmazás esetén természetesen az OR a jobb, mivel gyorsabban
hajtja végre a processzor, illetve rövidebb kódot eredményez. Egy hardveres
programozónak ezeket a tanácsokat érdemes megszívlelnie.
Talán felesleges is
megemlíteni: „Knight Rider” effektusaink hiányzó két darabját tisztelhetjük
algoritmusunkban. J
80-84, illetve 90-94
sorok: Itt is a bitek léptetésével operálunk, azonban a széleken kihullott
biteket újrahasznosítjuk úgy, hogy a túloldalon visszavezetjük. Vagyis egy
végtelen körgyűrűvé alakítottuk a léptetést. Gyakori, hogy a balra
léptetést kettes számrendszerben kettővel való szorzásra, (vagy önmagához
való hozzáadásra) a jobbra léptetést pedig felezésre használunk. Ez megint csak
a 2-es számrendszer sajátságából adódik. Mivel a standard BASIC nem tartalmaz
léptetési utasítást - mint a Pascal, vagy a C nyelv -, ezért mi a fenti
összefüggést megfordítva alkalmazzuk: A ”B=(A*2 AND 256)/256” és „A=(A*2 AND 255)+B” részek ezt intelligensen teszik, mert a túlcsordulást is
figyelembe veszik. Az „A” változó 2-vel szorzásánál, megeshet, hogy túlmegyünk
a 255-ös felső határon. Az AND 255 egyszerűen „leharapja”, vagyis
„kimaszkolja” a kilógó biteket. Ám ekkor még a túlcsordulást nem kezeltük le.
Végezhetnénk feltételvizsgálatot is, de az nem elegáns. Helyette inkább
felvettünk egy változót, aminél azonban most a túlfutó részt hagyjuk meg. Ez
vagy nulla, vagy 256. Ha ezt elosztjuk 256-al, akkor az eredmény vagy zérus,
vagy egy lesz. Ez már gond nélkül hozzáadható, vagy logikai OR kapcsolatba
hozható az „A” változónkkal, mert az átvitel korrektül körülfordul. A
visszafelé léptetés ugyanennek a megfelelője, nincs semmi csoda benne.
Talán körülményesnek tűnik elsőre egyik-másik példabeli megoldás.
Azonban az adott nyelvben vitathatatlanul tömör, illetve hatékony. Gondoljunk
arra, hogy az összetettebb rendszerek más gondolkodásmódot igényelnek, szokjunk
hozzá ehhez! Ne lepődjünk meg tehát, ha mások programjaiban hol ilyen, hol
olyan megvalósítást találunk.
A 81/91 sorokban egy
külső ciklus lett betéve, ami a létező összes kezdőértékkel
végigzongorázik a kijelzőn. A belső ciklus se csak 8-szor fut le, hanem 4*8=32-szer, mert így minden mintázat 4-szer fog
végigszaladni a szemünk előtt. Ennyi kell a biztonságos felismeréshez az
agyunknak. Segítségként, - ha valamelyik megtetszene -, képernyőre is
kiírjuk a sorszámokat. Érdemes a két algoritmust nem felejteni, mert a
léptetések alapvető dolognak számítanak az informatika minden területén!
Hardveresek leginkább
fénypatakokhoz, motorok, relé-blokkok, robotalkatrészek programozásakor, vagy
léptetőregiszteres áramkörök építésénél futhatnak össze vele. A
mikrovezérlőknél pl. az egyik legelemibb „trükk”, amivel programtár-helyet
lehet megtakarítani, hiszen minden processzor tartalmaz (gyakran többfajta)
léptetési célutasítást.
100-103 sorok:
Véletlenszerűen felvillannak itt-ott a pontocskák. Szétszórt
fényforrásoknál ez is látványos effektus szokott lenni.
Karácsonykor a karácsonyfára
igen látványos fényfűzér varázsolható ezzel az algoritmussal.
Programbefejezésképpen
az 1000-es sor elsötétíti a kijelzőnket, ami kultúráltabbá teszi a
leállást.
Egy tipp:
A futófények érdekes
verziója a „fénypatak”, amikor általában 3 lámpacsoportot kapcsolunk egymás
után be úgy, hogy mindig csak egy legyen aktív. A 3 lámpacsoportra tucatnyi
égőt kapcsolunk, majd 1,2,3,1,2,3,1,2,3,1,2,3…… sorrendben helyezzük el az izzókat. Ez a három csoport kell ahhoz,
hogy minimum a folyamatos haladás érzetét érezzük.
Ugyanezt 4
lámpacsoporttal is el lehet játszani. Ha 17-et adunk kezdőértéknek, s a
82-84, 92-94 sorokat futtatjuk, (előtte K=17) akkor találkozunk ezzel a
látványos effekttel.
A teljes programciklus
lefutása közben is mutatja ezt, azonban a fény-kavalkádban esetleg hajlamosak
vagyunk szem elől téveszteni.
Bizonyára sok olvasónk fejében felmerül az, hogy LED-ek helyett igazi
lámpákat, lámpacsoportokat, vagy akár LED-ek százaiból álló csoportfüzéreket
kapcsolgassunk programunkkal. Türelem: később ezt is meg fogjuk ismerni. J
A példaprogramok
felépítésével kapcsolatban fontos, hogy természetesen itt is elegendő
lenne csupán a három port egyikére kiírni az adatot. A készítésnél azonban azt
szerettem volna elérni, hogy lehetőleg minden hardveren üzemeljen a
program. Lehetett volna öntesztet végezni, esetleg bekérni a bázisport címét,
de itt célszerűbbnek láttam ezt a megoldást. Természetesen adott esetben a
nem használt OUT-ok elhagyhatók, a program ezzel csak tovább
egyszerűsödik. J
Rendőrlámpa programozása:
A fényeffektusoknál már
megismertük a léptetési (SHIFT) műveleteket. Most a bájt „összeszereléssel” fogunk kissé közelebbről ismerkedni.
Egy rendőrlámpa példája éppen jó lesz a megértéshez. Itt előző
cikkünkben ígértnek megfelelően, két autó, illetve egy gyalogos forgalmat
kell szabályozni. Az is egyértelmű, hogy ez 3 önállóan működő
lámpát jelent, ahol a két autósnál 3 lámpácska, vagyis bit kell a meghajtáshoz,
a gyalogosnál pedig kettő. Ez összesen 8 bitet jelent. Tehát éppen megvalósítható
a szimuláció a fénykijelző sávunkkal, nem kell másik hardvert építenünk. (Ha esetleg valaki terepasztalt akar
készíteni modelljeihez, s megtetszik neki a vezérlés, akkor 3mm-es LED-eket,
illetve 470 ohmos ellenállásokat alkalmazva megpróbálhat kettőt rákötni
egy portkimenetre, ezt így még éppen el fogja bírni. Igaz cserébe a
fényerősség lecsökken valamelyest. Fontos, hogy minden LED-nek saját
korlátozó ellenállása legyen, de erről már volt szó korábban.)
Mint látható, elég
kényelmetlen dologgal kell szembesülnünk: egy bájtban 3 önálló eszközt kell,
kezelni, s mindhárom a másiktól függetlenül üzemel! Megtehetnénk természetesen,
hogy a hardverünket bonyolítjuk, vagyis munkába fogjuk a port eddig nem
használt, másik kimeneti regiszterét. De az akkor is csak kettő önálló
bájt lenne, nekünk pedig három eszközünk van!
Betehetnénk
egy másik nyomtatóportot a gépünkbe, de azért ez túlzás lenne. Helyette inkább
érdemes szoftveres síkra terelni a megoldást. Az életben rengeteg helyen
előforduló, tipikus probléma ez. Mert a hardver drága, mindenhova bele
kell tenni. A szoftver pedig olcsóbb, hiszen csupán egyszer kell megírnunk.
Erről azonban már volt szó az előző cikkben. Tehát alapszabály:
a működő portbiteket a lehető legjobban ki kell használnunk, ha
gazdaságos berendezéseket kívánunk létrehozni. Mivel a legtöbb berendezés
bájtos szervezésű, ezért minimum ilyen lépésekben tudjuk skálázni
eszközeinket.
Adott tehát egy
útkereszteződés, melyet rendőrlámpákkal szeretnénk irányítani. Egy
négy irányba néző, átfeszítő sodronyról belógatott lámpa látja el az
autóforgalom irányítását. A kocka alakú testen az egymással szemben lévő
lámpák azonos vezérlést kapnak. (piros, sárga, zöld típusú irányítás). A
gyalogoskereszteződések sarkán 45-fokos szögben található két lámpatest
átlósan elhelyezve, így a lámpák egyszerre két oldalról láthatók. Ezek szintén
azonos vezérlést kapnak. A kereszteződésben nem minden irányú áthaladás
engedélyezett. A sorrendet az alábbi ábrák mutatják:
|
|
|
Első gépjárműcsoport. |
Második gépjárműcsoport |
Gyalogosforgalom |
A lámpák
működési sorrendjeit magyarázó ábra. A szerző munkája.
Ehhez a következő
vezérlési ütemterv tartozik: (Időzítési adatok nélkül.)
-
1 Piros mindhárom csoport.
-
2 Első csoport sárgára vált
-
3 Első csoport zöldre vált
-
4 Első csoport sárgára vált
-
5 Első csoport pirosra vált
-
6 Második csoport sárgára vált
-
7 Második csoport zöldre vált
-
8 Második csoport sárgára vált
-
9 Második csoport pirosra vált
-
10 Gyalogos csoport zöldre vált
-
11 Gyalogos csoport zöld jelzése villogtat
-
12 Gyalogos csoport pirosra vált
-
14 Vissza az első fázishoz
Az ütemterv része a lámpák bekapcsolása. Ez általában
villogó sárga jelzéssel indul, majd egy olyan hosszúságú piros jelzés
következik, mint ami ahhoz szükséges, hogy valamennyi jármű, illetve
gyalogos biztonsággal elhagyhassa a csomópontot. Ezután a vezérlés az egyes
fázisra ugrik. Kikapcsoláskor a sorrend fordított: az egyes fázist bevárjuk, s
ezután villogó sárga jelzésre váltunk. A lámpák csakis ezután kapcsolhatóak ki!
Az időzítések változhatnak a helyi adottságoknak megfelelően, ezért
ezt a programban egyedi változók tárolják, amit a legelső sorban gyorsan
lehet módosítani:
10
CLS:IDOALAP=500:HOSSZU=IDOALAP:ROVID=HOSSZU/5:VILLOG=ROVID/2
20 LOCATE 12,30:PRINT"Inditasi sotet periodus...
";
30 A1=0:A2=0:GY=0:GOSUB 240:H=HOSSZU:GOSUB 280:REM sotet
periodus
40 GOSUB 320:REM Sargan villogtatunk 10-szer
50 A1=4:A2=4:GY=2:GOSUB 240:REM Kiuritesi periodus
60 REM 1...5 fazis:Foiranyu forgalom atengedese
70 IF KILEP=1 THEN H=HOSSZU:GOSUB 280:GOSUB 320:END
80 LOCATE 12,30:PRINT"Foforgalom ateresztese... ";
90 FOR C=0 TO 4:A1=2^(2-C):IF A1<1 THEN A1=2^(C-2)
100 GOSUB 240:H=HOSSZU:IF A1=2 THEN H=ROVID
110 GOSUB 280:NEXT
120 REM 5...9 fazis: Keresztiranyu forgalom atengedese
130 LOCATE 12,30:PRINT"Keresztforgalom
ateresztese... ";
140 FOR C=0 TO 4:A2=2^(2-C):IF A2<1 THEN A2=2^(C-2)
150 GOSUB 240:H=HOSSZU:IF A2=2 THEN H=ROVID
160 GOSUB 280:NEXT
170 REM Vegso fazis: Gyalogosok atengedese
180 LOCATE 12,30:PRINT"Gyalogosforgalom
ateresztese...";
190 GY=GY XOR 3:GOSUB 240:H=HOSSZU:GOSUB 280
200 FOR C=1 TO 6:GY=GY XOR 1:GOSUB 240:H=VILLOG:GOSUB
280:NEXT
210 GY=GY XOR 3:GOSUB 240
220 GOTO 60
240 REM Osszeszerelo, kiiro rutin A1,A2,GY valtozokat
kiteszi a portra
250 A=(A1*32)+(A2*4)+GY
260 OUT &H278,A:OUT &H378,A: OUT &H3BC,A
270 RETURN
280 REM Idozito ciklus, hasznalhato helyette:DELAY
fejlettebb valtozatoknal.
290 FOR B=H TO 1 STEP -1:FOR K=0 TO IDOALAP
300 IF INKEY$<>"" THEN KILEP=1:LOCATE
10,25:PRINT"Figyelem, rendszer leallitas alatt...";
310 NEXT:LOCATE 1,65:PRINT
"Timer:";B;:NEXT:RETURN
320 REM Sargan villogo periodus villogtato rutinja
330 LOCATE 12,30:PRINT"Sargan villogo
periodus... ";
340 A1=2:A2=2:GY=0:FOR C=1 TO 20:GOSUB 240:H=VILLOG:GOSUB
280:A1=A1 XOR 2:A2=A1:NEXT:RETURN
Program3.
Ebben a programban is
jó pár apró fogás található, amit a hardverek programozásakor a
későbbiekben is alkalmazni fogunk. Ezért érdemes alaposan átrágni a
listát, s minden apró részt megérteni. Hely hiányában itt csak a legfontosabb
részeket tekintjük át;
Az első
programsorban időzítésekkel kapcsolatos beállítások vannak. Az
időalap változtatása valamennyi időzítést együtt szabályozza. A
„HOSSZU” változó a stabil zöld, illetve piros jelzések, a „ROVID” sárgák időtartamát,
a „VILLOG” pedig a villogó zöldet állítja be.
A 30-as sorban
valamennyi lámpát kikapcsoljuk. A lámpákat 3 változó ábrázolja,
(A1,A2,GY)amelyeket a 240-es sorban lévő szubrutin összeállít egy bájtba,
s kiírja mindhárom szóba jöhető adatportra. A „bájt összeszerelés”
érdekes, gyakori trükk. A 32-es szorzással voltaképpen (25=32 ) 5
helyi értékkel toljuk az A1-es, illetve 2 helyi értékkel (24=4) az
A2-es változót balra. A GY- változó értéke az alsó két biten van, azt nem kell
mozgatni. Ezután a három változó összeadható, vagy éppen OR függvénnyel
összekapcsolható. Jelen esetben az összeadást választottam, mivel pontosan
tudható, hogy mi az értéktartománya a három változónak.
A 40-es sor a kezdeti
sárga villogtatásért felelős rutint aktiválja. Azért tettem ki
szubrutinba, mert a leállításkor ismét szükség van a funkcióra. Felesleges lett
volna ismét begépelni. J
A villogtatás „lelke”
arra épül, hogy a sárga lámpákat reprezentáló biteket bekapcsoljuk, a többit
pedig ki. Majd egy ciklusban 20-szor negáljuk a bitek értékét. Az eredmény 10
felvillanás/kialvás lesz. A negálást XOR művelettel végezzük. Mivel a
második bit kettőnek az első hatványát, azaz kettőt jelenti, a
megfelelő kód: A1=A1 XOR 2 a másik változót már
ebből is elég feltölteni, hiszen együtt kell mindkét lámpának villognia: A2=A1
Az 50-es sorban
követjük az indítási fázis előírásait, s pirosra állítunk mindent.
(Kétlámpásnál kettőt, a háromlámpásoknál pedig négyet írunk ki.)
A tényleges
működtető program lényegi része a 60-as sorban kezdődik.
Őszintén szólva, ezt a részt először másképp képzeltem el megírni.
Azonban végezetül ennél az egy ciklussal megvalósított megoldásnál maradtam. A
ciklus A1-es változót 1,2,4,2,1 értékre állítja, ráadásul a sárgát reprezentáló
2-esnél a késleltetési időt is rövidebbre veszi. Az egyszerűség
kedvéért felhasználtam két feltételes szerkezetet, de ez egy zárójeles logikai
operátorsorral is megoldható lett volna. Így viszont áttekinthetőbb a kód.
Ezeket a funkciókat a 90 és 100-as sorok végzik. A hetvenes sor érdemel itt még
említést; Ez a kilépést végzi, ha lenyomunk egy gombot. Azért így lett
megoldva, mert a leállítás is kötött. Először a darab programot be kell
fejezni, kiüríteni a csomópontot piros jelzéssel, majd sárgát villogtatni, s
csak ezután lehet leállítani a lámpákat. A kívánt célt egy segédváltozó
vizsgálatával értem el, ami a leggyakrabban aktivizált programrészben, az
időzítő rutinban ellenőrzi a lenyomott billentyűt. Ha ilyet
talál, nyugtázó üzenetet ír ki, illetve a „KILEP” változót 1-értékre állítja.
Amikor a program megfelelő helyre ér, akkor változó 1 értéke elindítja a
sárga ciklust, majd a sötétre váltást, kilépést.
A 120-as sorban a
keresztirányú forgalmat szabályozó, 2-es lámpa rutinja gyakorlatilag ugyanaz,
csak az A2-es változót állítja. Voltaképpen a két programrészt egy közös
szubrutinnal akár össze is vonható, s a változó lesz csereberélhető.
A gyalogosokat
kiszolgáló lámpa vezérlése már kicsit rafináltabb feladat. Ott ugyanis zöldre
kell váltani, villogtatni a zöldet, majd pirosra visszakapcsolni. A piros-zöld
átkapcsolást úgy oldottam meg, hogy mindkét bitet negáltam. Ez logikus, hiszen
egymásnak az inverzeként üzemelnek a lámpák. A két alsó bit egyidejű
maszkja 1+2=3, tehát XOR 3-al lehet átváltani.
A villogtatást XOR 1-el
lehet elérni, hiszen most csakis az első bitet kell átváltogatni. Így
minden XOR-nál az inverzére változik a bit értéke, vagyis ciklusba téve ezt, a
lámpa villogni fog. (Természetesen az időzítések itt is biztosítják a
korrekt villogási sebességet.)
A 220-as sorral
visszaugrunk az első fázishoz, vagyis a kilépésig a program ebben a
hurokban fut. Ezzel a főág végére is értünk.
Az időzítés
kivitelezése azonban megérdemel néhány szót. Fejlettebb BASIC esetén (pl. QB,
TB) alkalmazhattam volna pl. a DELAY utasítást, vagy itt pl. a TIMER változót. Helyette két egymásba ágyazott
ciklus működik. Így enyhe szépséghibája a megoldásnak, hogy a sebesség a
CPU órajelétől fog függeni. Aki akarja, házi feladat gyanánt írja át
gépfüggetlenre! J Kis segítség: (H a megszokott
késleltető változó.)
350 SV=TIMER*100
360 IF TIMER*100<SV+H THEN 360
Ezzel az alappal már könnyen be lehet venni a billentyűzetfigyelést
is, akinek megtetszik. J
Természetesen
a programot sokkal rövidebben is meg lehetne írni, ha az egyes állapotok
kombinációit fejben kiszámoljuk, s azokat egy tömbből sorban
elővesszük. Ekkor az ember munkája pótolja a gép számításait, amit most
elvégez helyettünk. Való igaz, hogy így is tehettünk volna. Azonban célunk nem
holmi digitális „magnetofonok” írása, hanem a port bináris programozási
logikájának mélyebb megértése. Ezt pedig a példánk nem kismértékben mozdítja
elő. Persze csak akkor, ha az ember veszi a fáradtságot, s végigmegy
rajta.
Vannak azonban esetek,
amikor eleve nincs más megoldás, mint az előre letárolt táblázatok
alkalmazása!
Hétszegmenses kijelző programozása:
Eddigi
programpéldáinkban logikus, számítással kalkulálható adatokat írtunk ki a
portunkra. Vannak azonban olyan esetek, amikor megállapodáson alapuló, nem
logikus konvenciók írják elő, milyen jelkombinációkat kell kiküldenünk.
Ilyen tipikus eset, ha számokat, illetve karaktereket kell megjeleníteni
valamilyen szegmensekből, (pálcikákból) vagy pontokból álló eszközön. Itt
nem segítenek a logikai operátorokkal való praktikák, kénytelenek vagyunk egy
fordító táblázatot alkalmazni, s abban a kódoláskor előre megadni a
számokat:
10 DIM T(10):DATA 63,6,91,79,102,109,125,39,127,111
20 FOR C=0 TO 9:READ T(C):NEXT
30 INPUT SZ:A=T(SZ)
40 OUT &H278,A:OUT &H378,A: OUT &H3BC,A:GOTO 30
Ez a kis program életre kelti az előző számban
ismertetett hétszegmenses kijelző hardverünket. Bekér egy számot 0…9
között, s kiírja a kijelzőnkre. A kijelző ez esetben közös katódú,
bekötése: B0-a; B1-b;B2-c;B3-d;B4-e;B5-f;B6-g;B7-dp. (Vagyis az előző
számban ajánlottnak megfelelően.) Fontos, ha közös anódú kijelzőnk
lenne, akkor „A” változó étékét negálni kellene, s azt kiírni a portra! (A=A XOR 255)
A működés
önmagáért beszél: Először létrehozunk egy 10-elemű tömböt. A DATA
sorokban egymás után felsoroljuk 0…9 között sorban a bitkombinációk alapján
kiszámolt bájtokat.
A következő sorban
a DATA-ban tárolt adatokat átírjuk egy tömbbe, ahol index szerint lehet címezni
a beolvasott számjeggyel. Vagyis 0-t megadva a nulladik tömbelemet küldi a
kijelzőre, ami éppen a nullát fogja a pálcikákból kivilágítani. A program
természetesen nem tartalmaz se hibakezelést, se egyéb kényelmi funkciókat. Ezt
mindenkinek magának kell megcsinálnia. J
Ha valaki gyakorolni
szeretne, akkor álljon itt egy iskolapélda:
Egy könyvben láttam egy
olyan áramkört, ami LED-s es kijelzők tömegéből állt, s németül
kiírta a „szeretetlek” mondatot: „ICH LIEBE DICH”. Mi is meg tudjuk ezt
csinálni, hiszen egymás után ezeket a betűket kiküldhetjük a
kijelzőre. Tessék önállóan megpróbálkozni - a tanultak alapján - a
feladattal! A sikerélmény hatalmas, ugyanakkor nem bonyolult a megoldás.
Ezzel szoftveres
bevezető körutazásunk végére értünk. Ha a fenti példákon átrágtuk
magunkat, akkor végeredményben valamennyi programozási elemet elsajátítottuk
ahhoz, hogy összetettebb feladatokat is megoldhassunk már.
A következő
részekben kicsit több hardverrel fogunk megismerkedni, hiszen ez a lényeg.
Programozás-technikailag sok eszközt hasonlóan kell kezelni, mint a példákban
bemutatott kijelzőket. Hamarosan meg fogunk ismerkedni, hogyan tudunk
igazi „birkózógépet” varázsolni LPT - portunkból, vagyis felerősíteni a
gyenge, logikai jeleket, s reléket, szilárdtest kapcsolókat, motorokat
vezérelni vele, vagy 230V-os égőket, futófény sorokat, háztartási
berendezéseket irányítani, analóg feszültségeket kiadni, lemérni, esetleg magas
feszültség értékek meglétét detektálni, vagy akár egyéb, nem elektromos
mennyiségeket lemérni.
Ha ezeket az alapokat
is elsajátítjuk, akkor már könnyűszerrel tervezhetünk saját magunk is
önálló berendezéseket, melyekkel valóra válthatjuk legrejtettebb álmainkat, egy
robotot, vagy akár. a „gondolkodó” lakást, intelligens autót, stb.
A legközelebbi
részben arról lesz szó, hogy miként tudjuk megvédeni a portunkat a későbbi
kísérletek közben esetleg bekövetkező meghibásodástól, vagyis leválasztó
erősítőt építünk, s megtanulunk áramot „lopni” gépünk
tápegységéből, mert erre hamarosan szükségünk lesz.
Kis Norbert: