21. LPM0 – LPM3 sleepmodet

Alunperin julkaistu: 12.2.2017

Viimeksi muokattu: sunnuntai 12.2.2017

Tervetuloa Launchpad oppaan 21:een osaan. Jos olet lukenut kaikki osat tähän mennessä, niin kiitän mielenkiinnostasi.

Seuraavassa 10:ssä osassa käydään läpi mikrokontrollerin käyttöä sovelluksissa, missä tarvitaan kytkinten ja ledien lisäksi muutakin elektroniikkaa ja tekniikkaa, kuten erilaisia IC-piirejä, näyttöjä, antureita, erilaisia sulautettuja väyliä jne. Toivottavasti tulevat osat kiinnostavat ja antavat vastauksia mieltäsi askarruttaviin kysymyksiin.

Tulevissa osissa olen käyttänyt editorina kirjoitushetkellä CCS:n uusinta versiota: Code Composer Studio v5. Tämä johtuu siitä, että uudessa versiossa on hieman miellyttävämpiä ominaisuuksia koodin kirjoitusta varten ja muuta mukavaa. Koodit kyllä toimivat vanhemmallakin versiolla ja sillä ei oikeastaan opettelun kannalta ole väliä käyttääkö vanhempaa vai uudempaa versiota.

Myös käytettävä mikrokontrolleri saattaa olla eri kuin tähän mennessä käytetty MSP430G2231, mutta pyrin tekemään esimerkkikoodit kyseiselle mikrokontrollerille mikäli sovellus niin vain sallii.

Sen pidemmittä puheitta, siirrytään itse asiaan.

MSP430 Sleepmodet tai "unitilat"

Mikrokontrollereilla, aivan kuten tietokoneiden keskusyksiköillä (CPU) on yksi tärkeä ominaisuus muiden joukossa. Kuten otsikkokin sen paljastaa, kyse on sleep-modesta tai "idle" tilasta jos niin haluaa sanoa. Tässä tilassa CPU ei kuluta virtaa eikä näin ollen suorita mitään, mutta on kuitenkin valmiina tekemään asioita ja "heräämään" tarvittaessa.

Yksi MSP430 mikrokontrollereiden tärkeimmistä ominaisuuksista on juurikin vähävirtaisuus, minkä vuoksi niitä käytetään esimerkiksi yleismittareissa, vähävirtaisissa antureissa, kaukosäätimissä ja muuallakin, missä vähävirtaisuus on edellytys laitteen toiminnalle. Varsinkin paristo- tai akkukäyttöisissä laitteissa vähän energiaa kuluttava suoritus on ehdottoman tärkeää.

MSP430 mikrokontrolleri kykenee heräämään unitilasta 1-5 mikrosekunnissa, eli sekunnin miljoonasosissa, mikä on hyvin pikkuriikkinen aika sekuntiin verrattuna. Vähävirtaisessa tilassa MSP430 mikrokontrollerin kellot ja tarpeen tullen eri moduulit (peripheral) on pysäytettynä ja mikrokontrolleri voidaan herättää vain jollakin keskeytyksellä tai resetillä. Keskeytyksiä voi aiheuttaa timer, kytkimet tai jokin mikrokontrollerin sisäinen laite - esimerkiksi HW UART. Olipa keskeyttävä laite tai tulo mikä tahansa, niin herääminen takaisin toimintatilaan (AM, Active Mode) tapahtuu aina keskeytyksessä. MSP430 mikrokontrollereilla on mallista riippuen 3-5 kappaletta eri vähävirtaisia tiloja.

Seuraavaksi käydään läpi yleisimmät virransäästötilat, joita MSP430G2231 (ja myöskin muilla MSP430) mikrokontrollereilla voidaan käyttää helpoiten.

LPM0 - LPM4

MSP430 Mikrokontrollereiden vähävirtaisia tiloja kutsutaan englanniksi luontevasti "Low Power Mode" termillä ja vastaavaa LPM kirjainlyhennettä tullaan tästä eteenpäin käyttämään tarkoittamaan juurikin kyseisiä toimintatiloja. MSP430 mikrokontrollerilla on useita erilaisia LPM tiloja ja kukin tila on erilainen. LPM0 tilassa kulutetaan enemmän virtaa kuin LPM1 tilassa, mutta ei koskaan enempää kuin AM-tilassa. Kun mikrokontrolleri ei ole LPM-tilassa, on se silloin aktiivisena, eli AM-tilassa.

