Időzítők, számlálók

A fejezet tartalma:

Az időzítés szerepe a beágyazott rendszerekben

A beágyazott rendszerek időben kell, hogy reagáljanak a bekövetkező eseményekre, vagy előre megadott ütemezés szerint kel, hogy végezzék feladataikat (pl. adatgyűjtés/adatmegjelenítés azonos időközönként). Ebből következően a beágyazott rendszereknek képeseknek kell lennie az alábbiakra:
A fenti feladatok közben konfliktushelyzet is kialakulhat: például egy külső esemény akkor kér kiszolgálást, amikor éppen egy ütemezett feladatot végez a rendszer. Ez azt jelenti, hogy a fenti követelmények még egy újabbal bővülnek: a beágyazott rendszereknek meg kell tudni különböztetni a sürgős kiszolgálást igénylő eseményeket a kevésbé sürgős feladatoktól.

Ebből következik, hogy szükségünk van olyan eszközökre és módszerekre, amelyek lehetővé teszik a hatékony idő-alapú tevékenység végzését. Főbb elemei ennek az eszköztárnak az előző fejezetben tárgyalt megszakítások valamint az időzítők/számlálók, amelyekkel ebben a fejezetben foglalkozunk. A számláló (counter) olyan digitális áramkör, amellyel feszültségimpulzusokat tudunk leszámlálni. Ha a leszámlálandó impulzusok nem külső forrásból származnak, hanem ismert, állandó frekvenciájú jelet vezetünk a számláló bemenetére, akkor pedig időzítőről (timer) beszélünk, amely lehetővé teszi számunkra az idő mérését, illetve a feladatok ütemezését.

Ütemezést tulajdonképpen már használtunk a  legelső LED villogtató projektünknél is, amelyben wait(0.2) függvényhívásokkal arra utasítottuk a mikrovezérlőt, hogy 0.2 másodpercig várakozzon a LED állapotváltások között. Az ilyen várakoztatás roppant egyszerűen, akár üres programciklusokkal is megvalósítható, ám  a blokkoló jellege miatt nem  hatékony.  Komolyabb programjainkban nyilván azt szeretnénk majd, hogy a mikrovezérlő a várakozások során más feladattal is foglalkozhasson, s az időmérés a háttérben történjen. Ezzel el is érkeztünk a hardveres számlálók és időzítők használatához...

Számlálókat gyakran használnak a digitális áramkörökben. Ezek  többnyire sorbakötött bistabil billenőáramkörök, melyek mindegyike egy-egy bitnyi információt tárol. Egy n-bites számláló 2n-1 állapotot képes felvenni. Például az alábbi ábrán látható 8 bites számláló 0000 0000-tól 1111 1111-ig, azaz 0-tól 255-ig számol.


1. ábra: Egyszerű 8-bites számláló

Ha a számláló bemenetére ismert és stabil frekvenciájú jelet vezetünk, akkor a számlálónk időzítőként használható. Például 1 MHz-es órajel (periódusidő = 1 µs) esetén a számlálónk mikroszekundumokat számlál.

Időzítők/számlálók a MKL25Z128VLK4 mikrovezérlőben

A Freescale KL25 Sub_Family Reference Manual szerint az MKL25Z128VLK4 mikrovezérlő az alábbi számlálókkal, illetve időzítőkkel rendelkezik:

Összefoglalva: Az mbed környezetben az MKL25Z128VLK4 mikrovezérlő minden számlálója/időzítője adott feladatot lát el. A Systick időzítőt tehát csak akkor használhatjuk fel saját céljainkra, ha nem használjuk az mbed RTOS operációs rendszert. Timer0, Timer1, Timer2 közül csak azt használhatjuk fel saját célra, amelyek PWM csatornáit nem használjuk. PIT és LPTMR pedig csak akkor használhatók, ha nem használjuk sem a wait függvényeket, sem a WakeUp objektumosztályt, sem az alábbiakban tárgyalandó Timer, Timeout, Ticker objektumosztályokat.

A Timer objektumosztály

A Timer objektumosztály segítségével absztrakt időmérőket hozhatunk létre, amellyel pl. a két esemény között eltelt időt mérhetjük meg, mikroszekundumos felbontással.

