Micromite MKII - gyors BASIC futtató környezet PIC mikrovezérlőben. Dr. Kónya László – 2015.08.30
Programfejlesztési módszerek: A szövegszerkesztővel megírt programot forrásprogramnak hívjuk. Kétféle megoldás lehetséges, hogy a forráskódot a processzor által végrehajtható tárgykóddá (bináris kóddá) alakítsuk. Ezek: fordítás (kompilálás) vagy az értelmezés (interpretálás). Az interpretációnál az értelmező a forrásprogram minden egyes elemzett sorát néhány gépi nyelvű utasításra lefordítja, amiket azonnal a processzor végrehajt. Természetesen ilyenkor a program futtatását végző interpreternek is folyamatosan működnie kell. A kompilálás a teljes forrásszöveget bináris kóddá alakítja. Ezt már a fordítóprogramtól függetlenül végrehajtathatjuk, és egy fájlban tárolhatjuk. (« ez a végrehajtható fájl »). Mindegyik technikának vannak előnyei és hátrányai: Az interpretáció azért jó, mert ilyenkor azonnal tesztelhető a forráskód minden módosítása, és az esetleges formai hibák javítása is azonnal elvégezhető. A program futása a hibás sornál megáll. Kompilálás esetén a lefordított programunk mindig lényegesen gyorsabban fog működni, mint az interpreteres változat, mivel a számítógépnek a végrehajtás előtt nem kell minden egyes utasítást újra bináris kódra lefordítani, de minden program módosítást és javítást egy fordítási fázis követ. Micromite MKII a Microchip valamelyik PIC32MX170/470 (28,44,64, vagy 100 kivezetésű) mikrovezérlő típusába programozott Microsoft MBASIC kompatibilis interpreter, az MMBasic firmware. A BASIC interpreter a program sorait alkotó utasításait olvasva azokat értelmezi és végrehajtja. Kezeli a lebegőpontos, egész karakteres változókat, tömböket, hosszú változó neveket, miközben a beírt forrásprogram mindig szerkeszthető marad. A Micromite MkII funkciói a következők: Beépített BASIC interpreter: Gyors 32 bites CPU 256K flash és 64k RAM memóriájú PIC mikrovezérlőben van elhelyezve egy gyors BASIC interpreter. 60KB, nem felejtő flash memória van fenntartva a programoknak, 52KB RAM áll rendelkezésre a BASIC változók, tömbök, pufferek, stb. tárolására. Ez akár több mint 2500 soros BASIC programok tárolására is alkalmas. A BASIC interpreter 32 bites lebegőpontos, 64-bites egész és sztring változókat fogad el. Támogatja a hosszú változónevek és több dimenziós tömb struktúrák használatát. 1
19/33 input / output láb áll rendelkezésre az MM28/MM44 modulokban. Ezek egymástól függetlenül konfigurálhatók digitális bemenetnek vagy kimenetnek, analóg bemenetnek, valamint frekvencia- vagy időmérési és számítási célokra. Közülük tíz láb analóg feszültség mérésére is használható, hét port láb 5V toleráns. A tok programozása egy soros, TTL feszültség szintű, alapértelmezés: 38.400 baud sebességű, vonalon történik, amit konzolnak nevezünk. Automatikus programfuttatás: Miután a programot megírtuk, a Micromite képes automatikusan futtatni a programot bekapcsoláskor, felhasználói beavatkozás nélkül. Teljes képernyős szerkesztő használatát is támogatja az interpreter, ami számos fejlett funkcióval rendelkezik, mint például a keresés és a másolás, kivágás és beillesztés vágólap segítségével. Egyszerű adatátvitel segítségével a BASIC program egy másik számítógépről (Windows, Mac vagy Linux) XMODEM protokoll használatával betölthető vagy kimenthető. Input / Output funkciók MMBasic képes impulzusok hardveres, háttérben történő előállítására a BASIC program futása közben. A belső időzítő áramkör 1 ezred másodperc felbontásban állítható időzítő megszakítási lehetőséget biztosít. Nyolc lábon beállítható digitális állapotváltozásoktól függő megszakítás. Több elterjedt kommunikációs protokollt támogat: I2C, aszinkron soros, RS232, IEEE 485, SPI és az 1 vezetékes átvitelt. Számos érzékelő típussal képes kommunikálni (Hőmérséklet, páratartalom, gyorsulás, stb.). Beépített perifériakezelők: A Micromite beépített meghajtó programokat (drivereket) tartalmaz, közvetlen parancsokkal kezelhetők az infravörös távirányítók, a DS18B20 hőmérséklet-érzékelők, LCD kijelző modulok. Analóg kimenetként legfeljebb öt PWM vagy szervo használható, hang generálási, mechanikus vezérlési célokra. Az MMBasic támogatja a CPU órajel frekvencia változtatását Fogyasztás: a CPU BASIC programból alvó állapotba tehető, ilyenkor az áramfelvétel mindössze 90uA. Alvó állapotban az összes változó értéke megmarad. Watchdog funkció is rendelkezésre áll, ez ellenőrzi a futó programot, és arra lehet használni, hogy újraindítsa a processzort, ha a program hibás állapotba, vagy végtelenhurokba kerül. Kódvédelem: A futó program védhető egy PIN számkóddal, amely megakadályozza, hogy bárki listázza vagy módosítsa a programot, vagy megváltoztassa bármilyen jellemzőjét. Működéséhez 2.3-3.6 V feszültség szükséges (két ceruzaelem), áramfelvétele 631mA között változhat.
Micromite használata PIC mikrovezérlőkkel A Micromite MkII MMBasic interpreter 32 bites PIC mikrovezérlőkön képes működni, annak 28 lábú és 44 lábú változatain is. A használható típusok: 2
PIC32MX170F256B-50I / SP Órajel: 48MHz. PIC32MX170F256B-50I / SO mint előbbi, de felületszerelt SOIC tok. PIC32MX170F256B-I / SP Órajel: 40MHz. PIC32MX170F256B-I / SO mint előbbi, de felületszerelt SOIC tok.
Az interpreter működik a PIC32MX270F256 sorozatú tokokkal is. Ezek beépített USB-t tartalmaznak (amit nem támogat a Micromite), és ezért két I/O láb nem használható (15. és 23. láb). Ezen kívül a 21. és 22 láb nem 5V toleráns (legföljebb csak 3.3V-ot lehet rákapcsolni). 44 lábú tokoknál a beépített USB miatt a 10. és 42. láb szintén nem használható. Az Micromite interpreter PIC tokba írásához a legjobb választás a Microchip PICkit3 programozója. Használatához telepíteni kell a Microchip MPLAB X fejlesztőben található MPLAB IPE modult, amivel már a tok a PICkit3-al már programozható. Részletes leírás: http://geoffg.net/programming_pics.html A legújabb interpreter már a lábszámtól függetlenül egyetlen hex fájl. Programozáskor a tok automatikusan kiválasztja a megfelelő részt a 28 vagy 44 lábú toknak megfelelően. Az interpreter letöltési linkje, ami a felhasználói kézikönyvet is tartalmazza: http://geoffg.net/Downloads/Micromite/Micromite_Firmware.zip A 28 lábú tok programozásához szükséges bekötések:
3
A felprogramozott tok használatakor már ezt a nagyon egyszerű alapkapcsolást kell
használni:
A 28 lábú tok kivezetései, és mellette lábon használható funkciók
4
A jelölések a következők (zárójelben a későbbiekben bemutatandó SETPIN paranccsal megadható funkciók): ANALOG: DIGITAL:
Ezeket lábak használhatók feszültség mérésére (AIN) Használható digitális I / O, például digitális bemenet (DIN), digitális kimenet (DOUT) és nyitott kollektor kimenet (OOUT). INT: Külső megszakításra lehet használni, (INTH, INTL és INTB). COUNT: Frekvencia (FIN), idő (PIN) vagy számláló (CIN) célokra használható. 5V: Ezek a lábakra TTL (5V) áramkör csatlakoztatható. Minden más I/O láb szigorúan maximum 3.3V-os. COM xxx: Ezek soros kommunikációhoz használtak I2C xxx: Ezeket használják I2C kommunikációhoz SPI xxx: Ha SPI engedélyezett, ezeket a lábakat használja az SPI I/O. PWM xxx: PWM vagy szervo output (lásd a PWM és SERVO parancsok) IR: Ezeket használja az infravörös kommunikáció (lásd az IR parancs) WAKEUP: Ezt a lábat lehet használni, hogy felébredjen a CPU az alvó módból (lásd a CPU SLEEP parancsa). A 27. és 28. lábak a föld és a táp az analóg méréseknél. Általában, ezeket a digitális földhöz, és a tápfeszültséghez csatlakoztatjuk (8 és 13-as lábak), de ha szükséges, zajmentes és pontos analóg mérés, akkor az analóg tápnak (28 láb) jól szűrtnek kell lennie. A programban a SETPIN paranccsal állítjuk be a lábak funkcióit. Például a 7. lábon mért analóg feszültség kiíratása: SETPIN 7 Ain 5
PRINT "A feszültség" PIN (7) "V" Ez a feszültség olvasás akkor ad pontos eredményt, ha a 28. láb feszültsége pontosan 3.3V. Tápfeszültség:: A toknak a működéshez 2.3V és 3.6V közötti feszültségre van szüksége. Ez a kis áramfelvétel miatt (20-30 mA) akár két AA típusú sorba kötött elem vagy akkumulátor is lehet. A működéshez szükséges egy jó minőségű tantál vagy többrétegű kerámia kondenzátor (nem elektrolitikus!) 10-47 uF közötti kapacitással, csatlakoztatva a 20-as láb és a föld közé. Ez stabilizálja a magot működtető 1.8V-os belső feszültséget. Terminal Emulátor: Az interpreterrel való kommunikációhoz, programíráshoz, szerkesztéshez és a hibakereséshez egy soros vonalon kommunikáló terminált vagy számítógépen futó terminál emulátor programot kell használni. Ennek a programnak támogatnia kell VT100 emulációt, mivel a beépített szerkesztő ezt tételezi fel. Windows alatt ez az ajánlott program a Tera Term. Ez egy jó VT100 emulátor, és jól működik vele az XMODEM protokoll is, amely segítségével programokat tudunk fel és letölteni a számítógépről/re. A Tera Term letölthető: http://ttssh2.sourceforge.jp/ Soros kapcsolat: A terminál ezen a konzol porton keresztül kommunikál a Micromite-al. Alapértelmezett beállítások: 38400 baud, 8 bit, 1 stop bit, paritás nincs. Nem a szabványos RS232 +/- 12V-os feszültségeket kell használni, hanem helyette 0-3.3V feszültségszintű jelek szükségesek. Mivel a soros port a PC-ken már elavult, ezért jobb megoldás egy USB 3.3V-os TTL soros átalakító alkalmazása, ami az USB port tápja segítségével a tok áramellátását is biztosítja. A soros átalakító a számítógépen virtuális soros port-ként jelenik meg. Számos változat mellett jó választás a Microchip megoldása:
Egy PC RS232-es soros vonalára is lehet csatlakozni a következő kapcsolással. Mivel a megoldás a TTL szinthez képest ellentétes logikai feszültségszintet szolgáltat, ezért Micromite jeleit inverz módon kell kezelni. (INV opció).
OPEN "COM1: 4800, INV" AS #1
6
Első program: Ha megfelelően csatlakoztunk, és a Micromite bejelentkezik: A „>” prompt után írjuk a billentyűzetről a parancssorba: print 1/7
Majd nyomjuk meg az Enter gombot. Ez az úgynevezett azonnali, parancssoros üzemmód, ami hasznos egy-egy parancs gyors kipróbálására. Hosszabb program megírását az EDIT szó begépelésével kezdjük:
A parancssorba írjuk: EDIT majd nyomjuk meg az ENTER billentyűt. A szerkesztő elindul, írjuk be ezt a sort: PRINT "Hello World" Nyomjuk meg az F1 gombot: Ekkor a szerkesztő menti a programot. Ha ez után begépeljük a RUN szót majd ENTER billentyű. Megjelenik a Hello World üzenet. Ismételt EDIT beírásakor a meglévő program módosítható, folytatható.
Autorun: Ha azt szeretnénk, hogy a program a tok bekapcsolásakor automatikusan fusson, akkor be kell gépelni: option autorun on utasítást. Azután a tok bekapcsolásakor a BASIC program automatikusan elindul.
7
F1 gombbal a memóriába mentve a programot, RUN parancs begépelése után a LED folyamatosan villogni fog. Ezután a terminél soros csatlakozása akár meg is szüntethető. Ha változtatni szeretnénk a programon (pl. a be és kikapcsolás idejét), akkor a program megszakítható a CTRL+C billentyűpárossal, és a program szerkeszthető. Ez a Micromite egyik nagy előnye, hogy nagyon könnyű írni, és módosítani a programot.
Parancsok és Program Input A parancssorba begépelt parancsok azonnal végrehajtódnak. Program írása az EDIT parancs kiadása szükséges. Ennek hatására a beépített teljes képernyős szerkesztő program indul el. Amint az alábbi képen látható, a funkcióbillentyűk segítségével gyorsíthatjuk a munkát.
Szerkesztőfunkciók a keresés, a másolás, a kivágás és a beillesztés. Természetesen más szövegszerkesztővel (pl. Jegyzettömb), is megírhatjuk a programokat, azonban célszerű a TeraTerm programot használni, mert a beleépített XMODEM protokoll kezelésével lehetséges a begépelt programok mentése a lemezre, illetve megírt programok Micromiteba történő bevitele. Lemezre mentéskor először a TeraTerm-et konzolként használva adjuk ki a teljes programot kilistázó LIST ALL parancsot, majd írjuk be utána a xmodem s parancsot: list all xmodem s Nyissuk meg a Teraterm programban a File>Transfer>XMODEM>Receive… menüpontot, a lenyíló ablakban adjuk meg a mentendő fájl helyét, a nevét és végül mentsük el a programot. 8
Program betöltésének a menete hasonló. Először a TeraTerm-et konzolként használva adjuk ki az esetleg a tokban bennmaradt programot törlő NEW parancsot, majd írjuk be utána a xmodem r parancsot: new xmodem r Nyissuk meg a Teraterm-ben: File>Transfer>XMODEM>Send… menüpontot, és a lenyíló ablakba tallózzuk be a betöltendő fájlt (hely és név). Enter lenyomása után a fájl betöltődik. A programok írásához és a hibakereséshez egy kényelmesebb módszer az MMEdit program használata. Ez egy olyan program, amely egyaránt fut Windows vagy Linux alatt. Ez lehetővé teszi, hogy módosítsuk a programot a számítógépen, majd átvigyük a Micromite-ba egyetlen egérkattintással. Ez a program ingyenesen letölthető: http://www.c-com.com.au/MMedit.htm. A program minden esetben a PIC32 mikrokontroller flash memóriájába kerül, ami azt jelenti, hogy soha nem fog elveszni, még ha a feszültség váratlanul megszűnik, vagy a processzor újraindul. Programok felépítése, programsorok: A klasszikus BASIC-nél megszokott módon a sorok elején használhatunk sorszámokat, de ez nem kötelező. A programok sorainak a felépítése a következő: [Sorszám][címke:]parancsoperandusok[:parancsoperandusok] … A címkét, vagy sorszámot lehet használni egy adott programsor megjelölésére. A címkével kapcsolatosan ugyanazok az előírások (hossz, karakterkészlet, stb.), mint a változók neveinél, de ez nem lehet azonos parancs elnevezéssel. A címkére helyének a megadásakor használunk, de a rá való hivatkozáskor már nem használunk kettőspontot. Sorszámos hivatkozás esetén sem használunk kettőspontot. Például: GOTO xxxx - - xxxx: print "Ideugrottunk" Több parancs is írható egy sorba, amiket kettősponttal kell elválasztani egymástól. például INPUT A: PRINT B Programok futtatása: A program futtatása a RUN paranccsal indítható. A programot bármikor meg lehet szakítani a CTRL+C billentyűkombinációval. A program listázható a LIST paranccsal. Ez kiírja a képernyőre a programot 24 soronként felfüggesztve. A teljes program törlése a NEW paranccsal lehetséges. 9
Ha bekapcsoltuk az „Autorun” funkciót (OPTION AUTORUN ON), akkor a Micromite bekapcsoláskor automatikusan elindítja és futtatja a programot. Beállítási opciók: Az OPTION kulcsszó után számos beállítási lehetőséget adhatunk meg, ezek a kézikönyvben találhatók. Például a soros adatátviteli sebesség módosítása: OPTION BAUDRATE 9600 Billentyűparancsok: A működést vezérlő parancsok megadása gyorsítható funkcióbillentyűkkel. Ezek a gyorsbillentyűk: F2 RUN F3 LIST F4 EDIT F10 automatikus mentés F11 XMODEM VÉTEL F12 XMODEM SEND A gomb megnyomásával a hozzátartozó szöveg a parancssorba íródik és végrehajtódik.
Micromite speciális tulajdonságai Mentett változók: A Micromite A RAM-ban tárolt változóit flash memóriába tudja írni kikapcsolás előtt, hogy bekapcsoláskor ismét felhasználhassa őket. A VAR SAVE parancs utáni változókat a flash memóriának egy 2 kbájt méretű területen tárolja, amiről bekapcsoláskor a változók értékei visszatölthetők a VAR RESTORE paranccsal. Túl gyakori mentésre nem szabad használni, mert a flash tároló írási száma korlátozott. PIC32 mikrokontrollereknél ez a szám több mint 20.000 írás/törlés. Ha nagyon gyakori mentés szükséges, akkor egy valós idejű óra IC-t (RTC) érdemes használni. Az RTC SETREG és RTC GETREG parancsokkal az adatokat az RTC akkumulátorral védett RAM memóriájában tudjuk eltárolni illetve onnan elővenni. (Részletek: RTC parancs). CPU sebesség állítás: A CPU paranccsal futás közben állítható a processzor órajele. Alapértelmezésben ez 40MHz, de a sebesség módosítható, amivel csökkenthető a tok áramfelvétele. (48MHz > 31mA, 40MHz > 26mA, … 5MHz > 6mA) Amikor az órajel frekvenciája változik, ez nincs hatással a soros port, a belső órák és időzítők sebességére. A PWM, SPI és I2C sebessége a CPU órajelével arányosan változni fog. CPU Sleep: A CPU SLEEP paranccsal lehet a processzort aludni küldeni, adott másodpercre, a WakeUp lábra adott jelre ébreszteni. Alvás közben az aktuális áram 90-100mikroA. 10
CPU SLEEP x parancs x másodpercre altatja a tokot. Ez akkor jó, ha időközönként kell egy programot futtatni (pl. leolvasni egy érzékelő állapotát). Természetesen ezt használva az átlagos áramfelvétel kicsi lesz, kímélve a telep élettartamát. Ha az x időt nem adjuk meg akkor a parancs automatikusan konfigurálja az ébresztési lábat digitális bemenetként, és állapotváltáskor ébreszti a tokot. Watchdog Timer: A fő felhasználási területe a Micromite-nak vezérlőként történő alkalmazás van, mint egy beépített vezérlőt. Mivel az Autorun tulajdonság lehetővé teszi a felprogramozott működését, ezért az esetleges zavar miatti hiba miatt a program működése leállhat és kilépne a parancssorba. Sajnos az önállóan induló alkalmazásnál már nem is kell a terminált csatlakoztatni, ezért még beavatkozni sem tudnánk. Egy másik lehetőség, hogy a program beragadt egy végtelen ciklusban valamilyen okból. Mindkét esetben a látható hatás ugyanaz lenne, vagyis a tok nem működik. Ez ellen megoldás a beépített watchdog időzítő használata. Ez egy időzítő, amely ha visszaszámolva eléri a nullát, a processzor automatikusan újraindul (ugyanaz, mintha kézzel) újraindítottuk volna. Egy automatikusan definiált változóbit MM.WATCHDOG jelzi, ha a tok automatikusan újraindult a watchdog működése miatt. Ezen tulajdonság használatához a WATCHDOG parancsot kell írni a program olyan helyére, ami ciklikusan végrehajtódik (pl. a fő program végrehajtási hurokban). A parancs végrehajtása az időzítőt maximális értékre állítja vissza, megakadályozva hogy az elérje a nullát, ami újraindulást okozna. Biztonsági PIN-kód: Néha szükséges a program titkosítása. Ez a Micromite OPTION PIN parancsával lehetséges. A parancsban megadott PIN kódot a rendszer a memóriában fixen eltárolja, és ha a Micromite visszatér a parancssorba (bármilyen okból) a felhasználónak be kell gépelnie a PIN-kódot. Ez nélkül a felhasználó nem kapja vissza a vezérlést. Lehetőségként vagy a helyes PIN megadás, vagy az újraindítás marad, ami után ismét be kell írni a helyes PIN kódot. A program bármilyen módosítása csak a helyes PIN megadásával lehetséges! Ha a kód elveszett, akkor a tok újbóli használata csak az MMBASIC alaphelyzetbe hozásával lehetséges, de ilyenkor a bennlévő, PIN-el védett program elveszik. Persze elvileg egy PIC32 programozóval kiolvasható a memória tartalma, és sok fáradtsággal megkereshető a PIN, ezért ez a védelem nem abszolút biztos. Soros konzol: Az OPTION BAUDRATE paranccsal soros vonal az adatátviteli sebességét lehet változtatni, ami akár 230400 bit/s is lehet. A nagyobb sebességnél a szerkesztő is gyorsabban működik. Megbízható soros kapcsolat esetén érdemes legalább 115200 bit/s sebességet használni.. Ha a program terminál felügyelete nélkül fut önállóan, akkor konzol soros vonalát akár harmadik soros port-ként lehet használni, aminek sebességét az OPTION BAUDRATE paranccsal állíthatjuk. Ilyenkor érdemes az OPTION BREAK paranccsal letiltani a BREAK 11
gombot, mert a soros vételi vonalon esetleg megjelenő CTRL+C karakter leállítaná a futó programot. További hasznos opció az OPTION CONSOLE NOECHO használata, amely letiltja a küldött karakter visszaírását, valamint OPTION CONSOLE INVERT soros jelek állapotát fordítja meg, lehetővé téve kis áramkörrel kiegészített szabványos RS232 szintű eszközök csatlakozását. Amint megváltozott a konzol átviteli sebessége, ez addig fennmarad, amíg ismét egy másik OPTION BAUDRATE paranccsal meg nem változtatjuk. Sajnos ez a változás is állandó, tehát az alapállapot visszaállítása is csak az MMBASIC alaphelyzetbe hozásával lehetséges az alábbiak szerint. MMBasic alapállapotba hozása (RESET): Az MMBasic eredeti konfigurációra történő visszaállítására két módszer közül választhatunk: 1. A tokot újraprogramozzuk a PICkit 3 programozóval, az ingyenesen letötlhető Micromite förmver segítségével. 2. A tok tápfeszültségre kapcsolása előtt annak a konzolhoz csatlakozó Tx és Rx lábait összezárjuk, és úgy kapcsoljuk a tokot feszültségre. Ezt követően várjunk pár másodpercig, majd kapcsolja ki a tokot és szüntessük meg a rövidzárat. Az MMBasic RESET után a program memória és a mentett változók (pl. Biztonsági PIN, konzol adatátviteli sebesség, stb) törlődnek és visszaállnak alapállapotba. 64 bites egészek: Micromite MkII MMBasic támogatja a 64 bites egészek használatát a lebegőpontos ábrázolás mellett. Igen nagy számokat lehet használni. akár 19 számjegyűeket (max. 9223372036854775807 hogy pontosak legyünk). Ez nagyobb pontosságú, mint a lebegőpontos ábrázolás (aminek határa mintegy 7 számjeggyel). Egész számokkal végzett műveletek valamivel gyorsabbak (mintegy 25%), mint a lebegőpontosak. Az egészek megadhatók úgy, hogy hozzájuk írjuk a "%" kiegészítést, a változó nevekhez (pl. count%, j%, stb) állandókat pedig tizedesvessző nélkül adjuk meg. Amikor használjuk minden változót, állandót egységesen így kezeljük, ha keverjük a típusokat az a pontosság rovására megy.(Lásd a "Változók definiálása és használata" az eredeti kézikönyvben). Késleltetett indítás: A Micromite kb. 4msec alatt indul el, de bizonyos esetekben szükség lehet az indítást késleltetni azért, hogy a többi kapcsolódó áramkör (például USB-soros híd) feléledjen. A megoldás az ábrán látható, adott értékekkel az indulási késleltetés 350 msec. Más értékekkel ez az indulási késleltetési idő, természetesen megváltoztatható. Egyetlen, biztonságos HEX fájl: Ha írunk egy programot a következő beállításokat is szerepeltetve: OPTION BREAK 0 OPTION AUTORUN ON 12
akkor ez a program nem állítható le, és nem megszakítható. További védelem lehet a watchdog timer és opciós PIN alkalmazása. Ha most az MPLAB IPE segítségével kiolvassuk flash memória tartalmát, és egy hex állományba elmentjük, akkor együtt van az interpreter és az azon futó program. Ez a fájl bárhova elküldhető, mint egyedi firmware, és ha a hex fájlt beírjuk egy PIC32MX170F250 tokba a PICKit3 és MPLAB IPE segítségével akkor az új tok ugyanúgy fog működni, mint az eredeti, aminek a tartalmát másoltuk.
Speciális hardver eszközök Hogy könnyebb legyen egy alkalmazás elkészítése a Micromite több gyakran használt eszköz kezelőprogramját (driverét) tartalmazza. Ezek illesztését a következő ábrákon foglaltuk össze, programozási részletekkel kiegészítve. Infravörös távirányító vevő Könnyen hozhatunk létre egy távirányítós vezérlést az IR paranccsal. Ha ez a funkció engedélyezve van, és a háttérben fut, akkor a futó program, megszakítható és az IR távirányítón lévő gombok megnyomásával. Ez működni fog bármelyik NEC vagy a Sony kompatibilis távirányítóval. Az infravörös jel vételéhez szükség van egy infravörös vevőre, amelyik a tok IR lábára (16-os láb a 28 lábú tokon) csatlakozik. (ld. ábra). Az IR vevő érzékeli az Infravörös távirányító vevő infravörös fényt, majd demodulálja, és TTL feszültségszintű jel jelenik meg az IR lábon. Az IR parancs a lábat automatikusan konfigurálja. NEC távirányítók által használt 38KHz frekvenciájú jel vételéhez a megfelelő vevők: Vishay TSOP4838, Jaycar ZD1952 és Altronics Z1611A. Sony távirányítók 40kHz-es modulációs frekvenciát használnak, de vevőt erre a frekvenciára nehéz találni. Általában a 38KHz-es vevőkkel is működni fognak. A programban használandó beállító parancs: IR dev,kulcs,megszak Itt dev egy olyan változó, amit frissítésre kerül a készülék kódjával, a kulcs is egy változó, amit a lenyomott billentyűt azonosítja. megszak a megszakítási rutin címkéje. Az IR működés a háttérben zajlik, az éppen futó programtól függetlenül. Egy példa az IR használatárar: IR DevCode, KeyCode, IR_Int ' start the IR decoder DO < body of the program > LOOP IR_Int:
’a key press has been detected 13
PRINT "Received device=" DevCode " key = " KeyCode IRETURN IR távirányítók különböző eszközöket tudnak kezelni (VCR, TV, stb.), Így a programnak általában vizsgálnia kell az eszköz kódot és ha az megfelelő, akkor reagáljon a gomb megnyomására. Sok különböző eszközök és kulcskód van így a legjobb módszer a felderítésükre az előbbiekben közölt program. Az IR funkció ugyanazon az I/O lábon van, mint a CPU-t ébresztő jel (CPU SLEEP paranccal küldtük aludni), így lehetséges, hogy egy bejövő infravörös jel ébreszti a Micromite-ot. Ez akkumulátoros táplálásnál lehet a fogyasztás csökkentésre használni. Példa: IR DevCode, KeyCode, IR_Int ’start the IR decoder DO CPU SLEEP 'kisfogyasztású szundi, amig IR jel nem jön LOOP IR_Int: 'billentyűnyomás kiszolgálása < valamit csinál a lenyomott gomb alapján > IRETURN ' újra szundi Infravörös távirányító adó A IR SEND parancs segítségével előállíthatjuk a Sony infravörös távirányító egy 12 bites jelét. Ennek célja két Micromite közötti kommunikáció, megvalósítása, de egy ilyen kódolással dolgozó Sony berendezést is vezérelhetünk vele. Megjegyzendő, hogy minden Sony eszköz megköveteli, hogy minden üzenetet háromszor küldjünk el, közte 26msec-os szünetekkel. Az áramkör szemlélteti, hogy mire van szükség. A tranzisztor szolgál az infravörös LED meghajtására. Infravörös távirányító adó A jel küldésére használt parancs: IR SEND pin, dev, cmd Pin a használt láb sorszáma, dev a készüléket kódot jelöli, cmd a billentyű kódja. Bármilyen I/ O láb használható, konfigurálni nem kell, mert az IR SEND parancs automatikusan megteszi. Ne feledje, hogy a lábon kiadott jel modulációs frekvenciája szokásos 38KHz. Hőmérséklet mérése A DS18B20() függvény adja vissza a a DS18B20 hőmérséklet érzékelő által mért hőmérsékletet. Az érzékelő 3V-5V közötti feszültséggel táplálható, több érzékelőt is lehet használni, saját felhúzó ellenállással. Példa: PRINT "Temperature:" DS18B20 (pin) 14
DS18B20 hőmérsékletérzékelő
A megadott I/O láb konfigurálása automatikus. A visszaadott értéket 0.25ºC fokos felbontásban kapjuk, pontosssága ± 0,5 ºC. Ha hiba van a mérés során, akkor a visszaadott érték pontosan 1000 lesz. A teljes méréshez szükséges idő 200mS, és a futó programot megállítja erre az időszakra. Ez azt is jelenti, hogy a megszakítások is tiltva lesznek ezen idő alatt. Azonban ezt elkerülhetjük, ha külön elindítjuk a konverziót a DS18B20 START paranccsal, és később olvassuk ki a konverzió eredményét. Például: DS18B20 START 15 < do other tasks > PRINT "Temperature: " DS18B20(15) Persze ha start és kiolvasás közti idő kisebb mint 200msec, akkor a kiolvasásnál várakozik a mérés befejezésére. Hőmérséklet és páratartalom mérése A DHT22 parancs fogja kiolvasni a hőmérséklet és a páratartalom értékét egy DHT22 hőmérséklet/páratartalom érzékelő felhaszná-lásával. Ez az érzékelő RHT03 vagy AM2302 néven is kapható. A DHT22 táplálható 3.3-5V között (5V DHT22 hőmérséklet/páratartalom ajánlott), és felhúzó ellenállást is igényel, érzékelő hosszú kábel (akár 20 méter), esetén. Rövid kábelnálaz ellenállás elhagyható, mivel a lábon van egy belső felhúzó ellenállás. Programban használt parancs:: DHT22 pin, tvar, Hvar Ahol 'pin' az I/O láb, amelyhez az érzékelő van csatlakoztatva. Bármelyik I/O láb használható, de ha a DHT22 tápellátása 5V, akkor 5V toleráns lábat kell választani. Az I/O lábat automatikusan konfigurálja MMBasic. „Tvar "egy lebegőpontos változó, amelyben a hőmérsékletet adja, „Hvar" pedig a páratartalmat. A hőmérsékletet °C fokban egy tizedes pontossággal (pl. 23.4) adja, a relatív páratartalmat pedig százalékban (pl 54.3). Ha hiba van (például az érzékelő nincs csatlakoztatva vagy a kommunikáció hibás) a parancs 1000 értéket ad vissza, mind a hőmérséklet és a páratartalom változóban. Például: DHT22 pin, temp, humid PRINT "A hőmérséklet:" temp " és a pára:" humid Az adatlap egy másodperces késleltetés javasol bekapcsolás után az első olvasás előtt, és két másodperces szünetet minden egyes mérés között. Szervo kezelése
15
Szervo egy motorral vezérelt, forgó tengely pozícióját beállító mechanikus hajtás. A Micromite egyidejűleg akár öt szervót is tud vezérelni. Normál szervónál a tengelypozíció két szöghelyzet között (általában -90 és +90 fok között) állítható. Folyamatosan forgó szervóknál a tengelypozíció, és a beállási sebesség tetszőlegesen állítható. A tengely pozícióját egy impulzus szélessége vezérli, amely minden 20 msec-ben ismétlődik. Általában az impulzus szélessége 0.8msec (a pozíció -90º) és 2.2 msec (a pozíció +90º) között változik. 1.5 msec-os impulzusszélesség a középpozíció (0 fok). Persze ezek Szervohajtás az értékek a gyártóktól is függnek. Méretüktől függően a szervók elég erősek lehetnek, és könnyű velük a mechanikus környezetet kezelni. A legtöbb szervó nagy áramú 5V-os áramforrást igényel, két erősáramú vezetékkel,(piros +5V fekete GND). A harmadik vezeték a vezérlőjel, amit a Micromite SERVO I/O lábához kell csatlakoztatni. A Micromite-nak két szervó szabályozója van, az első 3 a második 2 szervó hajtást képes vezérelni. A parancsok: SERVO 1, 1A, 1B, 1C SERVO 2, 2A, 2B Ahol 1A, 1B, 1C, 2A, 2B a kívánt impulzusszélességek msec-ben. stb van a kívánt impulzus szélessége millimásodpercben minden kimenő csatorna. A szervo lábak kiosztását a lábakat definiáló rajzon PWM1A, PWM1B, PWM1C, PWM2A, PWM2B jelöli (a PWM és SERVO parancsok szorosan összefüggnek, ugyanazokat a lábakat használják. Ha kevesebb kivezetést használunk, akkor a többi SERVO/PWM láb más célra használható.. Az impulzusszélesség megadása nagy felbontású (0,005 ms). Például, a következő utasítás középre pozícionálja a tengelyt: SERVO 1, 1.525 Természetesen a parancs végrehajtása után a Micromite háttérben folyamatosan generálja az impulzus sorozatot a háttérben. Egy másik példa: két szervó tengelye leng felváltva minden 5 másodpercben: DO SERVO 1, 0.8, 2.2 PAUSE 5000 SERVO 2, 2.2, 0.8 PAUSE 5000 LOOP Valós idejű óra illesztése A RTC GETTIME használatával mindig megkapjuk az aktuális időt a PCF8563, 16
Valós idejű óra illesztése
DS1703, DS3231 vagy DS3232 valós idejű óra tokok valamelyikének a használatával. A PCF8563 és DS1703 tokok, egy-két perc/hónap pontossággal tartják az időt, míg DS3231 és DS3232 tokok különösen precízek és pontosak: egy perc/év. Ezek chipek I2C kommunikációt használják és két I/O lábat használnak. Az ábrán egy tipikus áramkör van DS1703. tokkal. A többi toknál is hasonló a bekötés. Mielőtt a tokot használnánk, be kell állítani az idejét. Ez az RTC SETTIME paranccsal történik: RTC SETTIME év, hónap, nap, óra, perc, másodperc. Az évnél csak az utolsó két számjegyet kell megadni, és az óraformátum 24 órás. Például a következő beállítás esetén az idő: 2016 november 10 délután 4 óra. RTC SETTIME 16, 11, 10, 16, 0, 0 Az RTC GETTIME parancs kiolvassa az időt a valós idejű óra tokból és a Micromite belső órájába tölti. Normális esetben ez a parancs a program elejére kerül, hogy bekapcsoláskor a pontos idő a belső órába íródik. A Micromite saját órájának a pontosságát a PIC32 RC oszcillátorának a pontossága határozza meg, óránként akár 10 másodperc eltérés is keletkezhet emiatt. Célszerű gyakran aktualizálni, amennyiben pontos időre szükség van. Például: RTC GETTIME ' idő beállítása induláskor SETTICK 12 * 3600000, SetTime, 4 'megszakítás minden 12 órában < normal program > SetTime: ' megszakítás 12 óránként RTC GETTIME ' idő szinkronizálás IRETURN LCD kijelző Az LCD parancs megjeleníti a szöveget a normál LCD modulon minimális programozási munkával. Ez a parancs több LCD modullal képes működni amelyek KS0066, HD44780 vagy SPLC780 vezérlő tokkal vannak szerelve, és 1, 2 vagy 4 sort tartalmazhatnak. LCD kijelző illesztése A kijelző beállításához az LCD INIT parancsot kell használni: LCD INIT d4, d5, d6, d7, rs, en d4, d5, d6, d7, rs,en a Micromite lábai, amire az LCD kijelző kivezetéseit kötöttük. d0-d3 és r/w kivezetéseket földre kell kötni. 17
A Micromite bármelyik I/O lába használható, külön beállítani sem kell ezeket (az LCD INIT parancs ezt automatikusan megteszi). Karakterek megjelenítéséhez a modul használjuk az LCD parancsot: LCD sor,pos,adat$ sor a kijelzó sora (1-4), pos a soron belüli kezdőpozíció, adat$ a kiírandó szöveg Ha előtte volt valami a kijelzőn, azt felülírja. Az ábrához kapcsolódó tipikus használat: (d4-d7 2-5 lábra rs-23, en-24) LCD INIT 2, 3, 4, 5, 23, 24 LCD 1, 2, "Temperature" LCD 2, 6, STR$(DS18B20(15)) ' DS18B20 15-ös lábon
Billentyűzet interfész A billentyűzet olcsó módszer az adatok bevitelére a Micromite alapú rendszerekben. A Micromite támogatja a mátrixba kötött 4x3-as, vagy 4x4-es billentyűzetet, figyelve és dekódolva a billenytűnyomásokat. Amikor egy gombnyomást észlel, egy megszakítást generál, amivel elindított programrutin ezt feldolgozza. 4x3 és 4x4 billentyűzetre példa az Altronics S5381 és S5383 típusok (http://www.altronics.com). Billentyűzet funkció használatához a parancs: KEYPAD var, int, r1, r2, r3, r4, c1, c2, c3, c4 A var változóban adja vissza a lenyomott billentyű kódját, int a megszakítás kiszolgáló rutin kezdőcíme, r1-r4 a négy sor, c1-c4 a négy sor bekötési pontjai a tokon. c4 csak akkor használt, ha 4x4-es billentyűzetet használunk. A Micromite bármelyik I/O lába használható, külön beállítani sem kell ezeket (a KEYPAD parancs ezt automatikusan megteszi). A felismerés és dekódoláskor billentyűlenyomáskor a háttérben történik, és a program fut tovább a parancs végrehajtása utánl. Amikor egy gombnyomást észlel, a var változó Numerikus billentyűzet illesztése értéke tartalmazza a gomb sorszámát, utána történik a megszakítás kiszolgáló rutin meghívása. Például: Keypad KeyCode, KP_Int, 2, 3, 4, 5, 21, 22, 23 '4x3 kbd DO < főprogram > LOOP KP_Int: 'gombnyomás detektálva PRINT "Lenyomott gomb = " KeyCode 18
IRETURN Elforgatás érzékelő (forgókapcsoló) Az eszközzel egyszerűen állíthatók a paraméterek egy mikrokontroller projektben. Kinézetre hasonló mint egy potenciométer. A rászerelt kezelőgomb forgatásával Gray kódú jelsorozatot generál. A következő programrészlet mutatja, hogyan kell dekódolni a kapott kódot, és vele frissíteni egy változót.Az eszköznek két kimenete (RA és RB) és egy Forgásirány érzékelő GND kivezetése van. A kimenetekre az ábra szerint felhúzó ellenállásokat kell kötni. És ez a program fragmenst lehet használni, hogy dekódolja a kimenet: SETPIN 3, DIN ’ setup RB as an input SETPIN 2, INTH, RInt ' setup an interrupt when RA goes high DO < főprogram > LOOP RInt: ' Interrupt to decode the encoder output IF PIN(3) = 1 then Value = Value + 1 ' clockwise rotation ELSE Value = Value - 1 ' anti clockwise rotation ENDIF IRETURN Ez a program azt feltételezi, hogy a jeladót, a Micromite 2 és 3-lábára kötöttük, de természetesen bármelyik láb használható. "value" változó, aminek értékét módosítja a tengely elforgatása. Ez egy egyszerű kissebességű beviteli periféria, gyors motorforgás érzékelésére nem használható. Kapcsolók, érintkező bemenetek Gyakran van szükség, hogy nyomógombot vagy kapcsolót használjunk egy feladatban. Ez könnyen megvalósítható, mivel minden bemenet konfigurálható, hogy bekapcsoljunk egy belső felhúzó (kb. 100 kohm értékű) felhúzó ellenállást. Ez azt jelenti, hogy a kapcsolót a GND és a bemeneti láb közé kötjük. Ha a kapcsoló nyitott, a felhúzó ellenállás miatt lában magas szint (3.3V), zárva alacsony szint (0V) lesz. 19
A láb beállítása: SETPIN pin, DIN, PULLUP Ha olyan kapcsolónk van ami prellezik, akkor lehetséges, hogy egy gombnyomást többszöri gombnyomásként érzékelünk. Ennek a problémának a kiküszöbölésére, amit prellmentesítésnek hívunk, két megoldás lehetséges. Szoftveres prellmentesítés esetén az első érzékelt állapotváltozás után 10-100 msec múlva ismét ellenőrizzük a kapcsoló állapotát, és ezt fogadjuk el. Hardveres prellmentesítés egy az érintkezővel párhuzamosan kötött 100nF kondenzátor beiktatásával lehetséges.
Távolság mérése Egy HC-SR04 ultrahangos érzékelő és a DISTANCE() függvénnyel lehet mérni távolságot az érzékelő és a célfelület között. A mérési tartomány 3 cm-től 3 méterig terjedhet. Úgy működik, hogy küld egy ultrahang pulzust és megméri a visszaérkezési eltelt időt. A Micromite-nál használt DISTANCE függvény: d = DISTANCE(trig, echo) trig: az a láb, ahova az érzéklelő „trig” kivezetése csatlakozik, echo: az a láb, ahova az érzéklelő „echo” kivezetése csatlakozik,
Ultrahangos távolságmérő
pin csatlakozik a "trig" input az érzékelő és a visszhang a pin csatlakozik "echo" kimenete az érzékelő. 3 kivezetésű eszköznél csak egy lábat kell bekötni. A visszaadott érték a távolság centiméterben, hogy a cél, d=-1, ha a cél nem detektálható. A mérési idő legalább 60 msec, ezt ismételt méréseknél figyelembe kell venni. A láb konfigurálása automatikusan történik.
I/O lábak használata Az I/O lábak működésének a beállítására a SETPIN parancs szolgál: SETPIN pin, cfg [, option] Itt pin az adott láb sorszáma, cfg jelöli a használat módját, tulajdonságát, a kiegészítő option paraméterek megadásával. A cfg helyére a következő paramétereket írhatjuk: OFF Nem konfigurált, vagy inaktív, 20
AIN Analóg bemenet (pl. a lábon lévő feszültség mérésére) DIN Digitális bemenet Ha 'option'-t elhagyjuk, akkor a bemenet nagy ellenállású lesz. Ha 'option' helyén a PULLUP szerepel, akkor egy belső, kb. 100kohmos ellenállás kapcsolódik a lábra felhúzó ellenállásként, így a feszültsége 3.3V lesz. Ha PULLDOWN" szerepel akkor a 100 kohmos ellenállás a lábat nullára állítja lehúzó ellenállásként. FIN frekvencia bemenet 'option' használható a kapuidő megadására (az az időtartam, amíg számolja a beérkező periódikus jelfolyam hullámait). Ez 10msec és 100000msec közötti érték lehet. Ilyenkor az értéket kiolvasó PIN() függvény mindig Hz-ben adja vissza a mért frekvencia értékét, függetlenül a beállított kapuidőtől. Ha 'option' nem szerepel, a kapuidő pontosan 1 másodperc lesz. PIN Periódusidő bemenet 'option' használható az átlagolandó ciklusok számának a megadására. Ez 1 és 10000 közötti szám lehet. A PIN() függvény mindig az átlagos periódusidő átlagértékével tér vissza, ami msec-ban jelenít meg. Ha 'option' nem szerepel, akkor csak 1 ciklust mérünk. CIN Számláló bemenet A SETPIN pin,CIN parancs kiadásakor a lábhoz kapcsolódó belső számláló nullázódik, és az érzékelt impulzusszám a PIN() függvény segítségével olvasható ki. A számláló nullázása a SETPIN pin,CIN parancs ismételt kiadásával lehetséges. DOUT Digitális kimenet 'option' lehet "OC" ami azt jelenti hogy a kimenet nyitott kollektoros lesz. A PIN() függvénnyel ki is olvashatjuk egy kimenet állapotát. PIN() függvény értéke adja vissza a bemenetek állapotát, a PIN()=kifejezés használható a kimeneti érték megadására. Következzen néhány példa az előbbiekben leírtak illusztrálására. Digitális bemenetek: Ha egy így definiált lábon nagyobb a feszültség mint 2.5V az logikai 1, 0.65V alatt pedig logikai 0. Vannak lábak, amelyekre 5V-os feszültség is kapcsolható. Példa: SETPIN 23, DIN IF PIN(23) = 1 THEN PRINT ”High” Analóg bemenetek: Az ANALOG-al jelzett lábkivezetésekkel analóg feszültséget mérhetünk 0-3.3V között. A PIN () függvény adja vissza a mért feszültséget. Például: > SETPIN 23,AIN 21
> PRINT PIN (23) 2,345 > 3.3V-nál nagyobb feszültség méréséhez feszültségosztót kell használni, kis feszültségeknél pedig műveleti erősítőt. A méréskor referenciaként az analóg táp láb feszültségét használja (28-as láb a 28-lábu PICnél), és feltételezi, hogy a feszültség pontosan 3.3V. Ha ez a feszültség nem 3.3V (pl. telepes táplálás), akkor ezt korrigálhatjuk: A = (PIN(x)/3.3)*PowerV ahol "PowerV" a feszültség értéke az analóg táplábon. A Micromite tartalmaz egy belső, 1,2 V-os ( 5%), feszültségreferenciát , amely a tápfeszültségtől függetlenül állandó. Lehetséges referenciaként ezt használni ezt a PIN(0) azonosítja. Ezzel akár a telepfeszültség is megmérhető (tápmerülés figyelés): PowerV = 3.3/(PIN(0)/1.2) Az 1.2V-os referenciával már mindig pontosan mérhető a feszültség: A = PIN(x)/(PIN (0)/1.2) A feszültségmérés nagyon érzékeny az analóg táp és Ground lábak zajára. Számláló bemenetek: A mikrovezérlő lábai közül a COUNT jelzésű bemenetek alkalmasak frekvencia, idő mérésére vagy csupán impulzusok számlálására. A következő programrészlet kiírja a 15. lábra kötött periódikus jel frekvenciáját: > SETPIN 15, FIN > PRINT PIN (15) 110.374 > Ebben az esetben a frekvencia 110,374 KHz. Alapértelmezésben a frekvenciamérés kapuideje egy másodperc, ez idő alatt beérkető impulzusokat számolja meg, vagyis a mérések frissitési frekvenciája. Ha a fenti parancsnál egy harmadik paramétert is megadunk, akkor a kapuidőt 10mS és 100000mS között változtathatjuk. A PIN () függvény mindig visszatér a frekvenciát Hz-ben adja vissza, a kapuidőtől függetlenül. Például, az előző feladat 10ms –os kapuidővel: > SETPIN 15, FIN, 10 > PRINT PIN (15) 110300 > 22
Kisebb frekvenciák >10Hz esetén jobb a periodusidő mérést használni. Ilyenkor a bemenő jel két felfutó élével kapuzzuk a belső generátor mS felbontású jelét. (pl. SETPIN 15,PIN) A lábak bejövő impulzusok számlálására is alkalmasak. Amikor egy lábat így definiálunk (pl. SETPIN 15, CIN) a hozzá kapcsolódó belső számláló lenullázódik, majd lépteti a számlálót minden bejövő felfutó élű impulzus. A számláló ismét nullázható egy SETPIN paranccsal. A Micromite nagyon keskeny, akár 10 ns szélességű impulzusokat is képes számlálni. A mérhető frekvencia akár 800KHz is lehet. Digitális kimenetek: Minden I / O láb be lehet állítani digitális kimenetnek. Ez azt jelenti, hogy amikor egy kimeneti lábat 0-ra állítjuk, akkor kimenet közel 0V, 1-be állítva 3.3V. MMBasic utasításokkal: PIN (15) = 0 illetve PIN (15) = 1. A láb képes 10 mA áramot szolgáltatni, ami elég egy LED meghajtásához. A "OC" opciója a SETPIN parancsban a kimeneti láb nyitott kollektoros. lesz, ami feszültségillesztésre alkalmas. Impulzus szélesség moduláció: A PWM (Pulse Width Modulation = impulzus szélesség moduláció) parancs lehetővé teszi hogy a Micromite olyan négyszögjelet generáljon aminek a magas-alacsony állapotának aránya változtatható. Ezzel a kimeneti feszültség középértéke és a vele táplált eszköz (pl. motor) árama változtatható, ami arányos a motor fordulatszámával és nyomatékával. PWM kimenet használható szervók meghajtására, hangok generálására. Két PWM vezérlő van. Az elsőnek három kimenete van, a másodiknak kettő, azaz összesen öt PWM kimenet áll rendelkezésre. Mindkét kontroller működési frekvenciája egymástól függetlenül állítható a 20Hz-500 kHz között, míg a kitöltési tényezők mind az öt kimenetnél 0% és 100%, között állítható 0,1%-os felbontással, ha a frekvencia 25kHz alatt van. 25kHz felett a felbontást 1%-os. Micromite bekapcsolásakor, vagy a PWM OFF parancs használatakor a PWM kimenetek magas impedanciájú állapotba kerülnek. Tehát, ha azt szeretnénk, a PWM kimenet alacsony legyen alapértelmezés szerint (ez a nulla teljesítmény a legtöbb alkalmazásban), akkor használjuk egy lábra kötött ellenállás, aminek másik végét a földre kötjük. Hasonlóképpen, ha azt szeretnénk, hogy az alapértelmezett PWM állapot magas legyen ((teljes teljesítmény) akkor az ellenállás másik végét 3.3V-ra kötjük. Megszakítások: Megszakítások használatával olyan eseményeket tudunk feldolgozni, amelyek bekövetkezésének időpontja előre nem ismert. Erre példa az, amikor a felhasználó megnyom egy gombot. Bár lehet olyan programot írni, ami ciklikusan vizsgálja a gomb állapotát, de a gomb megszakítással történő figyelése sokkal egyszerűbb.
23
Beállíthatjuk, hogy a gomb megnyomása megszakítást okozzon. Ilyenkor az éppen futó program futása megszakad és egy megszakítást kiszolgáló programrész hajtódik végre, majd a program a megszakított résztől tovább folytatódik. Az INT-el jelölt lábak használhatók megszakítást kérő bemeneteknek. Összefoglalva: a SETPIN parancs segítségével lehet beállítani a megszakítást használó bemeneteket, akár többet is. Be lehet állítani, hogy a megszakítás a lábon megjelenő jel fel, vagy lefutó élére történjen. Bekövetkezésekor egy azonnali ugrás történik egy megadott címkére. Visszatérés a megszakításból a megszakítási alprogram végén lévő IRETURN utasítás végrehajtásával történik, kivéve, ha a felhasználó által megadott szubrutin használjuk (ebben az esetben END SUB vagy EXIT SUB használt). A megszakítási alprogramban a GOTO, GOSUB parancsok és más alprogramok hívása is használható. Részletesen ismertetve a parancsot: Külső események okozta megszakítás beállítására SETPIN pin, cfg, target [, option] parancs szolgál. pin az a láb, aminek állapotváltozása okozza a megszakítást, cfg kulcsszóval adhatjuk meg a változás jellegét. A Micromite-ban 8 láb használható megszakítás bemenetként. 'cfg' értékei: OFF nem konfigurált INTH megszakítás felfutó élre INTL megszakítás lefutó élre INTB megszakítás élváltozásra ‘target' a megszakítást kiszolgáló rutin kezdetét jelölő címke. A rutinból való visszatérés a végén lévő IRETURN utasítás végrehajtásával történik, kivéve, ha a felhasználó álltal definiált szubrutint használunk (akkor a kilépésre END SUB vagy EXIT SUB parancsok végrehajtásával kerül sor). Ha 'option' helyére PULLUP-ot irunk akkor a belső felhúzó ellenállás kapcsolódik a lábra, PULLDOWN esetén az elenállás a föld és a lábkiveztetés közé kerül. Ha ezeket nem szerepeltetjük, akkor a láb nagyellenállású bemenet lesz. Mivel ez a parancs a lábat digitális bemenetként konfigurálja, ezért értéke a PIN() paranccsal is kiolvasható. Ha két vagy több megszakítás történik ugyanabban az időben, a feldolgozás lábszámok sorrendjében történik. (azaz, 2-es lábnak lesz a legmagasabb prioritása).Megszakítás kiszolgálása során minden más megszakítás tiltva van. A magszakításra definált láb egyébként a megszokott módon a PIN () függvénnyel kezelhető. Megszakítások bármikor kiszolgálásra kerülnek, de az INPUT utasítások végrehajtásakor tiltva vannak. Szintén tiltottak néhány hosszú, hardverrel kapcsolatos műveleteknél (pl DS18B20 () függvény). Az MMBasic legtöbb programjánál a megszakítás kérésre adott válasz 30 mikrosec alatt megtörténik.
Időzítések 24
MMBasic számos tulajdonsága teszi lehetővé időzítést igénylő események kezelését. Van egy belső órája, aminek segítségével az aktuális dátumot és az időt a DATE$ és TIME$ függvényekkel lekérdezhetjük, illetve módosíthatjuk. A naptár nulláról indul a Micromite első bekapcsolásakor, de egy valós idejű óra IC (pl. PCF8563) segítségével, az aktuális idő mindig betölthető. A PAUSE parancs a program végrehajtását felfüggeszti a megadott számú milliszekundumig. Például egy 12ms széles impulzus létrehozása: SETPIN 4,DOUT PIN(4)=1 PAUSE 12 PIN(4)=0 a PULSE paranccsal is létrehozhatunk nagyon rövid (20 mikrosec), vagy igen hosszú, több napig tartó impulzust, ami természetesen a háttérben fut. Egy másik hasznos parancs a TIMER, amely úgy működik, mint egy stopper. Beállíthatunk bármilyen értéket (általában nullát), és felfele számol minden ezredmásodpercben. Időzítést használ a SETTICK parancs is. Ez a parancs megszakítást generál periódikusan (adott ezredmásodpercenként). A parancs: SETTICK period, target [, nbr] Négy ilyen időzítő áll rendelkezésre ('nbr' = 1, 2, 3 or 4). Ha 'nbr' nem szerepel, akkor az 1es időzítőt használjuk. A megszakítások közötti idő a ‘period’, milliszekundumban megadva. ‘target' a megszakítást kiszolgáló rutin kezdetét jelölő címke. A rutinból való visszatérés a végén lévő IRETURN utasítás végrehajtásával történik, kivéve, ha a felhasználó álltal definiált szubrutint használunk (akkor a kilépésre END SUB vagy EXIT SUB parancsok végrehajtásával kerül sor). period 1- 2147483647 mSec (kb. 24 nap) között választható. Ezek a megszakítások tilthatók, ha a period értékét nullára állítjuk. (pl. SETTICK 0, 0, 3 tiltja a 3-as számláló okozta megszakításokat. Például, a következő kódrészlet kiírja az aktuális időt és a 2. láb feszültségét másodpercenként. Ezen a folyamat alatt függetlenül futhat a fő program, amely egyéb tevékenységet végez: SETPIN 2,AIN SETTICK 1000,DOINT DO ’Fő feldolgozási programhurok LOOP DOINT: ’tick interrupt PRINT TIME$,PIN(2) IRETURN A SETTICK parancs első paramétere a gyakoriság msec-ben, míg a második a címke, ahova ugrik, ha eltelt az idő. 25
Akár négy ilyen "tick" megszakítás állítható be. Ezen megszakítások prioritása a külső megszakításokhoz képest alacsonyabb. A pontosságot a Micromite belső órája határozza meg, és a gyártási tűrések, és a hőmérséklet miatt változhat. Ez kompenzálható az OPTION CLOCKTRIM paranccsal.
Definiált szubrutinok és függvények Gyakran használt tevékenységeket tetszőleges helyen aktivizálható alprogramok (szubrutinok), és függvények alkalmazásával jobb programszervezést, és könnyű módosíthatóságot tudunk megvalósítani. A megadott szubrutin vagy függvény pusztán csak egy programrész, amely meghívható bárhonnan a programon belül. Tegyük fel például, hogy azt szeretnénk, hogy legyen egy FLASH nevű parancsunk, ami s 2es lábra kötött LED-et villogtat. Ennek megadása: SUB FLASH SETPIN 2, DOUT PIN(2) = 1 PAUSE 100 PIN(2) = 0 END SUB Ezután a programban már használhatjuk a LED-et villogtató FLASH parancsot, például: IF A <= B THEN FLASH Ha a FLASH alprogram a program memóriában van akkor a parancssorból is használható, mint minden MMBasic parancs. A FLASH-alprogram megadása bárhol lehet a programban, de általában ezeket célszerű a program elején vagy a végén elhelyezni. Ha futás közben az interpreter ilyen definícióhoz ér, akkor azt egyszerűen átlépi.
Szubrutinok paraméterei (argumentumai) A definiált szubrutinoknak lehetnek paramétereik is. Ez a következőképpen néz ki: SUB MYSUB (arg1, arg2$, arg3)
END SUB És amikor meghívjuk az alprogramot, hozzá lehet rendelni konkrét értékeket. Például: MYSUB 23, "Cat", 55 A szubrutin belsejében szerepló arg1 értéke 23, arg2$ értéke "cat", stb lesz. Az argumentumok úgy viselkednek, mint a közönséges változók, de a szubrutin végrehajtása után eltűnnek. Használhatunk a főprogramban azonos nevű változókat de ez megnehezíti hibakeresést. Amikor meghívunk egy szubrutint használhatunk a definiáltnál kevesebb paramétert: Például: MYSUB 23 26
Ebben az esetben a hiányzó értékek nulla, vagy egy üres karakterlánc fogja helyettesíteni. Például, a fenti esetben ARG2$ értéke "" és arg3 értéke nulla lesz Akkor is igaz, ha kihagyunk egy értéket a lista közepén. Például: MYSUB 23,,55 arg2$ értéke "" lesz. Ahelyett, hogy a változó nevében jeleznénk a típust, (pl. $ arg2$-ben), használhatjuk az AS meghatározást. Például: SUB MYSUB (arg1, arg2 AS STRING, arg3) IF arg2 = "Cat" THEN … END SUB
Lokális változók A szubrutinon belül is sokszor szükséges használnunk átmeneti változókat. Ezért lehet definiálni a szubrutinon belül használható belső (lokális) változókat. Ezt a LOCAL parancs segítségével végezhetjük el. Például, az előbbi FLASH szubrutinban adjuk meg paraméteként azt, hogy hányszor gyulladjon ki a LED (nbr). SUB FLASH ( nbr ) LOCAL INTEGER count SETPIN 2, DOUT FOR count = 1 TO nbr PIN(2) = 1 PAUSE 100 PIN(2) = 0 PAUSE 150 NEXT count END SUB A számláló változót (count) a szubrutinon belül definiáljuk és csak a rutinon belül használható. Persze lehet egy count változó a főprogramban is de ez más mint a szubrutin belsejében definiált és használt count változó. Ha nem deklaráljuk ezt a változót a szubrutinban és az OPTION EXPLICIT beállítás nem aktív, akkor létrejön ez a változó a szubrutinban történő használatakor és a főprogramban is látható lesz normál változóként. GOSUB MySub ... MySub: LOCAL X, Y FOR X = 1 TO ... FOR Y = 5 TO ... <statements> RETURN Az X és Y változók csak addig érvényesek, amíg el nem érjük a RETURN utasítást. 27
Függvények definiálása A függvények hasonlóak a szubrutinokhoz, azzal a kivétellel, hogy az egyetlen visszaadott értéket a függvény neve hordozza. Például, két érték esetén a nagyobbikat akarjuk visszakapni a függvény nevében: FUNCTION Max(a, b) IF a > b Max = a ELSE Max = b ENDIF END FUNCTION A függvényt így használhatjuk: SETPIN 1, AIN : SETPIN 2, AIN PRINT "The highest voltage is" Max(PIN(1), PIN(2)) A paraméterekre vonatkozó szabályok hasonlók szubrutinoknál megadottakhoz. Az egyetlen különbség az, hogy zárójelben kell megadni a paraméterek listáját, ha meghívunk egy függvényt ( szubrutinoknál ez opcionális).. Visszatérési érték megadása úgy történik, hogy a függvény neve szerepel egy értékadási utasítás bal oldalán. Ha a függvény nevét $, % vagy ! karakterrel zárjuk, akkor a függvény visszatérési értéke is ilyen típusú lesz. A típust megadhatjuk, az AS kifejezés szerepeltetésével is. Például: FUNCTION Max(a, b) AS INTEGER Ami ugyanaz: FUNCTION Max%(a, b) A függvény neve a függvényben a megadott típusú szabványos változóként működik. Egy másik példa, hogyan formázzuk az időt 24 órás kijelzés helyett AM/ PM formátumban: FUNCTION MyTime$(hours, minutes LOCAL h h = hours IF hours > 12 THEN h = h - 12 MyTime$ = STR$(h) + ":" + STR$(minutes) IF hours <= 12 THEN MyTime$ = MyTime$ + "AM" ELSE MyTime$ = MyTime$ + "PM" ENDIF END FUNCTION Mint látható, a függvény nevét (MyTime$) mint egy közönséges helyi változót használjuk a függvény belsejében.
Név szerinti paraméterátadás 28
Ha az egy egyszerű változót (nem kifejezést), használunk mint értéket, amikor hívunk egy szubrutint vagy függvényt, akkor ennek a változása a kilépés után is megmarad. Ezt hívjuk név szerinti paraméterátadásnak. Például, írjunk egy szubrutint, ami két értéket megcserél: SUB Swap a, b LOCAL t t = a a = b b = t END SUB Ha valahol ezt meghívjuk: Swap nbr1, nbr2 Az eredmény az lesz, hogy az nbr1 és nbr2 értéke felcserélődik. Ha meg akarjuk tartani a változók eredeti értékeit, akkor ne használjunk ezeket, mint egy általános célú változót egy szubrutin vagy függvény belsejében. Sokkal biztonságosabb helyi változókkal dolgozni ilyen esetben.
Tömbök átadása Egy tömb egyes elemeit mint egy normális változót lehet használni egy szubrutinban vagy függvényben. Például az előbbi Swap szubrutin (lásd fent) helyesen működik: Swap dat(i),dat(i + 1) Ilyen megoldást gyakran használják tömbök rendezésénél. Teljes tömb ia használható egy szubrutin vagy függvény paramétereként, megadva a tömb nevét, amit () követ. Az átadott paraméter típusának (float, integer vagy string) és bent használt változó típusának azonosnak kell lennie. A rutinban hasznát tömb örökölni fogja az átadott tömb méretét, indexelését. Ha szükséges, a tömb mérete akár külön paraméterként is átadható. A név szerinti tömb átadás azt jelenti, hogy bármilyen változás történik a tömbben a hívott alprogramban az eredetiben is meg fog jelenni. Például, ha a következő program a "Hello World"-ot nyomtatja ki: DIM str$(5, 5) Str$(4, 4) = "Hello" Str$(4, 5) = "World" 29
Concat$ str$() PRINT Str$(0, 0) SUB concat$ arg$() arg$(0,0) = arg$(4, 4) + " " + arg$(4, 5) END SUB
További megjegyzés Csak egy END SUB vagy END FUNCTION lehet a szubrutinok vagy függvények végén. Ha előbb ki akarunk lépni, használjuk a EXIT SUB vagy EXIT FUNCTION parancsot.
Példa egy definiált függvényre Mi is definiálhatunk szubrutint, vagy függvényt ami hasonlóan fog működni mint az MMBasic-be építettek. Például, néha kellene egy TRIM függvény, amely levág megadott karaktereket egy karakterlánc elejéről és végéről. A következőkben lássunk egy példát arra, hogyan kell megírni egy ilyen egyszerű függvényt MMBasic-ben. A függvény első paraméterére a csonkítandó karakterfüzér, a második az karakterfüzér amit az eredeti füzérben keresünk. RTrim$ () függvény vág a string végéről, LTrim$() az elejéről, és Trim $ () mindkét végéről. ' trim any characters in c$ from the start and end of s$ Function Trim$(s$,c$) Trim$ = RTrim$(LTrim$(s$,c$),c$) End Function ' trim any characters in c$ from the end of s$ Function RTrim$(s$,c$) RTrim$ = s$ Do While Instr(c$,Right$(RTrim$,1)) RTrim$ = Mid$(RTrim$,1,Len(RTrim$)-1) Loop End Function ' trim any characters in c$ from the start of s$ Function LTrim$(s$,c$) LTrim$ = s$ Do While Instr(c$, Left$(LTrim$,1)) LTrim$ = Mid$(LTrim$,2) Loop End Function 30
Példák a függvények használatára: S$ = " ****23.56700 PRINT Trim$(s$, " ")
"
Eredmény: "****23.56700" PRINT Trim$(s$, " *0") Eredmény: "23.567" PRINT LTrim$(s$, " *0") Eredmény: "23.56700" Az MMBasic programozásával, és az ezekhez kapcsolódó kérdések tárgyalásával itt nem foglalkozunk, ezek leírása a kézikönyvben részletesen megtalálható
Programok fejlesztése és hibakeresése az MMEdit fejlesztő környezet segítségével. A MMBasic programok fejlesztésére rendelkezésre áll egy komplett fejlesztő környezet, ami a már az előzőekben említett http://www.c-com.com.au/MMedit.htm linkről letölthető. A program telepítése a Windows programoknál megszokott módon történik, nem ír a regisztrációs adatbázisba, és ezért létezik hordozható változata is. A program lényegében egy terminálfunkciókat megvalósító szövegszerkesztő és okos kiegészítőkkel a MMBasic programfejlesztést is lehetővé tevő program. Installálás után az ábrán látható képernyő fogad minket az indítóikonjára történő rákattintás után. Amint látható, számos szöveges legördülő menü található az ablak tetején. A gyorsabb elérés érdekében egy tekintélyes hosszúságú ikonsor is van a következő sorban, a gyakori parancsok gyors aktivizálásához. Mivel a program működésének megtanulásához rendelkezésre áll egy szintén letölthető MMedit.pdf kézikönyv, ezért a következőkben csak a programfejlesztéshez kapcsolódó legfontosabb jellemzőket fogjuk bemutatni.
31
Sablonok használata Ha szeretnénk, hogy a programjaink egységes képet mutassanak, célszerű a sablonok (angolul: template) használata, amiből akár öt különféle sablon tárolható. Ha egy program több azonos sorral kezdődik, akkor az első alkalommal történő begépelés után célszerű sablonként bármilyen néven elmenteni. Ha a fájl nevének a "DEFAULT.BT"-t adjuk, akkor File>New menüpont választásakor azonnal ez fog betöltődni. (Persze használhatjuk File>New from Template menüt is.) A sablon megváltoztatható: megnyitás után módosítás, és azonos néven mentés. Sablonok a Data mappába vannak tárolva, az összes mappa helyét Help> Névjegy ... menüre kattintva láthatjuk.
Könyvtár (Library) Gyakran használt saját szubrutinokat, függvények külön elmenthetők egy külön Library területre tudjuk elmenteni. (File>Library). Figyelem! Csak szubrutinokat és függvényeket menthetünk ilyen módon! A szerkesztő ablakban kijelöljük a mentendő függvényt vagy szubrutint, majd megnyitjuk a File>Library menüt, és a „Add selected code to library” jelölésű gombra kattintunk. A mentettek a programba való beillesztése a megnyílt ablak alapján magától értetődő. Ez a könyvtár szerkeszthető, a neve: library.bas és az Data mappában tárolódik. 32
Auto-Backup – Automatikus mentés Lehetőség van arra, hogy a szerkesztés közbeni munkáinkat az MMedit automatikusan elmentse külön fájlonként. A File>Preferences menüpontra kattintva megjelenő ablakban megkeressük az Auto-Backup Time felirat alatt lévő ablakot, itt írhatjuk be a periodikus mentés idejét percben. Ha az automatikus mentés ideje nem nulla, a programfájlok a Folder ablakban megadott helyre menti ciklikusan. Mentésre kerül a dátum az idő, majd a program neve: pl. 20140827_0738_programom.bas. Mentések letiltásához az időt nullára kell állítani. Letöltés és futtatás esetén is megtörténik a mentés backup.bas néven az előbbiekben megadott mappába.
Hibavadászat (debugging) segítése Programok tesztelésekor fontos a program változói aktuális állapotának a megtekintése, illetve a program futásának tetszőleges ponton történő megállítása (töréspont) valamint bármely programrész kizárása a futtatásból, mindezt a forrásprogram módosításával tudjuk megvalósítani. Hibavadászatot támogató eszközök:
Advanced>Mark selected line as comment A program tetszőleges részét kijelölve, ezt a részt a program futásából ki tudjuk zárni, kikommentezve. Advanced>Uncomment selected lines A fordított művelet. Advanced>Mark selected lines as DEBUG Hibakereséskor szokás a változókat kinyomtatni a PRINT utasítással. Ezeket a sorokat DEBUG szövegű kommenttel láthatjuk el. Advanced>Remove DEBUG mark a DEBUG kommentek eltávolítása. Advanced>Mark DEBUG lines as comment Teljes körű művelet az összes DEBUG sor kommentezésére. Advanced>Uncomment DEBUG lines. Teljes körű művelet az összes DEBUG sor visszaállítására. TRON/TROFF, Nyomkövetés be/Nyomkövetés ki parancsokat lehet elhelyezni a forrásprogramban tetszőleges szegmenseire. Az interperter a konzol portra küldi az aktuálisan értelmezett sor számát, így a nyomkövetés engedélyezésével és tiltásával követhetővé válik a programfutás menete.
Könnyű mozgás nagyméretű programban (könyvjelzők) Nagyméretű programokban történő navigáció könyvjelzők segítségével lehetséges. (Bookmarks főmenü) Könnyen hozhatunk létre egy adott sorra mutató könyvjelzőket, törölhetjük is ezeket. A létrehozott könyvjelzők nem mentődnek el a programfájllal együtt. 33
Az MMEdit felső ikonsorában folytonos vonallal bekeretezett két szélső gombbal is lehet lépkedni a könyvjelzők között körkörösen, a középső gombbal lehet létrehozni/törölni könyvjelzőt. A szaggatott vonallal kijelölt két gombbal tudunk egy felhasználó által definiált függvények vagy szubrutinok nevére állítva a kurzort, elugrani annak a definíciójára, illetve onnan visszaugrani.
Fájlok méretének a csökkentése Amikor a programunk mérete nagyobb lesz, az eszközmemória mérete problémás lehet. Ahelyett, hogy a méretcsökkenés érdekében comment nélküli és így olvashatatlan, formázása nélküli kódot írnánk, tartsuk meg a jól formázott programkialakítást: számos kommenttel és az áttekintést segítő üres sorokkal. Ezután a fájl méretének csökkentéséhez letöltéskor fogunk tömöríteni. Ez a tömörítés (angolul:crunch) elvégezhető a Program főmenüben található beállításokkal: Remove blank lines - vegyük ki az üres sorokat, Remove comments and blank lines, Távolítsuk el a megjegyzéseket,és az üres sorokat, Remove indents and trailing spaces Bekezdéseket biztosító, és a sorok végén lévő betűközök eltávolítása Crunch which does all of the above a fenti tömörítések végrehajtása egyszerre. Program letöltése előtt célszerű megnézni Program>Report Variable usage jelentést aminek elemzésével a nem használt függvényeket és szubrutinokat törölni tudjuk.
34
Összefoglalásként az elektromos jellemzők:
35
Kedvcsináló: GPS modul által vezérelt óra http://geoffg.net/Micromite_GPS_Clock.html A következőkben ismertetett projekt célja annak bizonyítása, hogy mennyire könnyű Micromite-al egy összetett feladatot megoldani, valamit egy hosszabb programkód bemutatása. Ez egy digitális óra, amely az aktuális időt egy GPS modultól kapja, másodperces pontossággal kijelzi, automatikusan kompenzálja a nyári időszámítást és az órát soha nem kell beállítani. A GPS vezérelt óra alapja egy Micromite, és néhány további alkatrészt használ.
A Micromint-be beírt program kódja: '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' GPS CLOCK ' Geoff Graham, March 2014 ' ' Demonstration of the Micromite ' This program will get the time from an EM-408 GPS module, add the timezone ' and daylight saving then display on a two line LCD. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Configuration constants TimeZone = 8.0 ' hours from GMT (+ or -) UseDST = 0 dms = 10 dhs = 2 dme = 4 dhe = 2
' ' ' ' '
set the the the the
to 1 to enable daylight saving time (DST) adjust month that DST starts hour that DST starts month that DST ends hour that DST ends
' global arrays DIM md(12), arg$(20) DATA 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 FOR i = 1 TO 12: READ md(i): NEXT i
36
LCD Init 23, 24, 25, 26, 17, 18 OPEN "COM1:4800" AS #1
' setup the LCD for display ' open the GPS serial interface
' this is the main program loop, it never exits DO KeepSearching: DO GetGPSRecord ' get a GPS record LOOP UNTIL arg$(0) = "GPRMC" ' we only want the RMC record IF arg$(2) <> "A" THEN ' "A" means valid record LCD 1, C16, "Searching" LCD 2, C16, "For Satellites" GOTO KeepSearching ' go back and keep looking ENDIF ' the GPS has the valid time ' first extract the elements of the date/time from the GPS record year = VAL(RIGHT$(arg$(9), 2)) ' extract the date month = VAL(MID$(arg$(9), 3, 2)) day = VAL(LEFT$(arg$(9), 2)) hour = VAL(LEFT$(arg$(1), 2)) ' extract the time min = VAL(MID$(arg$(1), 3, 2)) sec = VAL(MID$(arg$(1), 5, 2)) ' convert the time to minutes since midnight 1st Jan 2014 ' then add/subtract the timezone and if required add daylight saving ' this calculation takes just 15mS at 40MHz mins = GetMins(year, month, day, hour, min) mins = mins + TimeZone * 60 ' adjust for the timezone IF UseDST THEN ' if we observe daylight saving IF mins < GetDST(year, dme, dhe) OR mins > GetDST(year, dms, dhs) THEN mins = mins + 60 ' adjust for AWST DST ENDIF ENDIF ' because ' we have sec = sec IF sec >=
we will display the time at the start of the next second to add 1 second to the current time + 1 60 THEN sec = 0 : mins = mins + 1
' finally convert the minutes back into the current date/time Line1$ = GetDate$(mins) Line2$ = GetTime$(mins) ' we now have the date/time for the next second ready for display ' we have to wait for the end of the data stream from the GPS ' then we wait for the start of the next second and only then update the LCD DO : LOOP WHILE TIMER < 950 ' wait for the data to finish DO : LOOP WHILE INPUT$(200, #1) <> "" ' clear the input buffer DO WHILE INPUT$(1, #1) <> "$" : LOOP ' wait for a new second to start TIMER = 0 ' display the date and time for this second LCD 1, C16, Line1$ LCD 2, C16, Line2$ LOOP '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' subroutine to get a GPS record into the array arg$() SUB GetGPSRecord DO DO WHILE INPUT$(1, #1) <> "$" : LOOP ' wait for the start FOR i = 0 TO 20
37
arg$(i) = "" DO x$ = INPUT$(1, #1) IF x$ = "," THEN EXIT DO IF x$ = "*" THEN EXIT SUB arg$(i) = arg$(i) + x$ LOOP NEXT i LOOP END SUB
' ' ' ' ' ' ' '
clear ready for data loops until a specific exit get the character new data item, new field end of record, so return with it add to the data keep going increment the field
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' calculate the minutes since midnight 1st Jan 2014 FUNCTION GetMins(yr, mth, day, hr, min) GetMins = (yr - 14) * (365 * 24 * 60) + ((yr - 13) \ 4) * (24 * 60) GetMins = GetMins + (md(mth) * (24 * 60)) GetMins = GetMins + ((day - 1) * (24 * 60)) GetMins = GetMins + (hr * 60) GetMins = GetMins + min IF (yr - 16) MOD 4 = 0 AND mth > 2 THEN GetMins = GetMins + (24 * 60) END FUNCTION ' convert minutes back into the time (as a string) FUNCTION GetTime$(minutes) LOCAL hr, min, am$ am$ = "AM" hr = (minutes \ 60) MOD 24 IF hr >= 12 THEN am$ = "PM" IF hr > 12 THEN hr = hr – 12 IF hr = 0 THEN hr = 12 min = minutes MOD 60 GetTime$ = STR$(hr) + ":" GetTime$ = GetTime$ + RIGHT$("0" + STR$(min), 2) + ":" GetTime$ = GetTime$ + RIGHT$("0" + STR$(sec), 2) + " " + am$ END FUNCTION ' convert minutes back into the date (as a string) FUNCTION GetDate$(minutes) LOCAL yr, mth, day, mths$, days$ mths$ = " JanFebMarAprMayJunJulAugSepOctNovDec" days$ = "SunMonTueWedThuFriSat" FOR yr = 14 TO 99 IF minutes < GetMins(yr + 1, 1, 1, 0, 0) THEN EXIT FOR NEXT yr FOR mth = 1 TO 12 IF minutes < GetMins(yr, mth, 1, 0, 0) THEN EXIT FOR NEXT mth mth = mth - 1 day = ((minutes - GetMins(yr, mth, 1, 0, 0)) \ (24 * 60)) + 1 GetDate$ = MID$(days$, ((((minutes \ (24 * 60)) + 3) MOD 7) * 3) + 1,3)+" GetDate$ = GetDate$ + RIGHT$(" " + STR$(day), 2) GetDate$ = GetDate$ + "-" + MID$(mths$,mth*3,3) + "-" + STR$(yr + 2000) END FUNCTION ' get the minutes that DST will start or end in a month FUNCTION GetDST(yr, mth, hr) LOCAL d, m m = GetMins(yr, mth, 1, hr, 0) d = ((m \ (24 * 60)) + 3) MOD 7 GetDST = m + (((7 - d) MOD 7) * 24 * 60) END FUNCTION
38
"