MSP430 mikrokontrollerin eri toimintatiloja ohjataan CPU:n SFR rekisterin SCG0, SCG1, OSCOFF ja CPUOFF biteillä. SFR-rekisteri on muokattavissa ainoastaan assembly kielellä, mutta onneksi kääntäjäympäristö antaa meille yksinkertaisempia työkaluja näiden bittien muokkaamiseen.

LPM-tiloista on kerrottu lisää alla olevissa esimerkeissä, missä näytetään eri toimintatilojen välillä siirtyminen. Esimerkkikoodin jälkeen löytyy myös tarkempi selitys edellä mainituista tiloista.

Esimerkkikoodi LPM0 - LPM3

Kirjoitetaan lyhyt esimerkkikoodi, minkä pohjalta voimme virran kulutusta tutkia Launchpadin ja yleismittarin avulla. Ohjelma toimii siten, että CPU pysyy LPM-moodissa 5 sekuntia, minkä jälkeen aktiivimoodissa tarkkaillaan muuttujan tilaa toiset 5 sekuntia (kulutetaan käytännössä CPU:n tehoja) ja tätä toistetaan silmukassa.

#include <msp430g2231.h>
// Ohjelmamuistin koko tavuina (byte) Flash/RAM = 284/18
unsigned int SleepSeconds=0;   // luodaan globaalit muuttujat
unsigned int passedTime = 0;

void SleepMode(unsigned int sec);
void main(void)
{
          WDTCTL = WDTPW + WDTHOLD;    // watchdog pysäytys
          P1DIR = 0xFF;       // kaikki lähdöksi
          P1OUT = 0;    // kaikki pois päältä
          BCSCTL3 = XCAP_3;   // asetetaan 12,5 pF:n sisäiset kondensaattorit aktiiviseksi
          CCTL0 = CCIE;  // sallitaan vertailijan keskeytys
          TACTL |= ID_0 + TASSEL_1;  // asetetaan jakaja 0, laskentamoodi vertaileva ja ACLK-kello.   
          CCR0 = 32767;    // ladataan vertailurekisterin arvo 1 sekunnin keskeytystä varten
           __enable_interrupt();   // sallitaan globaalit keskeytykset
          TACTL |= MC_1;      // käynnistetään laskuri

          while(1)
          {
                  // 5 sekuntia sleepissä, 5 sekuntia aktiivisena
                  SleepMode(5);
                  while(passedTime < 10);
                  passedTime = 0;
          }
}
void SleepMode(unsigned int sec)
{
      SleepSeconds = sec;
      LED_RED_ON;
      // mennään sleep modeen
      // muuta LPMx_bits halutuksi LPM-tilaksi, esim: LPM2_bits
      _bis_SR_register(LPMx_bits + GIE);
      LED_RED_OFF; 
}
#pragma vector = TIMERA0_VECTOR
__interrupt void TimerA0(void)
{
      LED_GREEN_TOGGLE;
      passedTime++;
      // tarkastetaan voidaanko CPU herättää
      if(passedTime == SleepSeconds)
      {
            _bic_SR_register_on_exit(LPMx_bits); // muuta LPMx_bits vastaavaksi LPM-tilaksi
      }
}

Lataa tämän esimerkin CCSv5 projekti tästä.

Kun Launchpadiltä poistaa LED-jumpperit (J5) ja VCC jumpperin (J3), niin virrankulutusta voidaan yleismittarilla mitata. Alla on mitattu virrankulutus 1 MHz:n kellolla ja Timer A:n ollessa jatkuvasti aktiivinen:

AM: 0,36 mA
LPM0: 0,08 mA
LPM1: 0,08 mA
LPM2: 0,025 mA = 25 uA
LPM3: 0,0015 mA = 1,5 uA

LPM0 tilassa mikrokontrollerin CPU ja MCLK-kello ovat pois päältä. Mikrokontrolleri ei tällöin suorita koodia, eikä MCLK-kellosignaali "tikitä". DCO (Digitally Controlled Oscillator), SMCLK-kello ja ACLK-kello ovat kuitenkin päällä ja esimerkiksi timerit (jotka käyttävät näitä kelloja) voivat olla päällä. Mikrokontrolleri voi herätä timerin ohjaamana, jonkin lisälaitteen (peripheral, kuten UART) ohjaamana tai porttipinnin keskeytyksestä.

LPM1 on samankaltainen tila kuin LPM1, mutta tässä tilassa virransäästöä on tehty lisää sammuttamalla DCO. Muutoin tässä tilassa pätee samat asiat kuin LPM0-tilassa.

LPM2 tilassa vain ACLK-kello on päällä ja muut kellot sammuksissa. Tila on samankaltainen kuin edellä mainittu, mutta entistäkin vähänvirtaisempi.

LPM3 tilassa myös vain ACLK-kello on aktiivisena, mutta sisäinen jännite generaattori (DC generator), joka tuottaa DCO:n tarvitseman käyttöjännitteen ei ole päällä.

LPM4 tilassa kaikki kellot ja jännitegeneraattorit on sammutettu. Mikrokontrolleri on tässä tilassa herätettävissä vain ulkoisilla herätteillä joko porttipinneihin tai reset-linjaan. Tästä tilasta herätessään mikrokontrolleri ei välttämättä ole suoraan käytettävissä (ilman ongelmia), sillä joidenkin rekistereiden asetukset ovat voineet muuttua. Tämä on kuitenkin hieman mikrokontrollerikohtaista ja toiminta kannattaa todentaa ennen varsinaista käyttöönottoa. Tässä LPM4 -tilaa ei alettu tutkimaan kuitenkaan yksinkertaisuuden vuoksi.

Yleisimmin käytetyt LPM-tilat ovat siis LPM0 ja LPM3 ja niillä pärjää vallan mainiosti jatkossa. Kaikista näistä tiloista voidaan herätä porttipinnin keskeytyksestä, timerin avulla tai jonkin laitteen herättämänä (esim. UART) sekä resetin avulla.

"Intrinsic"-komennot

Käskyä, millä LPM-tilaan mennään ja sieltä poistutaan, kutsutaan englannin kielen termillä "intrinsic". Tälle ei oikein hyviä suomennoksia löydy, mutta jos sen haluaa suomentaa niin käännössanoina voi käyttää "olennainen" ja "luontainen" (lähde sanakirja.org). Näitä komentoja ovat siis esitellyssä koodiesimerkissä käytetyt _bic_SR_register_on_exit() ja _bis_SR_register() komennot.

Kyseisillä komennoilla voidaan C-kielisessä lähdekoodissa muokata bittejä, jotka olisivat muutoin muokattavissa vain assembly kielellä. Tällaiset komennot ovat kääntäjä- ja ohjelmointiympäristökohtaisia ja nämä komennot löytyvät vain CCS-ohjelmasta. IAR:llä on kuitenkin myös tarjolla omat komennot, muutaman merkin erotuksella tosin.

Ideana näillä "funktioilla" on siis tarjota ohjelmoijalle helppo tapa muokata C-kieleltä piilossa olevia bittejä, tässä tapauksessa CPU:n SFR-rekisterin bittejä. Komennot koostuvat assembly kielestä, jotka on "verhoiltu" C-kielisiksi funktioiksi. Kääntäjä lisää näitten funktioitten sisältämät komennot suoraan konekielen käskyiksi sille kohtaa koodia, missä niitä on käytetty. (lähde)

Nyt kun kaikki LPM-tilat on saatu selville ja niistä on esimerkitkin kirjoitettu, niin näitä voidaan jatkossa hyödyntää. Kaikissa seuraavissa osissa yleensä hyödynnetäänkin (ei välttämättä kuitenkaan aina) LPM-tiloja, sillä LPM-tilojen käyttö on MSP430 mikrokontrollereilla yleensä enemmän sääntö kuin poikkeus.

Mikäli aihetta kiinnostaa tutkia enemmän, niin alla on muutama linkki, mistä tällekin sivuille koostettu tieto on peräisin:

http://www.ti.com/lit/ug/slau144i/slau144i.pdf
http://processors.wiki.ti.com/index.php/MSP430_LaunchPad_Low_Power_Mode
http://www.swarthmore.edu/NatSci/echeeve1/Class/e91/Lectures/E91(4)TimerA_Interrupts.pdf