Fórum témák
» Több friss téma |
Cikkek » Launchpad: ismerkedés az MSP430 mikrovezérlőkkel IV. Launchpad: ismerkedés az MSP430 mikrovezérlőkkel IV.
Szerző: icserny, idő: Jan 14, 2013, Olvasva: 16046, Oldal olvasási idő: kb. 10 perc
Közvetlen adatátvitel vezérlés (DTC)Az előző oldal végén már láttunk egy példát a DTC használatára. Most ismerkedjunk meg a közvetlen adatátvitel beállításának és használatának részleteivel! A DTC lehetővé teszi, hogy a konverzió eredményét közvetlenül a memória címtartomány egy kijelölt területére másoltassuk. Ez többnyire egy RAM terület, de lehet periféria regiszter, vagy akár flash memória is. Ebben a DTC működése nagyon hasonlít a más mikrovezérlőknél vagy processzoroknál használt DMA-ra. A fő különbség az, hogy a DMA általános célú, külön meg kell adni, hogy melyik perifériából másolja át az adatokat. Az MSP430 DTC funkciója ilyen szempontból "bedrótozott DMA"-nak tekinthető, hiszen kizárólag az ADC-ből (az ADC10MEM regiszterből) viszi át a mérési adatokat, s a DTC-t kizárólag az ADC konverzió végét jelző impulzus triggerelheti. A DTC működését három regiszter vezérli:ADC10DTC0 - kiválasztja az egy- vagy kétblokkos átvitelt és a folyamatos vagy blokkonkénti módot. A kétblokkos (ping-pong) mód lényege az, hogy amíg az adatok feldolgozása folyik az egyik blokkban, vele egyidejűleg az adatgyűjtés folytatódhat a másik blokkban.
ADC10DTC1 - adja meg az átviendő adatok számát egy blokkra vonatkozóan. A regiszterbe írt 0 érték letiltja a DTC működését.
ADC10SA - a célhely kezdőcíme. Az ADC10SA regiszter beírása engedélyezi az adatátvitelt (ahogyan az ENC bit beírása engedélyezi a konverziót).
A kétblokkos mód azt jelenti, hogy a memóriában az ADC10DTC1 regiszterben megadott adatszám kétszeresének foglelunk helyet a memóriában, s előbb az első felét töltjük fel, majd a másodikat, s ezután (folyamatos átviteli mód esetén) újra az első blokkba írunk, majd a másodikba (más mikrovezérlő gyártók ping-pong módnak is nevezeik ezt az átviteli módot). A kétblokkos átvitel jelentősége az, hogy amíg az egyik blokk átvitele folyik, addig a másik blokkban zavartalanul végezhetjük az adatfeldolgozást.
Az ADC10DCT0 regiszterReserved - fentartott (nem használt) bitek ADC10TB - blokkmód választás (0: egyblokkos, 1: kétblokkos átviteli mód) ADC10CT - folyamatos átvitel (0: az adatátvitel leáll, ha egy (vagy kétblokkos mód esetén két) blokk átvitele megtörtént, 1: az adatátvitel folyamatos, csak szakad meg, ha az ADC10CT bitet töröljük, vagy az ADC10SA regisztert újraírjuk) ADC10B1 - ez az állapotjelző bit mutatja, hogy kétblokkos módban éppen melyik blokk feltöltése van folyamatban (0: a második blokk töltődik, 1: az első blokk töltődik) ADC10FETCH - a MSP430x2xx Family User's Guide nem részletezi ennek a bitnek a szerepét, csupán annyit mondanak róla, hogy általában '0'-át kell bele írni. Ismételt ADC konverzió és DTCA következő program azt mutatja be, hogy hogyan használhatjuk az ADC ismételt egycsatornás konverzió üzemmódját a közvetlen adatátvitellel kombinálva. Különösen hasznos ez az üzemmód akkor, ha több mérést akarunk végezni, hogy abból átlagot számoljunk. Az alábbi programban a korábbi, 4_adc_simple_ref1 mintapéldához hasonlóan az A5 (P1.5 láb) bemenetre vezett 0 - 1,5 V közötti jelet, valamint a belső hőmérő jelét (Chan 10) mérjük meg, a beépített 1,5 V-os belső referenciához viszonyítva. A fő különbség az, hogy most csatornánkánt több mérést végzünk gyors egymásutánban (MSP430G2231 esetén 32 db. mérést). Apró különbség az is, hogy ennél a mintapédánál egy Microchip gyártmányú TC1047A analóg hőmérő jelét kötöttük az A5 bemenetre, ezért a nyers mérési adat és az abból meghatározott feszültség mellett a Celsius fokokban mért hőmérsékletet is kiíratjuk. Hardver követelmények:
A TC1047A analóg hőmérő egy parányi, háromlábú, SOT23 tokozású IC, amely az alábbi paraméterekkel rendelkezik:
A TC1047A analóg hőmérő bekötése roppant egyszerű: az 1-es lábát a tápfeszültségre (VDD), a 3-as lábát a földre (VSS), a 2-es lábát pedig a mikrovezérlő A5 analóg bemenetére (P1.1 láb) kell kötni. A csatornánkénti mérések számát az NDATA makró definiíciójában adhatjuk meg. Az MSP430G2231 mikrovezérlő esetén a RAM memória korlátozza az adatokat tartalmazó tömb méretét, az MSP430D2553 esetében azonban megnövelhetjük az adatok számát. A mérés eredményeit egyirányú szoftveres UART kezeléssel (csak adatküldés) kiíratjuk. A programlistából kihagytuk a korábbi programokból már ismerős függvényeket, itt csak az új, vagy megváltoztatott függvények szerepelnek. 6_1. lista: Részletek a 4_adc_multi_ref1 programból
A számunkra fontos újdonságot elsősorban az ADC_multi_meas_REF1_5V() függvény jelenti. A függvény bemenő paraméterei:
Az ADC konfigurálásánál a korábbiakhoz képest az alábbi változásokat figyelhetjük meg:ADC10CTL0 beállításánál az MSC bitet is '1'-be állítjuk. Ennek hatására az első triggerjel (esetünkben ADC10SC '1'-be állítása) után az előírt darabszámú konverzió egymás után, automatikusan lefut. Akésőbbiekben majd még lesz róla szó, hogy ez a nagy sietség nem mindig vezet jóra... ADC10CTL0 beállításánál a CONSEQx = 2 beállításra van szükség (ismételt konverzió egy csatornában). ADC10DTC0 beállításánál gyakorlatilag csak két bittel kell foglalkoznunk (a többi bit fenntartott, vagy státuszjelző). Itt most minkdkettőt nullára kell állítanunk. ADC10TB = 0 azt jelenti, hogy egyblokkos módot használunk, ADC10CT = 0 pedig azt jelenti, hogy az adatblokk átvitele után leáll a konverzió, tehát nem folyamatos módot írunk elő. ADC10DTC1 - ebbe aregiszterbe az átviendő adatok számát kell beleírnunk. ADC10SA - ebbe a regiszterbe a tárolásra kijelölt terület kezdőcímét kell beírni. A programban
deklarálta az adattömböt. Jegyezzük meg, hogy a tömb neve is egy mutató, tehát közvetlenül használhatjuk a memórai kezdőcím megadásához. Az ADC_multi_meas_REF1_5V() függvényben azoban (legalábbis az IAR EW esetében) típuskényszerítést kell használnunk, hogy a mutató értékét beírhassuk az ADC10SA regiszterbe. Definiáltunk egy további függvényt a mérések átlagolására avg() néven. Ez egyszerűen a mért adatok számtani közepét számolja ki, nem igényel külön magyarázatot. A főprogram teljes mértékben az 4_adc_simple_ref1 mintapélda menetét követi. A fő különbség az, hogy a korábban használt ADC_single_meas_REF1_5V() függvény helyett most az ADC_multi_meas_REF1_5V() függvényt hívjuk meg, s minden méréssorozat után el kell végeznünk az átlagolást is. Például:
A mintavételezés optimalizálásaNem mindig előnyös az, ha az ADC-vel gyors egymásutánban végezzük a méréseket. Ha az ismételt konverziónak az a célja, hogy a zavarjeleket (ami többnyire az 50 Hz-es hálózatból származik) kiátlagoljuk, akkor célszerű a mintavételezési frekvenciát a zavarjel frekvenciájához igazítani. Az alábbi 4_adc_multi2_ref1 programban a Timer0 alegység CCR0 csatornájának OUT0 (máshol ezt TA0.0 néven említi az adatlap) kimenőjelével 2 ms-onként indítunk egy konverziót. Összesen 32 mérést végzünk, ez tehát az 50 Hz-es zavarjel nagyjából három periódusát fogja át (tulajdonképpen 31 mintavételi pont lenne éppen három periódus, de ennyire már nem érdemes precízkedni, hiszen a DCO frekvenciája sem tökéletesen pontos). A program nagymértékben megegyezik az előzővel, a Timerrel történő triggerelést pedig az előző oldalon bemutatott 4_adc_pwm2 programból puskázhatjuk ki. A programlistában szokás szerint csak a kritikus részeket mutatjuk be, az unásig ismételt rutinokat itt nem listáztuk ki. 6_2. lista: Részletek a 4_adc_multi2_ref1 programból
Az ADC_multi2_meas_REF1_5V() függvényben az ADC konfigurálásánál ügyeljünk arra, hogy most nem szabad '1'-be állítani az MSC bitet, mert minden konverziót külön-külön akarunk triggerelni, hiszen épp ez volt a fő célunk ennek a programnak a megírásánál. AZ ADC10CTL1 regiszternél hardveres triggerelés TA0.0-val (SHSx=2) és ismételt konverzió egy csatornában (CONSEQx=2) beállításások kellenek. Az ADC megszakítását engedélyezzük az ADC10IE bit '1'-be állításával, de a megszakítás a DTC használata miatt most csak az előírt számú mérés elvégzése után következik be, amikor már minden eredmény eltárolásra került. A DTC konfigurálása megegyezik az előző példában bemutatottakkal. A Timer konfigurálását viszont nem az ADC_multi2_meas_REF1_5V() függvényben, hanem a főprogram elején végezzük el, mivel ezt elég egyszer végrehajtani. Az ADC beállítások végén most nem indítunk konverziót ADC10SC '1'-be billentésével, hanem alvás módba tesszük a CPU-t, ahonnan csak az ADC megszakítás ébreszti fel a méréssorozat végén. Természetesen az altatás és a megszakítás helyett most is várakozhattunk volna szoftveres várakozó hurokban az ADC10IFG bebillenésére úgy, mint az előző programban. A Timer CCR0 csatornájának beállítása hasonló az előző oldalon bemutatott 4_adc_pwm2 programban bemutatotthoz. A különbség annyi, hogy az időzítő bemenőjel most az 1 MHz-es SMCLK lesz, leosztás nélkül, a TACCR0 periódus regisztert pedig 999-re állítjuk (a periódus 1000 μs). Ne feledjük azonban el, hogy a toggle módú (OUTMOD_4) kimenőjel csak minden második periódusban kerül azonos fázisba, tehát a kimenőjel periódusideje 2000 μs, azaz 2 ms lesz! Az ADC megszakítás kiszolgálásakor nincs más teendőnk, mint a CPU felébresztése. A feléledés után a ADC_multi2_meas_REF1_5V() függvényben a biztonság kedvéért letiltjuk a további ADC konverziókat (ENC=0), bár lehet, hogy erre nincs szükség. A program futási eredménye az alábbi ábrán látható.
A cikk még nem ért véget, lapozz! Értékeléshez bejelentkezés szükséges! |
Bejelentkezés
Hirdetés |