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. 7 perc
Lapozás: OK   5 / 8

Energiatakarékos üzemmódok

Az MSP430 mikrovezérlőket, s különösen az ultra-alacsony-energiaigényű MSP430G2xxx sorozatot alacsony fogyasztású alkalmazásokhoz szánták, s ez abban is tükröződik, hogy az aktív mód mellett több energiatakarékos üzemmóddal is rendelkezik: LPM0, LPM1, LPM2, LPM3, LPM4. Az energiatakarékos üzemmódok jelölésében az LPMx rövidítés a Low Power Mode (alacsony fogyasztású mód) elnevezést takarja.

A 3. oldal végén egy táblázatban foglaltuk össze, hogy aktív állapotban frekvenciától és órajel forrástól függően mekkora áramfelvételt mértünk. Ezen kívül olyan módok is beállíthatók, amikor a CPU ki van kapcsolva (nincs MCLK órajel), s a használatban lévő perifériáktól függően esetleg DCO, SMCLK vagy ACLK is kikapcsolható. A szokásos szóhasználattal alvásról beszélünk, amikor a CPU órajele ki van kapcsolva, s a CPU felébresztéséről, amikor a CPU újra órajelet kap.

A beállítható energiatakarékos üzemmódokat így foglalhatjuk össze:

Aktív mód: A CPU működik, program fut. MCLK, SMCLK és ACLK mind aktív. A Status regiszterben (SR) az üzemmódra vonatkozó bitek (CPUOFF, OSCOFF, SGC0, SGC1) mind nullára vannak állítva. Ez a mikrovezérlő normál módja, bekapcsoláskor ez van érvényben. Az áramfelvétel kb. 300 µA (T = 25°C-on, 1 MHz-es CPU frekvencián és VCC=2,2 V-os tápfeszültségen). Amint korábban láttuk, 3,5 V-on ez 400 µA-re növekszik.

LPM0: Ebben a módban a CPU és az MCLK órajel le van tiltva, a program nem fut, SMCLK, DCO és ACLK aktív. Ezt a módot akkor használjuk, ha a CPU-ra nincs szükség, de valamelyik periféria magas frekvenciájú órajelet igényel, amelyhez DCO szükséges. Ezt az üzemmódot a __low_power_mode_0() nevű beépített függvénnyel állíthatjuk be, amely a Status regiszter GIE és CPUOFF bitjeit '1'-be állítja. A CPUOFF bit bebillentése kikapcsolja az MCLK órajelet, s a CPU leáll (lásd az 1. oldalon található ábrát!). A GIE bit bebillentése azért fontos, mert a CPU-t az "alvó" állapotból csak RESET vagy programmegszakítás tudja felébreszteni. Az utóbbihoz pedig a megszakítási rendszer engedélyezése nélkülözhetetlen. Ebben a módban az áramfelvétel kb. 65 µA (T = 25°C, SMCLK = 1 MHz és VCC=2,2 V-os tápfeszültség mellett) .

LPM1: Ebben a módban a CPU és MCLK mellett a DCO oszcillátor is ki van kapcsolva. ACLK és SMCLK aktív. DCO kikapcsolhatóságához SMCLK számára az LFXT1 (vagy VLO) órajel forrást kell kiválasztani, tehát SMCLK és ACLK azonos forrást használnak, legfeljebb az utóosztó beállításában térhetnek el. Éppen ezért ennek az üzemmódnak nincs nagy gyakorlati jelentősége. Ezt az üzemmódot a __low_power_mode_1() nevű beépített függvénnyel állíthatjuk be, amely a Status regiszter GIE, CPUOFF és SGC0 bitjeit '1'-be állítja. Az SGC0 bit '1'-be állítása letiltja a DCO oszcillátort, ha egyik órajel forrásául sincs kiválasztva.

