Fórum témák
» Több friss téma |
Cikkek » Launchpad: ismerkedés az MSP430 mikrovezérlőkkel II. Launchpad: ismerkedés az MSP430 mikrovezérlőkkel II.
Szerző: icserny, idő: Nov 3, 2011, Olvasva: 22764, Oldal olvasási idő: kb. 5 perc
IdőzítőkAz előző fejezetben láttunk néhány példát arra, hogy külső megszakítások segítségével hogyan használhatjuk az LPM4-es energiatakarékos módot. Vannak azonban olyan esetek, amikor rendszeres időközönként, belső megszakítással szeretnénk ébreszteni a CPU-t, vagy valamilyen alkalmazáshoz a szoftveres késleltetésnél pontosabb időzítésekre van szükség. Ehhez meg kell ismerkednünk az MSP430 mikrovezérlők időzítőivel. Ezek közül az "őrkutyával" Watchdog Timer, WDT) tulajdonképpen már volt dolgunk, hiszen minden programunk azzal kezdődött, hogy le kellett tiltanunk a WDT-t. Logikus tehát, ha ezzel kezdjük az ismerkedést. A Launchpad kártyával kapott mikrovezérlőkben van ezen kívül egy sokoldalúan használható másik időzítő is (Timer) amellyel a következő oldalon foglalkozunk. Az őrkutya (WDT)Az őrkutya időzítő elsődleges szerep az, hogy védjen bizonyos rendszerhibák ellen: indítsa újra a mikrovezérlőt, ha a program valahol elbarangolt, vagy végtelen ciklusba került (kivéve a főprogram szándékosan végtelenné tett ismétlődő részét). Hasznos az őrkutya időzítő akkor is, ha valamelyik külső hardver eszköz nem válaszol záros időn belül, s a programunkban ez elakadást okozna. A WDT, mint egy időzített bomba, számlálja az óraimpulzusokat. Szerencsére nem robban, hanem újraindítja (reseteli) a mikrovezérlőt a számlálója túlcsordulásakor. Éppen ezért, ha a WDT nincs letiltva, akkor gondoskodni kell róla, hogy a számlálóját rendszeres időközönként töröljük. Az MSP430 mikrovezérlők WDT időzítője azonban beállítható úgy is, hogy ne újraindulást, hanem programmegszakítást okozzon. Ez azért jó, mert sok olyan alkalmazás van, ami rendszeres megszakítást igényel a feladatok ütemezéséhez. A WDTCTL regiszterA WDT beállítása és vezérlése a WDTCTL regiszteren keresztül történhet. Ez egy 16 bites regiszter, tehát minden írás vagy olvasása szó szélességű művelettel kell, hogy történjen. A WDTCTL regiszter a véletlen felülírástól yédett: íráskor a nagyobbik helyiértékű felébe egy úgynevezett jelszót kell írni (mely 0x5A). Az olyan írás műveletek, amelyeknél nem ez a szám szerepel a magasabb helyiértékű bájtban, megszakadnak, és a mikrovezérlő újraindul ("biztonsági kulcs hiba" jelzéssel). Az RST/NMI bemenet konfigurálása is ebben a regiszterben történik. A WDTCTL regiszter alsó helyiértékű felének bitkiosztása így néz ki:
WDTHOLD - Ezzel a bittel kapcsolhatjuk ki a WDT-t. (0: WDT engedélyezve, 1: WDT leállítva)
A WDT időzítő letiltásaA fentiek alapján mostmár érthető, hogy a programok elején mit jelent az alábbi titokzatos sor, ami minden programunk elején ott díszelgett:
A baloldalon a WDT vezérlő regiszterének neve szerepel, melynek alapértelmezett értéke az alsó 8 biten nulla. A fenti sorral '1'-be állítjuk a WDTHOLD bitet, ami lekapcsolja a WDT időzítőt, ami onnan kezdve sem számolni, sem resetelni, sem interruptot okozni nem fog a visszakapcsolásig, vagy a következő újraindulásig. Újraindítás (RESET) a WDT segítségévelA következő programmal LED1-et villogtatjuk, de igen szokatlan módon. A villogtatás periódusideje VLO használata esetén ~1600 ms, a 32 kHz-es LFXT1 használata esetén pedig 500 ms. Az időzítést most nem szoftveres programhurkokkal végezzük, hanem a WDT végzi hardveresen, s túlcsorduláskor újraindítja a programot (RESET). A várakozás alatt a program LPM3 energitakarékos módban alszik: MCLK, SMCLK és DCO kikapcsolva, csak ACLK jár (LFXT1 vagy VLO forrásból). Mintaként felhasználtuk az MSP430D2xx1 mintaprogramok (slac463a.zip) wdt_06.c programját (D. Dang, Texas Instruments, Oct. 2010) 6_1. lista: a wdt_reset.c program listája
A főprogram első sorában ACLK forrásául a VLO oszcillátort állítjuk be. Ha már beforrasztottuk a 32 kHz-es kvarcot, akkor hagyjuk ki ezt a sort! A WDT_ARST_250 makrót az io430g2230.h fejléc állomány definiálja, s azt állítjuk be vele, hogy WDT minden 8192-dik órajelre okozzon resetet.
A 32 kHz-es órajel esetében ez 250 ms-os időzítést jelent. A kb. 10 kHz-es VLO esetében pedig T = 8192/1000 = 0.8192 s = 819.2 ms. Mivel minden újrainduláskor átbillentjük LED1 állapotát, az minden második újrainduláskor kerül azonos fázisba, tehát a LED villogási periódusa a fentebb kiszámolt érték kátszerese (32 kHz-es LFXT1 esetén 500 ms, a 10 kHz-es VLO esetében pedig kb. 1.64 s). Megjegyzés: A fenti programban messzemenően kihasználtuk azt, hogy a P1OUT kimeneti adatregisztert az újraindulások (PUC feltétel) nem módosítják. Ha RESET-kor törlődne a P1OUT regiszter, akkor a fenti program nem működne, hiszen minden újrainduláskor nulláról kezdenénk! Periodikus megszakítás WDT segítségévelA következő program arra mutat példát, hogy az intervallum időzítő módba beállított WDT segítségével hogyan kelthetünk periodikus meszakításokat, s hogyan használhatjuk azt fel egy többfeladatos rendszerben ütemezésre. A program LED1-et és LED2-t különböző ütemben villogtatja (ezen időzítések az eddigi módon, szoftveres késleltetéssel nehezen volnának előállíthatók). Az időzítéshez a periodikus megszakítást generáló WDT szolgáltat időalapot, kb. 51,2 ms periódussal. Az egyes feladatok egymástól eltérő késleltetéseit az interrupt kiszolgáló eljárásában, az időszeletek számlálásával, szoftveres számlálók segítségével oldottuk meg. Az időzített események száma tehát könnyen bővíthető.
A főprogram előtt egy-egy globális változót kell deklarálnunk minden feladat ütemezéséhez. Ezeket a változókat illékonynak (volatile) deklaráltuk, mert a főprogramban és a megszakítási rutinban is használjuk. A változók 16 bites előjel nélküli egészek, így legfeljebb 65535 időszelet (kb. 3350 s) a leghosszabb beállítható késleltetési idő. Az uint16_t típust az stdint.h fejléc állomány deklarálja, ezért azt is be kellett csatolnunk. A főprogram első sorában most is a VLO oszcillátort állítjuk be ACLK forrásául. A WDT_ADLY_16 makrót az io430g2230.h fejléc állomány definiálja, s azt állítjuk be vele, hogy WDT minden 512-dik órajelre okozzon programmegszakítást.
A 32 kHz-es órajel esetében ez 16 ms időzítést jelentene, de az általunk kiválasztott kb. 10 kHz-es VLO esetében valójában T = 512/1000 = 51.2 ms. Ez lesz az időalap, s minden ütemezéshez beállított késleltetés ennek egész számú többszöröse lesz. Az időzítéseket ugyanis az időszeletek számlálásával valósítjuk meg. Az egyszerűség kedvééért az elvégzendő feladatokat (LED-ek villogtatása) is a megszakítást kiszolgáló eljárásban végezzük el. Így megtakarítottuk a főprogram és a megszakítási szint közötti kommunikációt. A másik lehetőség az volna (s bonyolultabb esetekben azt az utat kell követni), hogy a megszakítási rutinban szemaforokat állítunk be, melyeket a főprogram használ fel. A cikk még nem ért véget, lapozz! Értékeléshez bejelentkezés szükséges! |
Bejelentkezés
Hirdetés |