1. táblázat: A Timer objektumosztály tagfüggvényei
Függvény
Használat
Timer név
Létrehoz egy "név" nevű absztrakt Timer  objektumot.
start()
Elindítja az időmérést
stop()
Megállítja az időmérést
reset()
Nullázza az időmérőt
read()
Másodpercekben adja meg az eltelt időt.
read_ms() Ezredmásodpercekben adja meg az eltelt időt.
read_us() Milliomod másodpercekben adja meg az eltelt időt.
Megjegyzés: A read_ms() és read_us() tagfüggvények visszatérési értéke int típusú, ezért az absztrakt időzítők 231-1 µs-nál (kb. 2147 s) hosszabb időtartam mérésére nem alkalmasak.

Mintapélda: Reakcióidő mérése Timer használatával

Az alábbi programban, amely  Albertas Galin: "Reaction_timer" c. programjának átirata, a Timer absztrakt időzítőt stopperként használjuk, s egy LED felgyulladása és a válaszként lenyomott nyomógomb bekapcsolása között eltelt időt mérjük vele (a felhasználó reakcióideje). Az eredményt az alapértelmezett soros porton keresztül íratjuk ki.

Hardver követelmények:

2. ábra: A nyomógomb bekötése

 
1. lista: A 08_reaction_time/main.cpp  program listája
#include "mbed.h"

DigitalOut myled(LED_GREEN); //define LED
DigitalIn mybutton(D3,PullUp); //define pushbutton input with pull-up
Timer t; //define timer
int x; //x for random number storage

int main() {
myled = 1; //LED is initially off
printf("\r\nReaction test!\r\n");
printf("Push the button when the LED is on!\r\n");
while(1) {
while(!mybutton); //wait for button release
x=rand()%2000; //generate random number 0-2000
wait_ms(1000+x); //wait random time between 1 and 3 seconds
t.start(); //start the timer
myled=0; //LED on
while(mybutton); //wait for press
t.stop(); //stop the timer
myled=1; //LED off
wait_ms(20); //debounce delay
printf("The time taken was %f seconds\r\n", t.read());
t.reset(); //reset the timer
}
}
A nyomógomb bemenetet belső felhúzású módba konfiguráljuk, így nem kell külső felhúzó ellenállást kötni a D3 (PTA12) bemenetre. A while(1) feltételvizsgálattal kezdődő végtelen ciklus elején a nyomógomb felengedésére történő várakozás megakadályozza a lassú felengedésből, vagy az eleve lenyomva tartásból adódó téves időmérést. A LED felkapcsolása előtt egy (ál)véletlen hosszúságú (1000-3000 ms időtartamú) várakozás következik, majd elindítjuk a stoppert. A nyomógomb lenyomásakor leállítjuk az időmérést és lekapcsoljuk a LED-et, majd kiíratjuk az eredményt. Az újabb mérési ciklus megkezdése előtt nulláznunk kell a stoppert a t.reset() függvényhívással.

3. ábra: A 08_reaction_time program futási eredménye


A Timeout objektumosztály

A Timeout objektumosztály segítségével ébresztőórához hasonló időmérőt hozhatunk létre, amellyel adott idő elteltével visszahívási (callback) függvényt aktiválhatunk, a főprogram futását megszakítva. Mivel a visszahívási függvény programmegszakítási szinten aktiválódik, ügyelnünk kell rá, hogy a visszahívási függvény ne tartalmazzon blokkoló várakozást,  terjedelmes adatfeldolgozást, printf kiíratást, memória allokációt. Megfontolandó az RTOS Timer használata a Timeout helyett, mert akkor  nem  megszakítási szinten történik a visszahívás.

2. táblázat: A Timeout objektumosztály tagfüggvényei
Függvény
Használat
Timeout név
Létrehoz egy "név" nevű Timeout  objektumot.
attach(*fptr,time)
A Timeout objektumhoz rendel egy visszahívási függvényt és megadja a visszahívási időt. Az időt lebegőpontos formátumban, másodpercben adjuk meg.
attach_us(*fptr,time)
A Timeout objektumhoz rendel egy visszahívási függvényt és megadja a visszahívási időt. Az időt unsigned int formátumban, mikroszekundumokban adjuk meg.
detach()
Megszünteti a visszahívási függvény hozzárendelését az időzítőhöz
Megjegyzés: Az időzítések kezelése int32_t típusú változókban történik, ezért 231-1 µs-nál (kb. 2147 s) hosszabb időzítéseket ne adjunk meg!

Mintapélda: LED állapotváltás Timeout használatával

Az alábbi programban, amely az mbed Handbook Timeout_HelloWorld mintapéldája, a Timeout absztrakt időzítőt arra használjuk, hogy egy visszahívási függvény segítségével adott idő eltelte után LED2 állapotát átváltsuk, miközben a főprogram végtelen ciklusában LED1 villogtatása zajlik folyamatosan.

Hardver követelmények:
2. lista: A 08_timeout_helloworld/main.cpp  program listája
#include "mbed.h"

Timeout flipper;
DigitalOut led1(LED1); // LED_RED
DigitalOut led2(LED2); // LED_GREEN

void flip() { // callback function
led2 = !led2; // flip state of LED_GREEN
}

int main() {
led2 = 1;
flipper.attach(&flip, 2.0); // setup flipper to call flip after 2 seconds

// spin in a main loop. flipper will interrupt it to call flip
while(1) {
led1 = !led1; // blink LED_RED
wait(0.2); // by 2.5 Hz (0.2s ON, 0.2s OFF)
}
}
A program elindításakor (bekapcsolás, vagy RESET után) először csak LED1 (a piros LED) villog 2.5 Hz frekvenciával. Kb. 2 másodperc után LED2 (a zöld LED) is bekapcsol a flip függvény meghívásának hatására, s az újabb RESET-ig folyamatosan világít.

A Ticker objektumosztály

A Ticker objektumosztály segítségével olyan "ébresztőórát" hozhatunk létre, amellyel periodikusan, adott időközönként aktiválhatjuk az objektumhoz rendelt visszahívási (callback) függvényt, a főprogram futását megszakítva. Mivel a visszahívási függvény programmegszakítási szinten aktiválódik, ügyelnünk kell rá, hogy a visszahívási függvény ne tartalmazzon blokkoló várakozást,  terjedelmes adatfeldolgozást, printf kiíratást, memória allokációt.

Nem árulunk el nagy titkot azzal, ha elmondjuk, hogy a Timeout és a Ticker objektumosztály lényegében megegyezik, kizárólag a visszahívási függvény aktiválásában térnek el: Timeout esetén csak egyszer történik aktiválás, a Ticker esetében pedig minden aktiváláskor "újra felhúzzuk az ébresztőt", ezért periodikusan ismétlődik az aktiválás.

A különbséget megfigyelhetjük, ha a 2. listában bemutatott programban a Timeout  flipper; sort kicseréljük erre: Ticker flipper;

3. táblázat: A Ticker objektumosztály tagfüggvényei
Függvény
Használat
Ticker név
Létrehoz egy "név" nevű Ticker  objektumot.
attach(*fptr,time)
A Ticker objektumhoz rendel egy visszahívási függvényt és megadja a visszahívási időt. Az időt lebegőpontos formátumban, másodpercben adjuk meg.
attach_us(*fptr,time)
A Ticker objektumhoz rendel egy visszahívási függvényt és megadja a visszahívási időt. Az időt unsigned int formátumban, mikroszekundumokban adjuk meg.
detach()
Megszünteti a visszahívási függvény hozzárendelését az időzítőhöz
Megjegyzés: Az időzítések kezelése int32_t típusú változókban történik, ezért 231-1 µs-nál (kb. 2147 s) hosszabb időzítéseket ne adjunk meg!

Mintapélda: Nyomógomb pergésmentesítése Ticker használatával

Az alábbi programban egy Ticker időzítő segítségével periodikusan mintavételezzük egy nyomógomb állapotát. Ha a mintavételezések közötti időtartam nagyobb, mint a kontaktusok pergési ideje (10-15 ms), akkor a mintavételezéssel megoldhatjuk a nyomógomb pergésmentesítését. A nyomógombbal egy LED-et kapcsolgatunk ki és be. A nyomógomb kezelés vonatkozásban az alábbi program a Programmegszakítások fejezetben található 07_button_interrupt mintaprogram javított változatának tekinthető.

Hardver követelmények:
3. lista: A 08_button_debouncer/main.cpp  program listája
#include "mbed.h"

DigitalIn button(D3,PullUp); // Pusbutton input
DigitalOut led(LED_BLUE); // LED output (the blue LED)
Ticker sampler; // Ticker for button state sampling
volatile uint8_t button_state = 1; // Initially released

void button_check()
{
button_state = (button_state<<1) | (button & 1); // shift in button state
if((button_state & 3)==2) { // Check for H -> L transition
led = !led; // Switch LED state
}
}

int main()
{
led = 1; // LED off
sampler.attach(&button_check,0.02); // sample button state in each 20 ms
while (true) {
wait(1); // do nothing
}
}
A nyomógomb figyelésére a D3 kivezetést digitális bemenetként konfiguráljuk és bekapcsoljuk a belső felhúzást. A bemenet állapotát 20 ms-onként mintavételezzük, s jobbról beléptetjük a button_state változó legalsó bitjébe (1: a gomb felengedve, 0: a gomb lenyomva). Amikor lenyomás történik, akkor a button_state változó utolsó két bitjén '10' bitkombinációnak kell lennie: (button_state & 3)==2). A fenti programban ehhez az eseményhez rendeltük a LED állapotának átkapcsolását.

Az RTC kezelése a Time programkönyvtár használatával

Az RTC valósidejű óra kezeléséhez az alapértelmezett mbed API nem tartalmaz C++ objektumosztályt. Az alábbiakban bemutatott, hiányosan dokumentált Time programkönyvtár valójában a standard C könyvtárből örökölt C függvényekből áll, melyekhez a céláramkörök RTC hardverének kezelésére (regiszterek beállítása, illetve kiolvasása) szolgáló C függvények társulnak.

Az aktuális idő az 1970. január 1.  óta eltelt másodperceket jelenti (UNIX timestamp), a tárolása time_t "timestamp" (időbélyeg) típusú változókban történik, ami valójában uint32_t típust jelent. Az idő kiíratáshoz, emberi léptékű kezeléshez a tm sruktúra típust használjuk, amelyben külön-külön változókban szerepel az év, a hónap, a nap, az óra, a perc és a másodpercek.

A Time programkönyvtár szűkszavú leírása mellett néhány egyszerű mintapélda is található. Egy részletesebb, de elavult leírás itt található.

3. táblázat: A Time programkönyvtár függvényei
Függvény
Használat
time(NULL)
Az aktuális idő kiolvasása. A visszatérési érték timestamp típusú
set_time(time_t t)
Az aktuális idő beállítása
mktime(struct  tm  * t)
Egy tm struktúra átalakítása timestamp formátumra. A paraméter tm struktúrára mutató pointer, a vissztérési érték timestamp típus.
localtime(time_t * t)
Egy timestamp átalakítása tm struktúrába (a visszatérési érték pointer!)
ctime(time_t * t)
Egy timestamp olvasható szöveggé történő konverziója. Pl. “Wed Oct 28 11:35:37 2009\n”
sfrtime(char * buffer,
size_t max,
char * format,
struct tm * t)
Egy tm struktúra testreszabható formátumú szöveggé alakítása
A függvények bonyolult paraméterezésének megértéséhez egy-egy rövid mintapéldát is bemutatunk a már említett elavult dokumentáció alapján.

time - Az aktuális idő kiolvasása a targetáramkör RTC moduljából, amelyet előzőleg a set_time() segítségével állíthatunk be. Az "aktuális idő" az 1970. január 1.  óta eltelt másodperceket jelenti (UNIX timestamp).
#include "mbed.h"

int main() {
set_time(1256729737); // Set RTC time to Wed, 28 Oct 2009 11:35:37
while(1) {
time_t seconds = time(NULL);
printf("Time as seconds since January 1, 1970 = %d\n", seconds);
wait(1);
}
}

set_time - az aktuális idő beállítása
#include "mbed.h"

int main() {
set_time(1256729737); // Set time to Wed, 28 Oct 2009 11:35:37
}

mktime - Egy tm struktúrát időbélyeggé alakít, mely az 1970. január 1.  óta eltelt másodperceket jelenti (UNIX timestamp). Egyúttal a tm struktúra tm_wday (a hét napja) és tm_yday (az év napja) elemeit is aktualizálja. Ügyeljünk rá, hogy az évszámokat 1900-hoz képest kell megadni, s a hónapok számozása 0-val kezdődik!
#include "mbed.h"

int main() {
// setup time structure for Wed, 28 Oct 2009 11:35:37
struct tm t;
t.tm_sec = 37; // 0-59
t.tm_min = 35; // 0-59
t.tm_hour = 11; // 0-23
t.tm_mday = 28; // 1-31
t.tm_mon = 9; // 0-11
t.tm_year = 109; // year since 1900

// convert to timestamp and display (1256729737)
time_t seconds = mktime(&t);
printf("Time as seconds since January 1, 1970 = %d\n", seconds);
}

localtime - egy time_t típusú időbélyeg értékét egy (statikusan allokált) tm stuktúrába konvertálja.
#include "mbed.h"

int main() {
time_t seconds = 1256729737;
struct tm *t = localtime(&seconds);
}

ctime - egy time_t időbélyeg formában megadott időpontot olvasható  formátumú dátum/idő szöveggé alakít. Az eredmény  ilyen formátumú lesz: “Wed Oct 28 11:35:37 2009\n”.
#include "mbed.h"

int main() {
time_t seconds = time(NULL);
printf("Time as a string = %s", ctime(&seconds));
}

strftime - egy tm struktúra formájában megadott időpont testreszabható formátumú szöveggé alakítása. Az sfrtime függvény abban különbözik a ctime függvénytől, hogy time_t helyett tm stuktúrát  vár, s nem kötött formátumú az eredmény, hanem  általunk megadott formátumú.
#include "mbed.h"

int main() {
time_t seconds = time(NULL);
char buffer[32];
strftime(buffer, 32, "%I:%M %p\n", localtime(&seconds));
printf("Time as a formatted string = %s", buffer);
}
A formátum megadásához az alábbi szövegelemeket használhatjuk:

4. táblázat: Az sfrtime() függvénynél használható formátumelemek listája               
%S Second (másodperc 00-59)
%M
Minute (perc 00-59)
%H
Hour (óra 0-23)
%d
Day (nap 01-31)
%m
Month (hónap 01-12)
%Y/%y
Year (év 2009, illetve 09 formátumban)
%A/%a
Weekday name (hét napjának neve Monday, illetve Mon formátumban)
%B/%b
Month name (hónap neve January, illeve Jan formátumban)
%I
12 Hour format (12 órás kijelzés 00-12)
%p
AM vagy PM
%X
Time (idő 14:55:02 formátumban)
%x
Date (dátum 02/05/09 formában February 5, 2009 esetén)

Mintapélda: Az RTC kipróbálása

A Time programkönyvtár mintaprogramjának segítségével kipróbáljuk az MKL25Z128VLK4 mikrovezérlő RTC modulját. A program semmi hasznos dolgot nem csinál, csupán az alábbi lépéseket próbáljuk ki vele:
A kiíratásokhoz nyissunk egy terminálablakot és kapcsolódjunk az OpenSDA virtuális soros portjához az alapértelmezett formátummal és sebességgel (8N1, 9600 bps)!

Hardver követelmények:
4. lista: A 08_rtc_test/main.cpp  program listája
#include "mbed.h"

int main()
{
set_time(1256729737); // Set RTC time to Wed, 28 Oct 2009 11:35:37

while(1) {
time_t seconds = time(NULL);
printf("Time as seconds since January 1, 1970 = %d\n", seconds);
printf("Time as a basic string = %s", ctime(&seconds));
char buffer[32];
strftime(buffer, 32, "%I:%M %p\n", localtime(&seconds));
printf("Time as a custom formatted string = %s", buffer);
wait(1);
}
}
A program futási eredménye az alábbi ábrán látható:

4. ábra: A 08_rtc_test program futási eredménye

Mintapélda: az RTC használata

Az előző programban csak egy önkényesen választott időpontra állítottuk be az RTC óráját. Az alábbi programmal tetszés szerinti időpontot, tehát a tényleges időt is megadhatjuk a soros porton keresztül. Sajnos, a  FRDM-KL25Z kártya RTC órája csak korlátozottan használható (nincs sem telepes póttápegysége sem saját órejel generátora, hogy a kártya kikapcsolt állapotában is mérje az időt), de az alábbi programmal legalább beállítástól kikapcsolásig nyomon követhetjük az idő múlását. A kiíratásokhoz nyissunk egy terminálablakot és kapcsolódjunk az OpenSDA virtuális soros portjához az alapértelmezett formátummal és sebességgel (8N1, 9600 bps)!

Megjegyzés: Az alábbi mintapélda megírásához sokat merítettünk a limchonghan blogján közzétett Drift Corrected DS1307 Real Time Clock programból.

Az RTC beállításához egy TYYMMDDhhmmss parancsot kell kiküldenünk a terminálablakból, ahol:
T   - a kötelező parancsbetű (T mint Time)
YY - az évszám utolsó két jegye (2016-ban ez 16)
MM - a hónap sorszáma (Január esetében 01)
DD - a nap (01 - 31 közötti szám)
hh - az óra (00 - 23 közötti szám)
mm - a perc (00 - 59 közötti szám)
ss - a másodperc (00 - 59 közötti szám)

Hardver követelmények:
5. lista: A 08_rtc_example/main.cpp  program listája
#include "mbed.h"
Serial pc(USBTX,USBRX); //UART0 via OpenSDA
DigitalOut myled(LED1);
Ticker myticker;
time_t mytime;
volatile uint8_t myflag =0;

void processSerialCommand();

void setflag(void)
{
myflag = 1;
}

int main()
{

set_time(1451736661);
myticker.attach(&setflag,5);
while(1) {
if(pc.readable()) {
processSerialCommand();
}
if(myflag) {
mytime = time(NULL);
pc.printf("RTC time: %s\r\n",ctime(&mytime));
myflag = 0;
}
}
}

void processSerialCommand()
{
char c = pc.getc();
switch(c) {
case 'T':
// Command to set RTC time
// Command format: TYYMMDDHHMMSS
// Example: 2012 Oct 21 1:23pm is T121021132300
struct tm tme;
time_t newTime;

// Parse incomming 12 ASCII charaters into time_t
// no error checking for numeric values in YYMDDHHMMSS fields, so be careful!
c = pc.getc();
tme.tm_year = c - '0';
c = pc.getc();
tme.tm_year = 10*tme.tm_year;
tme.tm_year += c-'0';
tme.tm_year += 100; //Years are counted from 1900!
c = pc.getc();
tme.tm_mon = c - '0';
c = pc.getc();
tme.tm_mon = 10*tme.tm_mon;
tme.tm_mon += c-'0'-1; //corrected by -1 due to a stupid error
c = pc.getc();
tme.tm_mday = c - '0';
c = pc.getc();
tme.tm_mday = 10*tme.tm_mday;
tme.tm_mday += c-'0';
c = pc.getc();
tme.tm_hour = c - '0';
c = pc.getc();
tme.tm_hour = 10*tme.tm_hour;
tme.tm_hour += c-'0';
c = pc.getc();
tme.tm_min = c - '0';
c = pc.getc();
tme.tm_min = 10*tme.tm_min;
tme.tm_min += c-'0';
c = pc.getc();
tme.tm_sec = c - '0';
c = pc.getc();
tme.tm_sec = 10*tme.tm_sec;
tme.tm_sec += c-'0';
newTime = mktime(&tme);
set_time(newTime);
pc.printf("RTC set to: %s\r\n",ctime(&newTime));
}
while(pc.readable()) {
pc.getc(); // clear serial buffer
}
}
A program futási eredménye az alábbi ábrán látható. A kép alsó sorában a beírt parancs is látható, melynek hatására a pirossal aláhúzott válaszüzenet jelent meg.

5. ábra: A 08_rtc_example program futási eredménye


A WakeUp objektumosztály

Többé-kevésbé az időzítők témaköréhaz tartozik az Erik Olieman által írt WakeUp objektumosztály is, amely az LPTMR időzítő segítségével előre beállítható idő eltelével felébreszti a mikrovezérlőt az energiatakarékos "mélyalvás" üzemmódból. Ennek különösen telepes (elem vagy akkumulátor) táplálás esetén van jelentősége, hiszen ha tétlen állapotban lekapcsoljuk a mikrovezérlőt, jelentősen csökkenthetjük az energiaigényt, s  akkor ugyanazzal az elemmel/akkumulátorral hosszabb üzemidőt érhetünk el.

5. táblázat: A WakeUp objektumosztály tagfüggvényei
Függvény
Használat
set(time)
Beállítja az időzítést az egész másodpercekben megadott időre
set_ms(time)
Beállítja az időzítést az ezredmásodpercekben megadott időre
attach(*fptr)
Visszahívási függvényt rendel az időzítőhöz. Ha csak ébreszteni akarjuk az MCU-t, akkor nincs szükségünk erre a funkcióra!
calibrate()
A főoszcillátorhoz kalibrálja az LPTMR óráját.
Figyelem: a kalibrálás100 ms blokkoló várakozással jár!
Megjegyzés: A Frescale KLxx mikrovezérlők esetén a WakeUp objektumosztály tagfüggvényei ugyanazt az LPTMR perifériát használják, amit a korábban ismertetett Ticker objektumosztály is használ. Hogy ne legyen ebből összegabalyodás, a WakeUp elmenti, majd ébresztés után visszaállítja LPTMR korábbi állapotát. A zavartalan működés érdekében azonban nekünk kell ügyelnünk arra, hogy a WakeUp ébresztés beállítása után már ne hozzunk létre új Ticker példányt. Ha valamilyen okból mégis erre kényszerülünk (pl. InteruptIn ébresztés esetén), akkor egy WakeUp::set(0) beállítással előbb töröljük az ébresztő beállítását!

Mintapélda: WakeUp használata

Az alábbi programban egy LED-et villogtatunk úgy, hogy a LED kikapcsolt állapotában a mikrovezérlőt is "mélyalvás" állapotba helyezzük, amelyből a WakeUp segítségével ébresztjük fel, az időzítés letelte után. "Mélyalvás" állapotban az időzítők közül csak az LPTMR működik, ezért a WakeUp objektumosztály is ezt használja.

A 08_wakeup program lényegében Erik Olieman WakeUp mintaprogramja, minimális változtatásokkal. A program LED1-et (a FRDM-KL25Z kártyán ez LED_RED-et jelenti) 2 másodpercig kikapcsolt, majd 1 másodpercig bekapcsolt állapotban tartja. A program lefordításához  a WakeUp programkönyvtárat importálni kellett, s a program elején a WakeUp.h fejléc állományt be kellett csatolni.

Hardver követelmények:
6. lista: A 08_wakeup/main.cpp  program listája
#include "mbed.h"
#include "WakeUp.h"

DigitalOut myled(LED1); //LED_RED

int main() {
//The low-power oscillator can be quite inaccurate on some targets
//this function calibrates it against the main clock
WakeUp::calibrate();

while(1) {
myled = 1; //Switch LED off
WakeUp::set_ms(2000); //Set wakeup time for 2 seconds
deepsleep(); //Enter deepsleep mode
//-- zzZZ sleep here for 2 seconds -------------------
myled = 0; //Switch LED on after wakeup
wait(1); //Run state for 1 sec
}
}
Megjegyzés: A fenti programban a deepsleep() függvényhívással a mikrovezérlőt "mélyalvás" energiatakarékos módba állítjuk, s itt a programfutás megáll. "Felébredés" (wakeup) után a program a deepsleep() függvényhívást követő első utasítással folytatódik.