LPM2: Ebben a módban a CPU és MCLK mellett az SMCLK órajel is ki van kapcsolva. ACLK és DCO aktív. Ennek az üzemmódnak sincs nagy gyakorlati jelentősége. Egyetlen haszna talán az lehetne, hogy az állandóan futó DCO oszcillátor mellett a CPU ébresztéskor azonnal folytathatja a programot. Ez hasznos lehetett az MSP430 mikrovezérlők régebbi generációinál, azonban az újabb konstrukciójú mikrovezérlőknél, ahol a DCO feléledési ideje rendkívül rövid, ez az üzemmód lényegében szükségtelenné vált. Ennek Ezt az üzemmódot egyébként a __low_power_mode_2() nevű beépített függvénnyel állíthatjuk be, amely a Status regiszter GIE, CPUOFF és SGC1 bitjeit '1'-be állítja. Az SGC1 bit '1'-be állítása letiltja az SMCLK órajelet (lásd az 1. oldalon található ábrát!). Ebben a módban az áramfelvétel kb. 22 µA (T = 25°C, DCO = 1 MHz és VCC=2,2 V-os tápfeszültség mellett) .

LPM3: Ebben a módban a CPU,  MCLK, SMCLK és DCO le van tiltva, csak ACLK aktív. Ez az általánosan használt alacsony fogyasztású üzemmód, ha fenn tartani egy alacsony frekvenciájú órajelet a futó idő nyilvántartásához, vagy a CPU rendszeres időközönkénti felébresztéséhez. Az órajel forrása az órakvarccal ellátott LFXT1 oszcillátor, vagy pedig VLO lehet. A választástól függően az áramfelvétel 0,7 vagy 0.5 µA.

LPM4: Ebben a módban minden órajel és oszcillátor le van tiltva. Ez a mély alvás üzemmód, ahonnan csak külső megszakítás vagy RESET tudja felébreszteni a mikrovezérlőt. Más néven RAM tartalom megőrzésnek is hívják ezt a módot, amelyet a __low_power_mode_4() nevű beépített függvénnyel állíthatjuk be. íA függvény a Status regiszter GIE, CPUOFF, OSCOFF,SGC0 és SGC1 bitjeit '1'-be állítja. Az áramfelvétel kb. 0.1 µA (T = 25°C és VCC=2,2 V-os tápfeszültség mellett).

A STATUS regiszter vezérlő bitjei

A fentiekben már jeleztük, hogy az energiatakarékos üzemmódok beállítása mely bitekkel történik. A jobb áttekinthetőség kedvéért foglaljuk ezeket össze:

CPUOFF - ha '1', akkor letiltja a CPU órajelét, MCLK-t

OSCOFF - ha '1', akkor letiltja az LFXT1/VLO oszcillátort, ACLK jelforrását

SCG0 - ha '1', akkor letiltja a DCO oszcillátort (feltéve, hogy az nincs használatban MCLK vagy SMCLK számára.

SCG1 - ha '1', akkor letiltja az SMCLK órajelet.

Egyszerű példa az energiatakarékos mód használatára

A következő programban az inicializálás után a CPU-t altatjuk, s minden órajelet kikapcsolunk (LPM4 mód). A CPU felébresztése ilyenkor csak külső megszakítással lehetséges. Mi most az S2 nyomógombbal keltett megszakításokkal LED1-et kapcsolgatjuk. Induláskor és felébredéskor MCLK és SMCLK órajele az alapértelmezett 1 MHz-es DCO frekvencia lesz. ACLK-val most nem foglalkozunk. Az interupt kiszolgálása után a mikrovezérlő újra LPM4-es energiatakarékos módba kerül. Más néven ezt az üzemmódot RAM tartalom megőrző módnak is hívják, Ötletadó mintának felhasználtuk az MSP430G2xx1 mintaprogram gyűjtemény (slac463a.zip)  P1_04.c programját (D. Dang, Texas Instruments, Oct. 2010). A program sémája azokban az esetekben követhető, amikor a mikrovezérlő működését külső események vezérlik, s az események kiszolgálása interrupt szinten elvégezhető.

A példa lényege tehát az, hogy a főprogram LPM4-es módban "alszik", ami a legkisebb áramfelvételű mód. Az adatlap szerint az áramfelvétel kb. 0.1 µA (T = 25°C és VCC=2,2 V-os tápfeszültség mellett). A 200 µA-es legkisebb méréshatárral rendelkező kéziműszerrel gyakorlatilag mérhetetlenül kicsinek találtuk az áramfelvételt (I ≈ 0,1 µA, vagy kisebb). Ha ezt összehasonlítjuk az 1 MHz-es aktív állapotban mért 400 µA-es áramfelvétellel, akkor nyilvánvalóvá válik az energiatakarékos mód előnye: ha a hosszú várakozások között LPM4 módba tesszük a mikrovezérlőt, akkor a fogyasztása 1/4000-ed részére csökken!

 5_1. lista: A p1_3_insleep.c program listája

  1. #include  "io430.h"
  2. #include "intrinsics.h"
  3.  
  4. void main(void) {
  5.   WDTCTL = WDTPW + WDTHOLD;  // Letiltjuk a watchdog időzítőt
  6. //--- P1 PORT beállítása -----------------------------------------------------  
  7.   P1OUT = 0;                 // Minden P1.x alacsony állapotba
  8.   P1DIR = ~BIT3;             // P1.3 bemenet, a többi kimenet  
  9. //--- P2 PORT beállítása kimenetnek     --------------------------------------    
  10.   P2SEL = 0;                 // P2.x legyen digitális I/O
  11.   P2DIR = 0xFF;              // Minden P2.x legyen kimenet
  12.   P2OUT = 0;                 // Minden P2.x alacsony állapotba
  13. //----------------------------------------------------------------------------
  14. // P1.3 bemenet beállítása: interrupt minden lefutó él beérkezésekor
  15. //----------------------------------------------------------------------------  
  16. //P1REN |= BIT3;             // P1.3 felhúzását itt engedélyezhetnénk
  17.   P1IES |= BIT3;             // P1.3 lefutó élre érzékeny
  18.   P1IFG &= ~BIT3;            // P1.3 IFG törlése
  19.   P1IE |= BIT3;              // P1.3 interrupt engedélyezése
  20. //--- Programmegszakítás engedélyezése és belépés LPM4 módba -----------------  
  21.  __low_power_mode_4();                
  22. }
  23.  
  24. //--- Port 1 programmegszakítás kiszolgálása ---------------------------------
  25. #pragma vector=PORT1_VECTOR
  26. __interrupt void Port_1(void)
  27. {
  28.   P1OUT ^= BIT0;             // LED1 (P1.0) átbillentése
  29.   P1IFG &= ~BIT3;            // P1.3 interrupt jelzőbit törlése
  30. }


A program inicializáló része megegyezik az előző oldalon bemutatott programokkal. A fő különbség az, hogy itt az __interrupt_enable() helyett a __low_power_mode_4() függvényhívás szerepel. Ez a megszakítás engedélyezése mellett egyúttal kikapcsolja az összes órajelet, s a CPU csak a külső megszakítások kiszolgálásának időtartamára ébred fel. Emiatt elmarad a főprogram szokásos végtelen ciklusa is, hiszen a főprogramot sohasem ébresztjük fel.

A megszakítás kiszolgálásakor itt LED1 állapotát billentjük át, s természetesen törölnünk kell a megszakításjelző bitet. A megszakítás végén a STATUS regiszter (SR) automatikus helyreállításakor az energiatakarékos módot vezérlő bitek is helyreállításra kerülnek, így a CPU újra alvó állapotba kerül. Mint láthatjuk, az MSP430 mikrovezérlők átgondolt tervezésének köszönhetően nekünk sem a felébresztéssel, sem a visszaaltatással nem kell foglalkoznunk, mindez teljesen automatikusan történik. A megszakítás kiszolgáló eljárás megírása tehát semmiben sem különbözik a korábbiaktól. 

A főprogram felébresztése alvó állapotból

Az előző példában a külső esemény bekövetkeztekor a megszakítást kiszolgáló eljárásban végeztük el a teendőket. Vannak azonban olyan alkalmazások, amelyeknél ennél bonyolultabb a feladat, mert a külső megszakítás után egy hosszabb tevékenységsorozatot kell elvégeznünk, amit már nem célszerű a megszakítás szintjén futtatni (mert közben esetleg újabb megszakításokat kellene feldolgoznunk). Ilyen esetekben fel kell ébresztenünk a főprogramot.

Itt merül fel a kérdés: ha a megszakítás kiszolgálása végén a RETI utasítás automatikusan visszaállítja az SR vezérlő bitjeit, akkor hogyan akadályozhatjuk meg, hogy a CPU újra alvó állapotba kerüljön? A válasz egyszerű (csak a kivitelezése bonyolult): a STATUS regiszternek a veremtár tetejére elmentett másolatát kell módosítanunk, mielőtt kilépnénk a megszakítási eljárásból. Assembly programokban ezt a veremmutatóra hivatkozó indirekt címzéssel érhetjük el, C nyelvű programokban pedig a  __low_power_mode_off_on_exit() függvényhívást kell kiadnunk. A következő program erre mutat egy példát.

Az alábbi programban külső eseménnyel (szokásos módon az S2 gomb megnyomásával) ébresztjük fel a főprogramot, ami minden felébresztéskor egy adott ideig tartó tevékenységet végez (itt most kb. 2,5 másodpercig ellenütemben villogtatja a LED-eket), majd újra aludni tér, az LPM4-es mód beállításával. A program sémája lehet minden olyan alkalmazásnak, amikor külső esemény hatására valamilyen adott ideig tartó tevékenységet kell végezni: lépcsőházi világítás automata, dallamcsengő, riasztó stb.

 5_2. lista: A p1_3_wakeup.c program listája

  1. #include  "io430.h"
  2. #include "intrinsics.h"
  3.  
  4. void main(void) {
  5.   int i;
  6.  
  7.   WDTCTL = WDTPW + WDTHOLD;  // Letiltjuk a watchdog időzítőt
  8. //--- P1 PORT beállítása -----------------------------------------------------  
  9.   P1OUT = 0;                 // Minden P1.x alacsony állapotba
  10.   P1DIR = ~BIT3;             // P1.3 bemenet, a többi kimenet  
  11. //--- P2 PORT beállítása kimenetnek     --------------------------------------    
  12.   P2SEL = 0;                 // P2.x legyen digitális I/O
  13.   P2DIR = 0xFF;              // Minden P2.x legyen kimenet
  14.   P2OUT = 0;                 // Minden P2.x alacsony állapotba
  15. //----------------------------------------------------------------------------
  16. // P1.3 bemenet beállítása: interrupt minden lefutó él beérkezésekor
  17. //----------------------------------------------------------------------------  
  18. //P1REN |= BIT3;             // P1.3 felhúzását itt engedélyezhetnénk
  19.   P1IES |= BIT3;             // P1.3 lefutó élre érzékeny
  20.   P1IFG &= ~BIT3;            // P1.3 IFG törlése
  21.   P1IE |= BIT3;              // P1.3 interrupt engedélyezése
  22.   while(1) {
  23.     P1OUT = BIT0;            // LED1 = 1, LED2 = 0
  24.     for(i=0; i<10; i++) {
  25.       P1OUT ^= BIT0 + BIT6;  // LED1 és LED2 állapotának átbillentése
  26.       __delay_cycles(250000);// 250 ms várakozás
  27.     }
  28.     P1OUT = 0;               // LED-ek kikapcsolása  
  29. //--- Programmegszakítás engedélyezése és belépés LPM4 módba -----------------  
  30.     __low_power_mode_4();    // Alvás a következő gombnyomásig
  31.   }  
  32. }
  33.  
  34. //--- Port 1 programmegszakítás kiszolgálása ---------------------------------
  35. #pragma vector=PORT1_VECTOR
  36. __interrupt void Port_1(void)
  37. {
  38.     P1IFG &= ~BIT3;            // P1.3 interrupt jelzőbit törlése
  39.   __low_power_mode_off_on_exit(); //Felébresztjük az alvó CPU-t
  40. }

A program elején a már unalomig ismételgetett módon beállítjuk a portokat, s engedélyezzük a P1.3 bemenetre kötött nyomógomb megszakítását. A főprogram végtelen ciklusában a LED-ek 2,5 másodpercig tartó villogtatása, a LED-ek kikapcsolása és az alvó állapot beállítása ismétlődnek. Vegyük észre, hogy az alvó állapot miatt a while ciklus magja mindig csak a következő gombnyomáskor fut le újra.

A megszakítási rutinban csupán a megszakításjelző bitet töröljük, s elvégezzük a CPU ébresztését.

Megjegyzés: a program bekapcsoláskor egyszer gombnyomás nélkül is lefuttatja a LED villogtató "műsorát". Ha olyan alkalmazást készítünk, ahol ez nem kívánatos (pl. riasztó), akkor cseréljük meg a sorrendet, tegyük az LPM4 mód beállítását a végtelen ciklus legelejére!


A cikk még nem ért véget, lapozz!
Következő: »»   5 / 8
Értékeléshez bejelentkezés szükséges!
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem