Időzítők, számlálók
A fejezet tartalma:- Számlálók felhasználási területei
- Időzítők/számlálók a MKL25Z128VLK4 mikrovezérlőben
- A SysTick időzítő
- Mintaprogramok SysTick használatához
- Általános célú időzítő/számláló modulok (TPM)
- A TPM modulokhoz kapcsolódó csatornák
- Az Output Compare mód
- Input Capture - bemeneti jelrögzítés
- Eseményszámlálás
- Felhasznált anyagok és ajánlott olvasmányok
- Időtartam mérése
- Idő-alapú események generálása, ami lehet egyszeri vagy ismétlődő
- Megfelelő sebességgel reagálni az előre nem meghatározható időben bekövetkező eseményekre
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 a megszakítások, amelyeket a következő fejezetben tárgyalunk, 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 a legelső LED villogtató projektünknél is használtunk, amikor delayMs(500) függvényhívással arra utasítottuk a mikrovezérlőt, hogy fél másodpercig várakozzon a LED állapotváltások között. Az ilyen várakoztatás roppant egyszerűen, ü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ó 4 bites számláló bináris ábrázolásban 0000-tól 1111-ig, azaz 0-tól 15-ig számol.
1. ábra: Bináris, 4-bites szinkron számláló
Az 1. ábrán látható, J-K billenőkörökből (flip-flop) kialakított számláló jellemzői:
- bináris - mert kimenetein kettes számrendszerben ábrázolja a számláló állapotát
- 4-bites - mert négy bináris számjegyet képes kezelni (0b1111 után túlcsordul)
- szinkron számláló - mert minden kimenete egy órajellel szinkronizáltan vált állapotot
- felfelé számlál - mert pl. 0b0001 után 0b0010 lesz a következő állapot
2. ábra: A 4-bites szinkron számláló kimeneteinek jelalakja
A fentihez hasonló áramkörökkel találkozunk a mikrovezérlők perifériái között, ám ezeknek a számlálóknak még további feladatot is el kell tudni látnia:
- Választható órajelforrás (külső, belső - többféle frekvenciából választva, vagy programozható előosztó)
- A számláló legyen beírható - tetszőleges értékről vagy tetszőleges számig folyik a számlálás
- A számláló legyen kiolvasható - a számláló pillanatnyi állapota legyen az adatbuszra kapuzható
- Megszakítás (vagy egyéb esemény) generálása túlcsorduláskor
Számlálók felhasználási területei
Ahogy a bevezetőben is írtuk, a beágyazott rendszerekben a számlálókat többféle célra is használhatjuk. Néhány tipikus felhasználási terület:- Események számlálása
- Késleltetések előállítása (a számlálót időzítőként használjuk)
- Két esemény bekövetkezte között eltelt idő mérése
Események számlálása
Képzeljük el, hogy az úton elhaladó járműveket akarjuk megszámlálni, vagy a gyári futószalagon a késztermékeket. Esetleg az időegységenkénti radioaktív bomlások számát szeretnénk meghatározni egy Geiger-Müller detektor segítségével (a fukushimai baleset után készült ilyen, okostelefonokhoz kapcsolható eszköz). Ezekben a feladatokban az a közös, hogy végeredményben a számláláshoz valamilyen érzékelőt (szenzor) kell kapcsolnunk a számláló bemenetére. Az alaphelyzetből való indításhoz egy törlési lehetőségre is szükség lehet (nullázzuk a számlálót).3. ábra: Eseményszámláló
Késleltetések
előállítása
Különféle berendezések vezérlésénél általános gyakorlat az, hogy
valamilyen tevékenységet adott idő elteltével kell elindítani,
vagy
befejezni. A mosógéptől a kenyérsütőig számtalan példát lehetne
erre
sorolni. Az időzítés megvalósításához egy ismert frekvenciájú
órajel
generátort kapcsolunk a számláló bemenetére, így a számlálót
időzítőként használjuk. Például az alábbi ábrán egy órajel
generátor 1
Hz-es órajelet biztosít a számláló számára, a számláló tartalma
így
másodpercenként növekszik eggyel. Ha nulláról indítjuk a
számlálást és
egy digitális komparátor a számláló mindenkori tartalmát egy
előre
beírt számmal (esetünkben 60-bal) összehasonlítja, akkor az
előre
megadott idő elteltével (esetünkben 60 s múlva) lesz "1" a
digitális
komparátor kimenetének állapota - jelezve, hogy eltelt a
megadott idő 4. ábra: Időzítőként használt számláló
Két esemény bekövetkezte között eltelt idő mérése
Előfordulhat olyan feladat, amelyben két esemény között eltelt időt kell megmérnünk. Ilyen esemény lehet például a CH-05 ultrahangos szenzor kimenő jelének fel-, illetve lefutó éle. Megmérve az ezek között eltelt időt, s ismerve a hang terjedési sebességét, meghatározhatjuk a céltárgy távolságát, ahonnan a hang visszaverődött. Kényelmes megoldás, ha az első esemény bekövetkeztekor (Indítás) nullázni tudjuk a számlálót, a második esemény bekövetkeztekor (Leállítás) pedig rögzítjük a számláló állását egy másik regiszterben. Ezt az utóbbi folyamatot egyébként bemeneti jelrögzítésnek (Input Caprire) hívja a szakirodalom.A gyakorlatban néha nem egyszerű az indító és a leállító jel elkülönítése, vagy nem nullázható a számláló, mert több jelrögzítő csatorna is tartozik hozzá. Ilyenkor mindkét esemény bekövetkeztekor rögzítjük a számláló értékét, majd kiolvassuk és gyorsan eltároljuk (programmegszakításban). Végül a két érték különbségéből megkapjuk a kívánt értéket.
5. ábra: Bemeneti jelrögzítés
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:- SysTick 24-bites (vissza)számláló, amely az ARM Cortex-M mikrovezérlő mag része (a SysTick számláló megvalósítása az ARM Cortex-M0 és M0+ magú mikrovezérlőknél opcionális, de a legtöbb gyártó beépíti). Ezt a számlálót többnyire az operációs rendszerek (pl. RTOS) használják a feladatok ütemezéséhez.
- TPM0, TPM1, TPM2 általános célú 16-bites számlálók/időzítők, amelyekhez 2-6 db impulzus-szélesség modulációra (PWM), bemeneti jelrögzítésre (Input Capture), vagy digitális komparálásra (Output Compare használható csatorna is tartozik.
- Periodic Interrupt Timer
(PIT) modul,
ami 2 db 32 bites időzítővel rendelkezik, amelyek egy 64
bites
időzítővé is összekapcsolhatók. A PIT
modul elsősorban periodikus megszakítások előállítására
szolgál, de
annak sincs akadálya, hogy az Arduino környezetben használt
millis() függvényhez
hasonló módon a
bekapcsolás (vagy a legutolsó RESET) óta eltelt folyó időt
mérjük vele.
- Low-Power Timer (LPTMR)
16-bites időzítő/számláló. Az LPTMR
kisfogyasztású időzítő egyik legfontosabb jellemzője, hogy
mindegyik
energiatakarékos módban üzemképes marad, s külső események
számlálására
vagy belső órajellel időzítésre, vagy programozott
ébresztésre
használható. A 16-bites számláló bemenetéhez előszámlálót
vagy
zajszűrőt is konfigurálhatunk. Az előosztás mértéke kettő
hatványai
szerinti, 2 - 65536 közötti szám lehet.
- Real-Time Clock (RTC)
modul, melyben található egy 32-bites másodperc számláló,
egy 16-bites
előszámláló, egy 16-bites időkompenzációs regiszter és egy
32-bites
regiszter az ébresztés beállítására. A FRDM-KL25Z
kártya esetén a használatot némiképp korlátozza, hogy az RTC
órajelét
az OpenSDA áramkör
biztosítja,
s az MKL25Z128VLK4
mikrovezérlő PTC1
kivezetését (RTC_CLKIN)
lefoglalja.
A SysTick időzítő
A Cortex-M processzorok tartalmaznak egy SysTick nevű időzítőt, ami egyszerű lehetőséget biztosít periodikus megszakítások keltésére. A SysTick időzítő egy 24 bites visszafelé számlálót tartalmaz, amely nullára futáskor automatikusan újratöltődik (a töltési érték programozható), s egy megszakítást generál (a 15. számú megszakítási vektor). A megszakítást kiszolgáló szoftver lehet egy operációs rendszer része (taszkváltás az időszelet lejártakor). Természetesen azokban az alkalmazásokban, ahol nem használunk operációs rendszert, a SysTick időzítő tetszőleges célra felhasználható (pl. LED villogtatás, vagy más feladat ütemezéséhez).A SysTick megszakítások természetesen letilthatók, s akkor lekérdezéses módban is vizsgálhatjuk a számláló állapotát.
A SysTick időzítő regiszterei
A SysTick időzítő működését négy regiszter szabályozza. Ezek közül a negyedikkel (a kalibrációs regiszterrel) ebben a tananyagban mi nem foglalkozunk. Mivel projektjeink létrehozásánál becsatoljuk a CMSIS core definíciókat és függvényeket, ezért a SysTick használatánál a "CMSIS név" oszlopban megadott nevekkel hivatkozhatunk a regiszterekre (a definíciókat a core_cm0plus.h állomány tartalmazza).1. táblázat: A SysTick modul regiszterkészlete
Cím |
Regiszternév |
CMSIS név |
A regiszter funkciója |
---|---|---|---|
0xE000_E010 |
SYST_CSR | SysTick->CTRL |
Vezérlő és állapotjelző
regiszter |
0xE000_E014 |
SYST_RVR | SysTick->LOAD | Újratöltési érték
regiszter |
0xE000_E018 |
SYST_CVR | SysTick->VAL | Számláló pillanatnyi
értéke |
0xE000_E01C |
SYST_CALIB | SysTick->CALIB | Kalibrációs regiszter |
6.a ábra: A SysTick->CTRL vezérlő és állapotjelző regiszter bitkiosztása
ahol az egyes bitek szerepe a következő:
- Count Flag - Eseményjelző, amely '1', ha a visszaszámlálás 0-ra futott. Kiolvasáskor automatikusan törlődik.
- Clk Source - az órajel forrása (0: rendszer órajel/16, 1: a rendszer órajele)
- TickInt - SysTick megszakítás engedélyezése (1: megszakítás kérése, amikor a visszaszámlálás 0-ra fut)
- Enable - a SysTick számláló
bemenetének
engedélyezése (0:
nincs
számlálás, 1:
számlálás
engedélyezve)
A SysTick->LOAD regiszterbe írjuk be azt a számot, ahonnan a visszaszámlálás kezdődik. Az N órajel időtartamú visszaszámláláshoz N-1-et kell írnunk ebbe a regiszterbe. Mivel a számláló 24 bites, ezért 0x000001 - 0xFFFFFF közötti értékeket írhatunk a SysTick->LOAD regiszterbe. Elvileg nullát is írhatnánk bele, de annak nincs értelme, mert 1 -> 0 átmenetkor keletkezik a Count esemény...
A SysTick->VAL regiszterből olvashatjuk ki a számláló pillanatnyi értékét (amennyiben kíváncsiak vagyunk rá), illetve nullát írhatunk bele konfiguráláskor, hogy engedélyezéskor újratöltéssel kezdjünk.
A SysTick->CALIB regiszter implementációfüggő, a gyártótól függ, hogy mit valósít meg belőle. A regiszter bitkiosztása az alábbi ábrán látható.
6.b ábra: A SysTick->CALIB regiszter bitkiosztása
Az egyes bitek szerepe:
- NOREF - alternatív órajel rendelkezésre állása (0: a rendszer órajelen kívül más órajel is választható a SysTick->CTRL regiszter Clk Source bitjének 0-ba állításával, 1: Nincs más órajel választási lehetőség a CPU frekvencián kívül)
- SKEW - Jelzi, hogy TENMS (0: pontos érték, vagy 1: kerekítés eredménye)
- TENMS - Ha nem
nulla az
érték,
akkor a 10 ms időzítéshez szükséges óraütések számát adja
meg, amit a
gyártó hardveresen állít elő a regiszterben. CMSIS Core használata
esetén nincs
szükség ennek a regiszternek a használatára, mert a SystemInit() függvény
és minden
órajel konfigurálás beállítja a SystemCoreClock
változó értékét, ami a CPU órajel frekvenciáját adja meg.
Ebből a 10 ms
késleltetéshez szükséges óraütések száma egyszerűen
képezhető: SystemCoreClock/100
(vagy
az alternatív órajel választása esetén: SystemCoreClock/1600).
Ez a
szoftveres megoldás abban is rugalmasabb, hogy 10 ms-tól
eltérő
késleltetési periódus is könnyen megadhatunk.
Mintaprogramok SysTick használatához
Az alábbiakban három egyszerű programon keresztül mutatjuk be a SysTick időzítő használatát. Az elsőben a konfigurálást és a számláló pillanatnyi értékének kiolvasását mutatjuk be. A másodikban egy rövid (250 ms) késleltetéshez használjuk fel a SysTick időzítőt. A harmadik programban pedig azt mutatjuk be, hogyan használhatjuk fel a SysTick időzítőt tetszőleges hosszúságú időzítésre (a SysTick itt egy időegységnyi késleltetésre szolgál, s a köré szervezett for ciklus számlálja le az előírt számú időegységet).Program5_1: SysTick konfigurálása
Ebben a programban szabadonfutó módba állítjuk a SysTick számlálót és a periodikusan kiolvasott számláló legfelső két bitjét megjelenítjük az RGB LED zöld és piros színkomponensein, láthatóvá téve a számláló bitjeinek billegését. A megjelenítéshez a számláló értékét 4 bináris helyiértékkel jobbra léptetjük, s ezt az értéket írjuk ki a B portra. Így a számláló 23. bitje a PTB19 lábra kötött zöld LED-et, a 22. bit pedig a PTB18-ra kötött piros LED-et vezérli.1. lista: Program5_1/main.c listája
/* Program5_1
* LED-ek villogtatása a SysTick számláló felhasználásával.
*
* A program forrása: Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* Megjegyzés: A CPU frekvencia 20.97 MHz a könyvben szereplő 41 MHz helyett!
*/
#include <MKL25Z4.H>
int main (void) {
int c;
//--- A GPIOB port konfigurálása ----
SIM->SCGC5 |= 0x0400; // Port B engedélyezése (bit 10)
PORTB->PCR[18] = 0x100; // PTB18 legyen GPIO (MUX = 1)
PORTB->PCR[19] = 0x100; // PTB19 legyen GPIO (MUX = 1)
PTB->PDDR |= 0xC0000; // PTB18 és PTB19 legyen kimenet (bit18 és 19=1)
//--- SysTick konfigurálása ---------
SysTick->LOAD = 0xFFFFFF; // Újratöltés érték legyen a maximális
SysTick->VAL = 0; // Kezdéshez alaphelyzetbe állunk
SysTick->CTRL = 5; // Engedélyezés, nincs interrupt, rendszer órajel a forrás
while (1) {
c = SysTick->VAL; // Számláló kiolvasása
PTB->PDOR = c >> 4; // legfelső két bit kijelzése
}
}
Program5_2: 250 ms késleltetés SysTick használatával
Ebben a programban 250 ms késleltetésnek megfelelő számú számlálási ciklust végeztetünk a SysTick számlálóval, s figyeljük a COUNT jelzőbit bebillenését. A késleltetés leteltével átbillentjük a PTB18-ra kötött piros LED állapotát.Az újratöltési érték kiszámításánál vegyük figyelembe, hogy esetünkben az alapértelmezett CPU frekvencia eltér a Mazidi könyvben megadott értéktől! Az újratöltési értéket úgy kapjuk meg, hogy a rendszer órajel másodpercenkénti periódusainak számát (kb. 20 970 000 1/s) megszorozzuk a kívánt időtartammal (itt most 250 ms = 0,25 s).
Újratöltési érték = CPU freq. * időtartam = 20 970 000 1/s * 0,25 s = 5 242 500
Ne felejtsük el ellenőrizni, hogy az így kiszámolt érték belefér-e a 24 bites számlálóba, tehát az újratöltési érték nem lehet nagyobb 0xFFFFFF-nél, azaz 16 777 215-nél! Ez itt a fenti értéknél teljesül. Az újratöltési regiszterbe a fenti értéket eggyel csökkentve kell beírni. Ez itt most fölösleges finomkodás lenne, hiszen a belső RC oszcillátor eleve pontatlan, s a 20.97 MHz-es érték is kerekített érték.
2. lista: Program5_2/main.c listája
/* Program5_2
*
* A piros LED villogtatása a SysTick számláló felhasználásával.
* A program 250 ms-os lejáratra állítja a SysTick számlálót
* és a a piros LED állapotát átbillentjük, amikor a COUNT
* bit nullára futást jelez a SysTick->CTRL regiszterben.
*
* A program forrása: Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Freescale_ARM_codes.htm
* Megjegyzés: A CPU frekvencia nálunk 20.97 MHz a könyvben szereplő 41 MHz helyett!
*/
#include <MKL25Z4.H>
int main (void) {
int c;
//--- A GPIOB port konfigurálása ----
SIM->SCGC5 |= 0x0400; // Port B engedélyezése (bit 10)
PORTB->PCR[18] = 0x100; // PTB18 legyen GPIO (MUX = 1)
PTB->PDDR |= 0x40000; // PTB18 legyen kimenet (bit18)
//--- SysTick konfigurálása ---------
SysTick->LOAD = 5242500; // Újratöltés érték 250 ms-hoz
SysTick->VAL = 0; // Kezdéshez alaphelyzetbe állunk
SysTick->CTRL = 5; // Engedélyezés, nincs interrupt, rendszer órajel
//--- végtelen ciklus ---------------
while (1) {
if(SysTick->CTRL & 0x10000) // Ha a COUNT jelző bebillent...
PTB->PTOR = 0x040000; // billentsük át a piros LED állapotát!
}
}
Megjegyzés: Vegyük észre, hogy
a kezdeti konfigurálás után csak a COUNT
jelző figyelésével kell foglalkoznunk, mivel a számláló újratöltése, a
számlálás újrakezdése és a COUNT
jelzőbit törlése is automatikusan
történik!
Program5_3: A delayMs() újratervezése SysTick használatával
Ebben a programban a zöld LED-et villogtatjuk, 1000 ms-onként átbillentve az állapotát. A 24 bites SysTick számláló csak korlátozott időtartamú időzítést tesz lehetővé. Az előző programban bemutatott módon 1000 ms késleltetés már nem állítható elő. Ebben a programban megmutatjuk, hogyan használhatjuk fel a SysTick időzítőt tetszőleges hosszúságú időzítésre. Visszatérünk a delayMs() függvényhez, melynek belsejében most a SysTick időzítő segítségével állítunk elő egy időegységnyi késleltetést, s a köré szervezett for ciklus számlálja le az előírt számú időegységeket. Az időegységnek 1 ms-ot választunk, így az ennek megfelelő újratöltési érték a CPU frekvencia ezredrésze lesz:Újratöltési érték = CPU freq. * időtartam = 20 970 000 1/s * 0,001 s = 20 970
3. lista: Program5_3/main.c listája
/* Program5_3
*
* A zöld LED villogtatása a SysTick számláló felhasználásával.
* Ebben a programban a SysTick számlálót használjuk időzítésre
* a delayMs() függvényben.
*
* Esetünkben a rendszer órajel alapértelmezetten 20.97 MHz.
* SysTick 20970-től számlál visszafelé, ami 1 ms késleltetést ad.
* A programban szereplő 1000 késleltetési ciklus végeredményben
* 1 ms * 1000 = 1 sec időzítést eredményez, ennyi időnként váltjuk
* át a zöld LED állapotát. A zöld LED a PTB19 lábra csatlakozik.
*
* A program forrása: Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Freescale_ARM_codes.htm
* Megjegyzés: Az alapértelmezett CPU frekvencia esetünkben 20.97 MHz
* a könyvben szereplő 41 MHz helyett!
*/
#include <MKL25Z4.H>
void delayMs(int n); // Késleltető függvény
int main (void) {
SIM->SCGC5 |= 0x400; // A GPIOB port engedélyezése
PORTB->PCR[19] = 0x100; // PTB19 legyen GPIO módban!
PTB->PDDR |= 0x080000; // PTB19 legyen kimenet!
while (1) {
delayMs(1000); // 1000 ms késleltetés
PTB->PTOR = 0x080000; // Átbillentjük a zöld LED állapotát
}
}
void delayMs(int n) {
int i;
SysTick->LOAD = 20970 - 1; // Újratöltési érték 1 ms késleltetéshez
SysTick->VAL = 0; // Számláló törlése
SysTick->CTRL = 0x5; // Engedélyezés, nincs interrupt, rendszer órajel
for(i = 0; i < n; i++) {
while((SysTick->CTRL & 0x10000) == 0); // A COUNT jelzőre várunk
}
SysTick->CTRL = 0; // SysTick leállítása
}
Általános célú időzítő/számláló modulok (TPM)
Az MKL25Z128VLK4 mikrovezérlő 3 db általános felhasználású időzítő/számláló egységgel rendelkezik, melyek elnevezése (TPM0, TPM1, illetve TPM2, általánosságban TPMx) a Timer/PWM Module név rövidítéséből ered. Részletes leírásuk a Freescale KL25 Sub_Family Reference Manual 31. fejezetében található. Ezek a modulok 16-bites számlálók, amelyek szabadonfutó, illetve modulo számlálóként tudnak felfelé számlálni. A "modulo" számlálás azt jelenti, hogy a számlálás 0-tól az időzítő MOD regiszterébe beírt számig tart, utána nullánál folytatódik. Lehetőség van a le/fel számlálásra is, amikor a számlálás 0-tól MOD-ig, majd MOD-től 0-ig tart. Ez a mód különösen az ún. szimmetrikus PWM jelek (Center-Aligned PWM mód) előállításhoz fontos. Mindegyik számlálóhoz több impulzus-szélesség modulációra (PWM), bemeneti jelrögzítésre (Input Capture), vagy digitális komparálásra (Output Compare használható csatorna is kapcsolódik. TPM0 6 db csatornával, TPM1 és TPM2 pedig két-két csatornával rendelkezik. A számlálók bemenetére választhatóan külső jelek fogadására alkalmas mikrovezérlő lábat vagy belső órajelet konfigurálhatunk. A számláló előtt egy max. 7 bites előosztót is használhatunk (1, 2, 4, 8, 16, 32, 64 vagy 128-szoros előosztással).7. ábra: Egy TPM számláló/időzítő blokkvázlata
Egy TPM számláló/időzítő részegységének felépítési vázlata a 7. ábrán látható. A főbb összetevők: a bemeneti jelválasztó, az előszámláló, a modulo számláló, a modulo adatregiszter, valamint a túlcsordulást jelző és megszakításkérő áramkörök. A vezérlő bitek, illetve bitcsoportok szerepéről a konfigurálás kapcsán lesz szó.
A TPMx modulok regiszterei
A Freescale MKL25Z128VLK4 mikrovezérlő három TPM modulja hasonló regiszterkészlettel rendelkezik (az TPM0 modul több PWM csatornával rendelkezik, ezért ennek több regisztere van, mint a TPM1 és TPM2 moduloknak). A regiszterkészletek báziscímei:- TPM0 báziscíme: 0x4003 8000
- TPM1 báziscíme: 0x4003 9000
- TPM2 báziscíme: 0x4003 A000
2. táblázat: A TPM0 időzítő modul regiszterkészlete
Regiszternév |
A regiszter funkciója | Cím |
---|---|---|
TPM0_SC | Status and Control (állapotjelző
és vezérlő regiszter) |
4003_8000 |
TPM0_CNT | Counter (számláló regiszter) |
4003_8004 |
TPM0_MOD |
Modulo (számlálási határ) |
4003_8008 |
TPM0_C0SC |
Channel 0 Status and Control (0. csatorna állapotjelző és vezérlő) | 4003_800C |
TPM0_C0V |
Channel 0 Value (0. csatorna
adatregiszter) |
4003_8010 |
TPM0_C1SC | Channel 1 Status and Control (1. csatorna állapotjelző és vezérlő) | 4003_8014 |
TPM0_C1V | Channel 1 Value (1. csatorna adatregiszter) | 4003_8018 |
TPM0_C2SC | Channel 2 Status and Control (2. csatorna állapotjelző és vezérlő) | 4003_801C |
TPM0_C2V | Channel 2 Value (2. csatorna adatregiszter) | 4003_8020 |
TPM0_C3SC | Channel 3 Status and Control (3. csatorna állapotjelző és vezérlő) | 4003_8024 |
TPM0_C3V | Channel 3 Value (3. csatorna adatregiszter) | 4003_8028 |
TPM0_C4SC | Channel 4 Status and Control (4. csatorna állapotjelző és vezérlő) | 4003_802C |
TPM0_C4V | Channel 4 Value (4. csatorna adatregiszter) | 4003_8030 |
TPM0_C5SC | Channel 5 Status and Control (5. csatorna állapotjelző és vezérlő) | 4003_8034 |
TPM0_C5V | Channel 5 Value (5. csatorna adatregiszter) | 4003_8038 |
TPM0_STATUS |
Capture and Compare Status
(Jelrögzítés és komparálás státusza) |
4003_8050 |
TPM0_CONF |
Configuration (Konfiguráció) |
4003_8084 |
A TPM0_SC állapotjelző és vezérlő regiszter bitkiosztása az alábbi ábrán látható:
8. ábra: A TPMx_SC regiszter bitkiosztása
A 32 bites regiszternek csak a legalsó 9 bitjét használjuk. A w1c jelzés arra utal, hogy a TOF jelzőbitet 1 írásával lehet törölni. Az egyes bitek szerepe:
- DMA - DMA átvitel engedélyezése a TOF jelzőbitre
- TOF - Timeout jelzőbit (TOF = 1, ha a számláló értéke megegyezik a MOD regiszterbe írt adattal, és újabb impulzus érkezett)
- TOIE - Megszakításkérés
engedélyezése (0: megszakítás
tiltva, 1: megszakítás
engedélyezve)
- CPWMS - Szimmetrikus
(Center-aligned) PWM mód választása (0:
a számláló felfelé számlál, 1:
a számláló fel/le számlál)
- CMOD - Órajel választás (00: számláló letiltva, 01: belső órajel, 10: külső órajel, 11: fenntartva)
- PS - Előosztó osztási
arány választás:
000 Divide by 1
001 Divide by 2
010 Divide by 4
011 Divide by 8
100 Divide by 16
101 Divide by 32
110 Divide by 64
111 Divide by 128
A TPMx_MOD regiszter legalsó 16 bitje a számlálási modulo (körülfordulási) értéket tartalmazza. Amikor a számláló elérte ezt az értéket, és újra inkrementál, akkor '1'-be billen a TOF jelzőbit. A számláló új értéke attól függ, hogy milyen számlálási módban vagyunk. Felfelé számlálásnál a MOD értéket a 0 követi, fel/le számlálás esetén pedig MOD-1 lesz a következő érték.
A TPMx modulok konfigurálása
Az alábbiakban a legegyszerűbb üzemmód (egyszerű időzítő, TOF figyelése lekérdezéses módban) beállításának lépéseit mutatjuk be.1. A TPMx modul engedélyezése: Mielőtt valamelyik TPMx időzítőt használatba vesszük, engedélyezni a működését a System Clock Gating Control 6 (SIM_SCGC6) nevű regiszter megfelelő bitjének '1'-be állításával az alábbi ábra szerint. A SIM_SCGC6 regiszter a Rendszer-integrációs Modulhoz (SIM) tartozik, részletes leírása a Freescale KL25 Sub_Family Reference Manual 12. fejezetében található.
9. ábra: A SIM_SCGC6 regiszter bitkiosztása
A TPM0, TPM1, TPM2 bitek valamelyikének '1'-be állítása engedélyezi az adott TPMx modul órajelét, ezzel lehetővé téve annak működését. Ez az órajel a rendszerbusz frekvenciája, s nem azonos azzal az órajellel, amit a számláló bemenetére kapcsolunk, ez csupán a regiszterek írását, olvasását, s a számláló működését biztosítja.
2. Az órajel kiválasztása: amikor a TPMx modult időzítőként kívánjuk használni, akkor ismert frekvenciájú órajelet kell biztosítani a számláló bemenetén. Az órajel kiválasztása az UART0 modul esetéhez hasonló módon történik: többféle lehetőség közül választhatunk a SIM rendszer-integrációs modul SIM_SOPT2 regiszterének konfigurálásával. Azonban a választott órajel rendelkezésre állása függ az MCG órajel generátor konfigurálásától.
3. táblázat: Az előre definiált órabeállítások esetén választható TPM órajelek
MCG mód | MCGFLLCLK |
MCGPLLCLK/2 | OSCERCLK | MCGIRCLK |
---|---|---|---|---|
0 |
20.97 MHz |
---- |
---- | 32,768 kHz |
1 |
---- | 48 MHz | 8 MHz |
---- |
2 |
---- | ---- | ---- | 4 MHz |
3 |
---- | ---- | 4 MHz |
---- |
4 |
---- | 48 MHz | 8 MHz |
---- |
10. ábra: UART0 órajelének előállítása
11. ábra: A SIM_SOPT2 regiszter bitkiosztása
A SIM_SOPT2 regiszter bitcsoportjai közül TPMSRC[1:0] a TPMx modulok közös órajelének kiválasztására szolgál (00: órajel letiltva, 01: MCGFLLCLK vagy MCGPLLCLK/2, 10: OSCERCLK, 11: MCGIRCLK), a PLLFLLSEL bit az FLL vagy PLL áramkör kimenő órajelének kiválasztására szolgál (0: MCGFLLCLK, 1: MCGPLLCLK/2), s ez a bit más perifériák (pl. UART0) működésére is hatással van!
Megjegyzés: A Freescale MKL25Z128VLK4 mikrovezérlő órajelenek előállításáról és elnevezéseiről a KL25 Sub-Family Reference Manual 5. fejezetében, a SIM rendszer-integrációs modul regisztereinek szerepéről és bitkiosztásairól a 12. fejezetében, a többcélú órajel generátor (MCG) felépítéséről és konfigurálásáról pedig a 24. fejezetben találunk részletes információt.
3. Tiltsuk le a TPMx modult a konfigurálás idejére: írjunk nullát a TPMx_SC regiszterbe!
4. Töltsük fel a modulo regisztert: a megfelelő értéket írjuk be a TPMx_MOD regiszterbe!
5. Töröljük a TOF jelzőbitet: bármilyen meglepő, a törléshez 1-et kell írnunk a TPMx_SC regiszter TOF bitjébe!
6. Töröljük a számláló regisztert: írjunk nullát a TPMx_CNT regiszterbe!
7. Engedélyezzük a számláló működését a megfelelő üzemmód beállításával együtt: egyszerű időzítéshez a TPMx_SC regiszter CMOD bitcsoportját állítsuk 01-be, a PS bitcsoportot pedig állítsuk be a kívánt előszámlálási aránynak megfelelően (000: 1x, 001: 2x, 010: 4x, ... 111: 127x leosztás)!
8. Az időzítéshez: várjunk addig, amíg a TOF jelzőbit '1' nem lesz!
Program5_4: időzítés TPM0-val
Ebben a program kék LED-et villogtatjuk, s a TPM0 időzítőt használjuk a késleltetés előállításához. Esetünkben a rendszer órajel alapértelmezetten 20.97 MHz. A TPM0 16 bites számlálója legfeljebb 65536/20 970 000 Hz = kb. 3,125 ms késleltetést biztosít számunkra. A programban ezért egy for ciklusban 160 darab túlcsordulást várunk meg, mielőtt átváltanánk a kék LED állapotát. Végeredményben tehát 3,125 ms * 160 = 500 ms telik el két állapotváltás között. A kék LED a PTD1 lábra csatlakozik, ezt a lábat GPIO kimenetnek kell konfigurálnunk.4. lista: Program5_4/main.c listája
/* Program5_4
*
* Ebben a program kék LED-et villogtatjuk, s a TPM0 időzítőt
* használjuk a késleltetés előállításához.
*
* A program forrása: Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Freescale_ARM_codes.htm
* Megjegyzés: Az alapértelmezett CPU frekvencia esetünkben 20.97 MHz
* a könyvben szereplő 41 MHz helyett!
*/
#include <MKL25Z4.H>
int main (void) {
int i;
SIM->SCGC5 |= 0x1000; // A D port engedélyezése
PORTD->PCR[1] = 0x100; // PTD1 pin legyen GPIO módban!
PTD->PDDR |= 0x02; // PTD1 legyen kimenet!
SIM->SCGC6 |= 0x01000000; // A TPM0 időzítő engedélyezése
SIM->SOPT2 |= 0x01000000; // MCGFLLCLK legyen az órajel!
TPM0->SC = 0; // Konfiguráláshoz letiltjuk az időzítőt
TPM0->MOD = 0xFFFF; // Maximális modulo érték (65536-1)
TPM0->CNT = 0; // A számláló törlése
TPM0->SC |= 0x80; // TOF törlése
TPM0->SC |= 0x08; // Számláló engedélyezése (CMOD=01, PS=000)
while (1) {
for(i = 0; i < 160; i++) {
while(!(TPM0->SC&0x80));// TOF-ra várunk...
TPM0->SC |= 0x80; // TOF törlése
}
PTD->PTOR = 0x02; // Kék LED (PTD1) átbillentése
}
}
Program5_5: A TPM0
előosztójának használata
Ebben a program is a kék LED-et villogtatjuk, s a TPM0
időzítőt használjuk a késleltetés előállításához. A késleltetési
idő megnyújtásához azonban most nem for ciklushoz folyamodunk (több
túlcsordulás kivárásával), hanem a bemenő jel frekvenciáját osztjuk le
a TPM0 előosztójának
bekapcsolásával. A maximális, 128-szoros leosztás és a maximális modulo
érték 65536 * 128 / 20 970 000 Hz = kb. 400 ms
késleltetést biztosít számunkra. Végeredményben tehát 400
ms telik el két
állapotváltás között. A kék LED a PTD1 lábra csatlakozik, ezt a lábat
GPIO kimenetnek kell konfigurálnunk.5. lista: Program5_5/main.c listája
/* Program5_5
*
* Ebben a program kék LED-et villogtatjuk, s a TPM0 időzítőt
* használjuk a késleltetés előállításához.
*
* A program forrása: Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Freescale_ARM_codes.htm
*/
#include <MKL25Z4.H>
int main (void) {
SIM->SCGC5 |= 0x1000; // A D port engedélyezése
PORTD->PCR[1] = 0x100; // PTD1 pin legyen GPIO módban!
PTD->PDDR |= 0x02; // PTD1 legyen kimenet!
SIM->SCGC6 |= 0x01000000; // A TPM0 időzítő engedélyezése
SIM->SOPT2 |= 0x01000000; // MCGFLLCLK legyen az órajel!
TPM0->SC = 0; // Konfiguráláshoz letiltjuk az időzítőt
TPM0->SC = 0x07; // Az előszámláló leosztása 128 legyen!
TPM0->MOD = 0xFFFF; // Maximális modulo érték (65536-1)
TPM0->CNT = 0; // A számláló törlése
TPM0->SC |= 0x80; // TOF törlése
TPM0->SC |= 0x08; // Számláló engedélyezése (CMOD=01)
while (1) {
while(!(TPM0->SC&0x80)); // TOF-ra várunk...
TPM0->SC |= 0x80; // TOF törlése
PTD->PTOR = 0x02; // Kék LED (PTD1) átbillentése
}
}
Program5_6: A TPM1
időzítő használata
Ez a program lényegeben megegyezik a Program5_5
mintapéldával, ebben is a kék LED-et villogtatjuk, de most a TPM1
időzítőt használjuk a késleltetés előállításához. A programban a TPM0 -> TPM1 átnevezések mellett ügyeljünk
arra, hogy a SIM->SCGC6
regiszterben is egy másik bitet kell '1'-be állítanunk (lásd a 9.
ábrán)!6. lista: Program5_6/main.c listája
/* Program5_6
*
* Ebben a programban a TPM1 időzítőt használjuk.
* Ettől eltekintve megegyezik a Program5_5 mintapéldával.
*
* A program forrása: Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Freescale_ARM_codes.htm
*/
#include <MKL25Z4.H>
int main (void) {
SIM->SCGC5 |= 0x1000; // A D port engedélyezése
PORTD->PCR[1] = 0x100; // PTD1 pin legyen GPIO módban!
PTD->PDDR |= 0x02; // PTD1 legyen kimenet!
SIM->SCGC6 |= 0x02000000; // TPM1 időzítő engedélyezése
SIM->SOPT2 |= 0x01000000; // MCGFLLCLK legyen a TPM órajel!
TPM1->SC = 0; // TPM1 letiltása a konfiguráláshoz
TPM1->SC = 0x07; // Az előszámláló leosztása: 128
TPM1->MOD = 0xFFFF; // Maximális modulo érték (65536-1)
TPM1->CNT = 0; // A számláló törlése
TPM1->SC |= 0x80; // TOF törlése
TPM1->SC |= 0x08; // Számláló engedélyezése (CMOD=01)
while (1) {
while(!(TPM1->SC&0x80)); // TOF-ra várunk...
TPM1->SC |= 0x80; // TOF törlése
PTD->PTOR = 0x02; // Kék LED (PTD1) átbillentése
}
}
Program5_7: Hosszabb
időzítés kisfrekvenciás órajellel
A TPM modul regisztereinek
írása és a belső működése ugyan a rendszerbusz órajelével
szinkronizált, de a számláló bemenetére aszinkron órajel is
kapcsolható. Ezt a lehetőséget használjuk ki az alábbi példában, ahol a
32,768 kHz-es MCGIRCLK
órajelet választjuk ki TPM órajelnek, s így az előzőeknél jóval
hosszabb időzítéseket is előállíthatunk. A Program5_7 mintapéldában a kék LED-et villogtatjuk, a TPM0 időzítőt használjuk a késleltetés előállításához, s az MCGIRCLK órajelet választjuk ki TPM órajelnek. A TPM0 időzítő előosztóját 32-szeres leosztásra konfiguráljuk, így 1024 számláló inkrementálás 1 s késleltetésnek felel meg. A 16 bites számlálóval így kb. 1 ms - 64 s közötti időzítéseket állíthatunk be (most a ms valójában 1/1024 s időzítést jelent, ennek egész számú többszöröseit állíthatjuk be). A programban szereplő 5120-1 modulo beállítással tehát azt érjük el, hogy a LED állapotváltásai között 5 s telik el.
A Mazidi könyv Program5_7 mintapéldája egy kompatibilitási problémát is felszínre hozott: az újabb kiadású (v2.50) RTE Device Startup másképp inicializálja az MKL25Z4 mikrovezérlőket, mint a korábbi kiadás. Ez nem csupán a CPU frekvenciában jelent eltérést (20.97 MHz a v1.x kiadásokban szereplő 41.94 MHz helyett), hanem abban is, hogy a többcélú órajel generátor alapértelmezett beállításában nincs engedélyezve az MCGIRCLK használata.
Ennek a problémának a megoldására két lehetőség is van:
- Ne hagyatkozzunk az alapértelmezésre, hanem explicit módon adjuk meg a kiválasztott, előre definiált órajel generátor beállítást, akkor is, ha a 0. konfigurációt választjuk! Ehhez a system_MKL25Z4.h állományba egyszerűen szúrjuk be a #define CLOCK_SETUP 0 sort.
- Magunk is engedélyezhetjük az az MCGIRCLK használatát, ha az MCG->C1 regiszter "Internal Reference Clock Enable" (IRCLKEN) bitjét '1'-be állítjuk.
7. lista: Program5_7/main.c listája
/* Program5_7
*
* Kék LED villogtatása TPM0 időzítéssel, 32 kHz-es órajellel.
*
* Ebben a programban a 32.768 kHz-es belső oszcillátor jelét
* használjuk fel, 32-szeres előosztóval, tehát 1024 inkrementálás
* jelent 1 s időzítést, így a 16 bites számlálóval több másodperces késleltetés
* is könnyen realizálható. A programban szereplő 5 * 1024 = 5120 inkrementálással
* 5 s idő telik el a kék LED (PTD1) két állapotváltása közben.
*
* A program forrása: Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Freescale_ARM_codes.htm
*/
#include <MKL25Z4.H>
int main (void) {
MCG->C1 |= 2; // Enables IRCLK for use as MCGIRCLK
SIM->SCGC5 |= 0x1000; // A D port engedélyezése
PORTD->PCR[1] = 0x100; // PTD1 pin legyen GPIO módban!
PTD->PDDR |= 0x02; // PTD1 legyen kimenet!
SIM->SCGC6 |= 0x01000000; // A TPM0 időzítő engedélyezése
SIM->SOPT2 |= 0x03000000; // MCGIRCLK legyen a TPM órajel
TPM0->SC = 0; // Konfiguráláshoz letiltjuk az időzítőt
TPM0->SC = 0x05; // Előosztási arány 32 legyen
TPM0->MOD = 5120 - 1; // 0 - 5119-ig számlálunk (5 sec)
TPM0->SC |= 0x80; // TOF törlése
TPM0->SC |= 0x08; // Számláló engedélyezése (CMOD=01)
while (1) {
while(!(TPM0->SC&0x80)); // TOF-ra várunk...
TPM0->SC |= 0x80; // TOF törlése
PTD->PTOR = 0x02; // Kék LED (PTD1) átbillentése
}
}
A TPM modulokhoz
kapcsolódó csatornák
Ahogy a TPM modulok
bevezetőjében említettük, az MKL25Z128VLK4
mikrovezérlő
3 db általános felhasználású időzítő/számlálójának mindegyikéhez több
olyan "csatorna" (kiegészítő áramkör) is kapcsolódik, amelyek
impulzus-szélesség modulációra
(PWM), bemeneti jelrögzítésre (Input Capture), vagy digitális
komparálásra (Output Compare
használhatók. A TPM0 időzítő 6
db ilyen csatornával, TPM1
és TPM2 pedig két-két
csatornával
rendelkezik. A TPM modulok és a csatornák kapcsolatát az alábbi ábra
szemlélteti.12. ábra: A TPM időzítő modulok és a hozzá kapcsolódó csatornák blokkvázlata
TPMx_CnV - a csatorna adatregisztere
Mindegyik csatornához eljut a TPM modulo számláló regiszterének pillanatnyi értéke, s mindegyik csatorna rendelkezik egy-egy 16 bites írható/olvasható adatregiszterrel (a fenti ábrán a C0V, ..., CNV) amely az alábbi lehetőségeket nyújtja:- a modulo számláló pillanatnyi értékének rögzítésére adott esemény bekövetkeztekor (Input Capture)
- a modulo számláló pillanatnyi értékének összehasonlítására egy előre megadott számmal, s egyezés esetén egy kimenet állapotának megváltoztatására (Output Compare)
- Impulzus-szélesség moduláció egy kimenet vezérlésével a modulo számláló pillanatnyi értéke és egy előre megadott szám egyezése alapján
TPMx_CnSC - a csatorna állapotjelző és vezérlő regisztere
Azt, hogy az adott csatorna milyen módban működjön, a hozzá tartozó vezérlő regiszterben állíthatjuk be. A csatorna állapotjelző és vezérlő (Status and Control) regiszterek általános neve TPMx_CnSC, ahol x és n jelentése ugyanaz, mint az adatregisztereknél. A TPMx_CnSC regiszter bitkiosztása az alábbi ábrán látható. A 32 bites regiszternek csak az alsó 8 bitje van használatban.13. ábra: TPMx_CnSC regiszter bitkiosztása
Az egyes bitek szerepe:
- CHF - Csatorna jelzőbit, amely hardveresen '1'-be áll, ha a csatornához rendelt adott esemény bekövetkezett. A jelzőbit törlése '1' beírásával történik!
- CHIE - Csatornához rendelt esemény esetén megszakítás (0: tiltása, 1: engedélyezése)
- MSB:MSA - módválasztó bitek (lásd külön táblázatban!)
- ELSB:ELSA - Él vagy kimeneti szint választó bitek (lásd külön táblázatban!)
- DMA - DMA átvitel
engedélyezése
4. táblázat: A TPM IC/OC/PWM csatornák beállítható üzemmódjai
CPWMS |
MSB:MSA |
ELSB:ELSA |
Üzemmód |
Konfiguráció |
---|---|---|---|---|
x |
00 |
00 |
nincs |
csatorna letiltva |
x |
01/10/11 |
00 |
komparálás szoftveres vezérléssel |
nincs hardveres kimenetvezérlés |
0 |
00 |
01 |
Bemeneti
jelrögzítés (Input Capture) |
rögzítés felfutó élnél |
10 |
rögzítés lefutó élnél |
|||
11 |
rögzítés mindkét élnél |
|||
01 |
01 |
kimenetvezérlés
digitális összehasonlítással (Output Compare) |
kimenet átbillentése egyezéskor |
|
10 |
kimenet törlése egyezéskor |
|||
11 |
kimenet '1'-be állítása
egyezéskor |
|||
10 |
10 |
Él
igazított jelű PWM |
kimenet törlése egyezéskor | |
x1 |
kimenet '1'-be állítása egyezéskor | |||
11 |
10 |
impulzus
módú kimenetvezérlés digitális összehasonlítással (Output Compare) |
negatív impulzus egyezéskor |
|
x1 |
pozitív impulzus egyezéskor |
|||
1 |
10 |
10 |
Középre
igazított jelű PWM |
pozitív impulzus jelalak |
x1 |
negatív impulzus jelalak |
TPMx_STATUS - a TPMx modul állapotjelző regisztere
A TPMx_STATUS állapotjelző regiszter nem valamelyik csatornához tartozik, hanem a TPMx időzítő modulhoz, s benne kigyűjtve megtalálható valamennyi csatorna CHF jelzőbitjének másolata és a TPMx számláló TOF túlcsordulásjelző bitje is. A TPMx_STATUS regiszter bitkiosztása az alábbi ábrán látható. A 32 bites regiszternek csak az alsó 8 bitje van használatban. A w1c bejegyzések arra utalnak, hogy mindegyik jelzőbit '1' beírásával törölhető. A működés szempontjából mindegy, hogy a jelzőbiteket ebben a gyűjtőregiszterben figyeljük/töröljük, vagy az egyes csatornaregiszterekben külön-külön. Több jelzőbit együttes figyelése nyilván ebben a gyűjtőregiszterben egyszerűbb, kényelmesebb.14. ábra: A TPMx_STATUS regiszter bitkiosztása
A csatornák kivezetései
Mindegyik TPMx modul mindegyik csatornájához külön kivezetés rendelhető, s általában egynél több lehetőség közül választhatunk. Például a TPM0 modul CH0 csatornájához a PTA3, PTC1, PTD1 vagy a PTE24 kivezetések közül választhatunk. A választás a megfelelő PORTx_PCRn portvezérlő regiszter MUX bitcsoportjába írt számmal történik (Alt3 vagy Alt4 funkciót kell választanunk, ahogy az alábbi táblázat, illetve a FRDM-KL25Z Pinouts dokumentum jelzi). A hardverütközések kiszűrésével a FRDM-KL25Z kártya esetében az alábbi lehetőségek közül választhatunk:5. táblázat: A TPMx_CHn időzítő csatornákhoz választható kivezetések (zárójelben az Alt funkció sorszáma)
Időzítő |
Csatorna |
Kivezetés |
---|---|---|
TPM0 |
CH0 |
PTC1 (4), PTD1 (4) |
CH1 |
PTA4 (3), PTC2 (4), PTD1 (4) |
|
CH2 |
PTA5 (3), PTC3 (4), PTD2 (4), PTE29 (3) |
|
CH3 |
PTC4 (4), PTD3 (4), PTE30 (3) |
|
CH4 |
PTC8 (3), PTD4 (4), PTE31 (3) |
|
CH5 |
PTC9 (3), PTD5 (4) |
|
TPM1 |
CH0 |
PTA12 (3), PTB0 (3), PTE20 (3) |
CH1 |
PTA13 (3), PTB1 (3), PTE21 (3) | |
TPM2 |
CH0 |
PTA1 (3), PTB2 (3), PTB18 (3), PTE22 (3) |
CH1 |
PTA2 (3), PTB3 (3), PTB19 (3), PTE23 (3) |
Az Output Compare mód
Ha egy csatorna Output Compare (kimenetvezérlés digitális összehasonlítással) módban van (MSB:MSA = 01 vagy 11), amikor a hozzá tartozó TPMx_CNT számláló felfelé számlál, akkor a számlálás 0-tól indul, s a számláló pillanatnyi értéke minden léptetéskor összehasonlításra kerül a csatorna TPMx_CnV adatregiszterének tartalmával. Ha egyezés van, akkor a csatorna CHF jelzőbitje '1'-be áll, s a csatornához rendelt kimenet állapota megváltozik az ELSb:ELSa-ban kiválasztott módon. A számlálás folytatódik a TPMx_MOD regiszterben megadott értékig, majd a számláló túlcsordul és újrakezdi a számlálást.MSB:MSA = 01 módban az alábbi kimenetvezérlési lehetőségek közül választhatunk:
- Kimenet átbillentése egyezéskor
(toggle output on match) - Amikor a TPMx_CNT
számláló pillanatnyi
értéke megegyezik a csatorna TPMx_CnV
adatregiszterének tartalmával, akkor a csatornához
rendelt kimenet ellenkező állapotba billen.
- Kimenet törlése egyezéskor (clear output on match) - Amikor az üzemmódot beállítjuk, a kimenet '1'-be áll, majd amikor a TPMx_CNT számláló pillanatnyi értéke megegyezik a csatorna TPMx_CnV adatregiszterének tartalmával, akkor a csatornához rendelt kimenet '0' állapotba billen.
- Kimenet beállítása egyezéskor (set output on match) - Amikor az üzemmódot beállítjuk, a kimenet '0'-be áll, majd amikor a TPMx_CNT számláló pillanatnyi értéke megegyezik a csatorna TPMx_CnV adatregiszterének tartalmával, akkor a csatornához rendelt kimenet '1' állapotba billen.
- Első konfiguráláskor a "kimenet törlése", illetve "kimenet beállítása" üzemmódok konfigurálásakor a csatornához rendelt kimenet automatikusan az ellenkező állapotba áll be (kimenet törlése módban '1'-be, kimenet beállítása módban '0'-ba).
- Újabb konfiguráláshoz törölni kell a TPMx_CnSC regisztert, s meg kell várni annak érvényesülését (a TPMx_CnSC regiszter beírása akkor érvényesül, amikor TPMx előszámlálója túlcsordul, s TPMx_CNT számláló lép egyet).
- Pozitív impulzus - Amikor a TPMx_CNT számláló pillanatnyi értéke megegyezik a csatorna TPMx_CnV adatregiszterének tartalmával, akkor a csatornához rendelt kimenet egy órajel időtartamra magas szintre vált, majd visszavált az alapértelmezett alacsony szintre.
- Negatív impulzus - Amikor
a TPMx_CNT számláló
pillanatnyi értéke megegyezik a csatorna TPMx_CnV adatregiszterének
tartalmával, akkor a csatornához rendelt kimenet egy
órajel időtartamra alacsony szintre vált, majd visszavált az
alapértelmezett magas szintre.
Program5_8: kimenet billegtetése Output Compare használatával
Ebben a példaprogramban a TPM0_CH1 csatornát használjuk Output Compare módban periodikus kimenő jel előállítására a PTD1 kimeneten (kék LED). Az MCGFLLCLK (20.97 MHz) órajelet választjuk TPM órajelnek, melyet az előosztóval 128-szorosan leosztunk. A TPM0_CH1 csatornát Output Compare Toggle (átbillentés) módba állítjuk és a PTD1 kimenetet (kék LED) vezéreljük vele. Minden alkalommal, amikor TPM0_CNT és TPM0_C1V megegyeznek, a kimenet állapota átbillen, s a programban TPM0_C1V értékét 32766-vel megnöveljük, így a következő egyezés 32766 * 128 / 20 970 000 Hz = kb. 200 ms múlva lesz. A program tehát a kék LED-et villogtatja kb. 2.5 Hz frekvenciával (felváltva 200 ms "BE", majd 200 ms "KI" állapot váltakozik).A konfigurálás lépései:
- Engedélyezzük a D portot (SIM->SCGC5: bit12 = 1)
- A PTD1 kivezetés TPM0CH1 (Alt4) funkcióját választjuk (PORTD->PCR[1]: MUX = 4)
- Engedélyezzük a TPM0 modult (SIM->SCGC6: bit24 = 1)
- Konfiguráljuk a TPM modulok közös órajelét (SIM->SOPT2: TPMSRC = 01, PLLFLLSEL = 0)
- Letiltjuk a TPM0 modul számlálóját a konfigurálás idejére (TPM0->SC = 0)
- Beállítjuk TPM0 előszámlálóját (TPM0_SC: PS = 111)
- Beállítjuk TPM0 modulo regiszterét (TPM0_MOD = 0xFFFF)
- Beállítjuk a TPM0_C1SC vezérlő regiszterben az OC toggle módot (MSB:MSA=01, ELSB:ELSA=01)
- Töröljük a TPM0_C1SC regiszterben a CHF jelzőt
- Beállítjuk az első késleltetési ciklust (TPM0_C1V = 32766)
- Elindítjuk a számlálót (TPM0_SC: CMOD = 01)
- Várunk a TPM0 CH1 csatorna CHF jelzőjére (TPM0_C1SC: CHF = 1 eseményre várunk)
- Töröljük TPM0 CH1 csatorna CHF jelzőjét (TPM0_C1SC: a CHF = 1 beírás töröl)
- Új időpont beállítása (TPM0_C1V értékét növeljük meg 32766-tal)
8. lista: Program5_8/main.c listája
/* Program5_8
*
* Ez a program a TPM0_CH1 OC csatornát használja
* periodikus kimenő jel előállítására. Az MCGFLLCLK (20.97 MHz)
* órajelet választjuk TPM órajelnek. Az előosztót 128-szoros leosztásra állítjuk.
* A TPM0_CH1 csatornát Output Compare Toggle (átbillentés) módba állítjuk
* és a PTD1 kimenetet (kék LED) vezéreljük vele.
* Minden alkalommal, amikor TPM0_CNT és TPM0_C1V megegyeznek,
* a kimenet állapota átbillen, s a programban TPM0_C1V értékét
* 32766-vel megnöveljük, így a következő egyezés
* 32766 * 128 / 20 970 000 Hz = kb. 200 ms múlva lesz.
*
* A program forrása: Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Freescale_ARM_codes.htm
*/
#include <MKL25Z4.H>
int main (void) {
SIM->SCGC5 |= 0x1000; // A D port engedélyezése
PORTD->PCR[1] = 0x400; // PTD1 legyen TPM0CH1 kimenet
SIM->SCGC6 |= 0x01000000; // A TPM0 időzítő engedélyezése
SIM->SOPT2 |= 0x01000000; // MCGFLLCLK legyen a TPM órajel
TPM0->SC = 0; // Konfiguráláshoz letiltjuk az időzítőt
TPM0->SC = 0x07; // Előosztási arány 128 legyen
TPM0->MOD = 0xFFFF; // Maximális modulo érték
TPM0->CNT = 0; // A számláló törlése
TPM0->CONTROLS[1].CnSC = 0x14; // OC Toggle mód
TPM0->CONTROLS[1].CnSC |= 0x80; // CHF jelző törlése
TPM0->CONTROLS[1].CnV = 32766; // 200 ms múlva legyen egyezés
TPM0->SC |= 0x08; // TPM0 számláló indítása
while (1) {
while(!(TPM0->CONTROLS[1].CnSC & 0x80)) { } // CHF jelzőre várunk
TPM0->CONTROLS[1].CnSC |= 0x80; // CHF jelző törlése
TPM0->CONTROLS[1].CnV += 32766; // 200 ms múlva újabb egyezés
}
}
Mintaprogram: OC_flash
A Kimenet átbillentése
(toggle) módnál valamivel bonyolultabb a Kimenet törlése egyezéskor (clear
output on match), illetve a Kimenet
beállítása egyezéskor (set output on match)
üzemmódok használata és működése. Ezekkel lényegében szabályozott
szélességű impulzusokat tudunk előállítani. Amikor ezen az üzemmódok
valamelyikét beállítjuk, a kimenet a választott állapot ellenkezőjére
áll be (Kimenet törlése választásakor '1'-be, Kimenet beállítása
választásakor pedig 0-ba), majd a számláló és az adatregiszterben
előírt érték egyezésekor ellenkező állapotba vált.
Ha ismételni akarjuk az impulzust, akkor először le kell tiltanunk az Output Compare módot, meg kell várni ennek érvényesülését (TOF flag vagy számláló változásának figyelésével), majd újra kell konfigurálnunk az OC módok valamelyikét.
Az alábbi programban a TPM0 modul CH1 csatornáját használjuk kb. 100 ms szélességű impulzusok keltésére Output Compare módban, s a PTD1 kivezetést (kék LED) villogtatjuk vele. Ahhoz, hogy az impulzus elegendően hosszú (100 ms) lehessen, alacsony frekvenciájú órajelet, a 32.768 kHz-es belső oszcillátor jelét használjuk fel TPM órajelként. A következő villantáshoz megvárjuk a szabadonfutó módban számláló TPM0_CNT túlcsordulását, így a villantások között 2 s telik el. A közös anódú RGB LED vezérlése negatív logikájú jelekkel történik, ezért a Kimenet beállítása módot kell használnunk.
A program végtelen ciklusában két esemény bekövetkeztére várunk:
- Amikor az egyezéskor (a 100 ms-os villantás végén) a CHF1 jelzőbit bebillen, akkor töröljük a jelzőt és letiltjuk a csatorna OC módját.
- Amikor pedig túlcsordul a számláló, akkor töröljük a bebillen TOF jelzőbitet, majd újraindítjuk az
OC Kimenet beállítása
módot (elindítjuk az újabb villantást).
9. lista: OC_flash/main.c listája
/* OC_flash
*
* Kék LED villantás TPM0_CH0 OC időzítéssel, 32 kHz-es órajellel.
*
* Ebben a programban a TPM0 modul CH1 csatornáját használjuk
* adott szélességű impulzusok keltésére Output Compare módban,
* s a PTD1 kivezetést (kék LED) vezéreljük vele. Ahhoz, hogy az
* impulzus elegendően hosszú (100 ms) lehessen, alacsony
* frekvenciájú órajelet, a 32.768 kHz-es belső oszcillátor jelét
* használjuk fel TPM órajelként.
*/
#include <MKL25Z4.H>
int main (void) {
MCG->C1 |= 2; // IRCLK lehessen MCGIRCLK forrás
SIM->SCGC5 |= 0x1000; // A D port engedélyezése
PORTD->PCR[1] = 0x400; // PTD1 pin legyen FTM0_CH1 módban!
SIM->SCGC6 |= 0x01000000; // A TPM0 időzítő engedélyezése
SIM->SOPT2 |= 0x03000000; // MCGIRCLK legyen a TPM órajel
TPM0->SC = 0; // Konfiguráláshoz letiltjuk az időzítőt
TPM0->MOD = 0xFFF0; // Szabadonfutó mód, periódus = 2 sec
TPM0->SC |= 0x80; // TOF törlése
TPM0->SC |= 0x08; // Számláló engedélyezése (CMOD=01)
TPM0->CONTROLS[1].CnSC = 0x1C; // OC, Set high
TPM0->CONTROLS[1].CnSC |= 0x80; // CHF jelző törlése
TPM0->CONTROLS[1].CnV = 3276; // 100 ms múlva legyen egyezés
while (1) {
if(TPM0->STATUS&0x02) { // CHF1-re vártunk...
TPM0->STATUS |= 0x02; // CHF1 törlése
TPM0->CONTROLS[1].CnSC = 0; // Csatorna letiltása
}
if(TPM0->SC&0x80) { // TOF-ra vártunk...
TPM0->SC |= 0x80; // TOF törlése
TPM0->CONTROLS[1].CnV = 3276; // 100 ms múlva legyen egyezés
TPM0->CONTROLS[1].CnSC = 0x1C; // OC, Set high
}
}
}
Input Capture - bemeneti jelrögzítés
Bemeneti jelrögzítés módban egy I/O kivezetésen keresztül vezetjük be azt a jelet, melynek átmenetei időpontját rögzíteni kívánjuk. Amikor egy esemény bekövetkezik, a TPMx_CNT számláló állása átmásolásra és eltárolásra kerül a csatorna TPMx_CnV regiszterében, míg a számláló tovább számlál. A számláló értékének rögzítésekor a csatorna CHF jelzőbitje is bebillen.A bemeneti jelrögzítés konfiguráláshoz a csatorna TPMx_CnSC vezérlő regiszterében az MSB:MSA biteket 00-ra kell állítani, a TPMx_CHn bemenet ilyenkor él-érzékeny (edge sensitive) állapotban működik. Az ELSB és ELSA bitekkel állítjuk be, hogy felfutó, lefutó, vagy mindkét él bekövetkeztekor rögzítsük a számláló állapotát (bővebben lásd a 4. táblázatnál). A TPMx_CHn bemenet kiválasztása és konfigurálása ugyanúgy történik, mint az Output Compare módnál.
Program5_9:
periódusidő meghatározása bemeneti jelrögzítéssel
Ebben a programban bemeneti jelrögzítés módban használjuk a TPM2_CH0 csatornát, periodikus
hullámforma periódusidejének mérésére. TPM órajel gyanánt az
alapértelmezett (20.97 MHz) MCGFLLCLK
órajelet használjuk, amelyet a TPM előszámlálója segítségével néggyel
leosztunk. Így TPM2 számlálója 20.97 MHz / 4 = 5 242 500 Hz
frekvenciájú jelet számlál.A TPM2 modul 0. csatornáját bemeneti jelrögzítésre konfiguráljuk és a mikrovezérlő PTA1 kivezetését használjuk bemenetként, így az UART0 bejövő jeleit vizsgálhatjuk vele, ha a bitrátát 9600 bps-re vagy kisebbre állítjuk. Amikor a PTA1 bemenetén felfutó él érzékelhető, a TPM2_CNT számláló pillanatnyi értéke átmásolódik a TPM2_C0V regiszterbe és a CHF jelzőbit '1'-be áll.
A program a CHF bit bebillenésére vár, majd meghatározza a jelenlegi és a legutóbbi esemény között eltelt időt. Az eredmény 11..9 bitjeit kijelezzük az RGB LED-en. A LED színe változik, ha a frekvencia 10 kHz alatt van (nagyobb frekvenciák esetén egy periódus alatt az impulzusok száma nem éri el a 9. bitet).
Használjuk a Termite (vagy más, hasonló) terminál emulátor programot egy karaktersorozat kiküldésére, majd figyeljük az eredményt!
Megjegyzés: Bitenként változó jelsorozathoz küldjünk A55AA55A... karaktereket!
A bemeneti jelrögzítés konfigurálásának lépései:
- Engedélyezzük a A portot (SIM->SCGC5: bit9 = 1)
- A PTA1 kivezetés TPM2CH0 (Alt4) funkcióját választjuk (PORTA->PCR[1]: MUX = 3)
- Engedélyezzük a TPM2 modult (SIM->SCGC6: bit26 = 1)
- Konfiguráljuk a TPM modulok közös órajelét (SIM->SOPT2: TPMSRC = 01, PLLFLLSEL = 0)
- Letiltjuk a TPM2 modul számlálóját a konfigurálás idejére (TPM2->SC = 0)
- Beállítjuk TPM2 előszámlálóját (TPM2_SC: PS = 010)
- Beállítjuk TPM2 modulo regiszterét (TPM2_MOD = 0xFFFF)
- Beállítjuk a TPM2_C0SC vezérlő regiszterben az IC up módot (MSB:MSA=00, ELSB:ELSA=01)
- Töröljük a TPM2_C0SC regiszterben a CHF jelzőt
- Elindítjuk a számlálót (TPM2_SC: CMOD = 01)
- Várunk TPM2 CH0 csatorna CHF jelzőjére (TPM2_C0SC: CHF = 1 eseményre várunk)
- Töröljük TPM2 CH0 csatorna CHF jelzőjét (TPM2_C0SC: a CHF = 1 beírás töröl)
- A jelenlegi és az előző eseménynél eltárolt TPM2_C0V értékek különbségét
képezzük, s az RGB LED-en megjelenítjük annak 11..9 bitjeit.
/* Program5_9
*
* Ez a program a TPM2_CH0 csatornát használja bemeneti
* jelrögzítés módban periodikus hullámforma periódusidejének mérésére.
*
* A program a CHF bit bebillenésére vár, majd meghatározza a jelenlegi
* és a legutóbbi esemény között eltelt időt. Az eredmény 11..9 bitjeit
* kijelezzük az RGB LED-en. A LED színe változik, ha a frekvencia
* 10 kHz alatt van (nagyobb frekvenciák esetén egy periódus alatt az
* impulzusok száma nem éri el a 9. bitet).
*
* A program forrása: Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Freescale_ARM_codes.htm
*/
#include <MKL25Z4.H>
int main (void) {
unsigned short then = 0;
unsigned short now = 0;
unsigned short diff;
//--- A GPIO kivezetések konfigurálása az RGB LED-hez ----
SIM->SCGC5 |= 0x400; // B port engedélyezése
SIM->SCGC5 |= 0x1000; // D port engedélyezése
PORTB->PCR[18] = 0x100; // PTB18 GPIO módba állítása
PTB->PDDR |= 0x40000; // PTB18 kimenet legyen
PORTB->PCR[19] = 0x100; // PTB19 GPIO módba állítása
PTB->PDDR |= 0x80000; // PTB19 kimenet legyen
PORTD->PCR[1] = 0x100; // PTD1 GPIO módba
PTD->PDDR |= 0x02; // PTD1 kimenet legyen
//--- Timer konfigurálás -----------------------------------
SIM->SCGC5 |= 0x0200; // A port engedélyezés
PORTA->PCR[1] = 0x0300; // PTA1 TPM2CH0 módba állítása
SIM->SCGC6 |= 0x04000000; // TPM2 engedélyezés
SIM->SOPT2 |= 0x01000000; // MCGFLLCLK legyen a TPM órajel
TPM2->SC = 0; // Időzítő letiltása konfiguráláshoz
TPM2->SC = 0x02; // Előszámláló: /4
TPM2->MOD = 0xFFFF; // Szabadonfutó mód
TPM2->CONTROLS[0].CnSC = 0x04; // IC mód, felfutó élre
TPM2->SC |= 0x08; // Számláló engedélyezés
while (1) {
while(!(TPM2->CONTROLS[0].CnSC & 0x80)); // CHF jelzőre várunk
TPM2->CONTROLS[0].CnSC |= 0x80; // CHF törlése
now = TPM2->CONTROLS[0].CnV; // A rögzített érték kiolvasása
diff = now - then; // Az időtartam számítása
then = now; // Az új érték lesz a vonatkoztatási pont
//--- LED-e beállítása az időtartam 11..9 bitjei szerint
diff = diff >> 9;
if (diff & 1) // Piros LED beállítása bit9 szerint
PTB->PCOR = 0x40000;// LED = be
else
PTB->PSOR = 0x40000;// LED = ki
if (diff & 2) // Zöld LED beállítása bit10 szerint
PTB->PCOR = 0x80000;
else
PTB->PSOR = 0x80000;
if (diff & 4) // Kék LED beállítása bit11 szerint
PTD->PCOR = 0x02;
else
PTD->PSOR = 0x02;
}
}
Eseményszámlálás
A TPMx modul számlálóként működik, ha a TPMx_SC vezérlő regiszter CMOD bitcsoportjában (bináris) 10-et írunk. Ebben az üzemmódban a számláló a kívülről érkező jel felfutó éleire számol. A bejövő jelet a mikrovezérlő a TPM órajelhez szinkronizálja, ezért a külső jelek számlálása esetén is konfigurálnunk kell a közös TPM órajelet.Ahogy a 7. ábrán is látható, a szinkronizált jel a TPMx modul előosztójára kerül, s a továbbiakban a számlálás ugyanúgy történik, mint a belső órajelek esetében. Amikor a számláló eléri a modulo regiszterben beállított felső határt, a TPMx_SC regiszterben bebillen a TOF jelzőbit, s a számlálás nulla értékről folytatódik.
Bemenetválasztás
Külső események számlálásához az MKL25Z128VLK4 mikrovezérlő három TPM moduljához egyidejűleg legfeljebb két bemenet választható ki: egy TPM_CLKIN0 és egy TPM_CLKIN1 bemenet. Elvileg nyolc I/O kivezetés közül választhatunk, de a FRDM kártyán hardverütközések miatt csak az alábbi táblázatban vastagon szedett négy bemenet használható erre a célra. Konfiguráláskor engedélyezni kell a megfelelő portot (pl. C port), s a kivezetéshez tartozó portvezérlő regiszterben az Alt4 módot kell beállítani a MUX bitcsoportban.6. táblázat: az MKL25Z128VLK4 mikrovezérlő eseményszámláláshoz használható bemenetei
TPM_CLKIN0 |
TPM_CLKIN1 |
---|---|
PTA18 |
PTA19 |
PTB16 |
PTB17 |
PTC12 |
PTC13 |
PTE29 |
PTE30 |
TPM2-re, a 25. bit TPM1-re, a 24. bit pedig TPM0-ra vonatkozik. Ha a bit 0, akkor a TPM_CLKIN0 bemenetet rendeljük az adott TPMx modulhoz. Ha pedig a bit 1, akkor a TPM_CLKIN1 bemenetet használjuk.
15. ábra: A SIM_SOPT4 regiszter bitkiosztása
Megjegyzés: A FRDM-KL25Z kártya mikrovezérlője 3,3 V-os tápfeszültséggel működik, ezért a bemenetekre 3,6 V-nál nagyobb feszültséget nem szabad kapcsolni, mert a mikrovezérlő károsodhat!
Program5_10: Külső események számlálása
A programban külső eseményeket számlálunk a PTC12 kivezetés, mint TPM_CLKIN0 bemenet használatával. TPM órajel gyanánt az alapértelmezett (20.97 MHz) MCGFLLCLK órajelet használjuk. A TPM0 modul külső órajel bemenetét a mikrovezérlő PTC12 kivezetéséhez rendeljük, amelyet TPM_CLKIN0 módba konfigurálunk.A számlálót rendszeresen kiolvassuk, s a kiolvasott pillanatnyi értékének legalsó három bitjét kijelezzük az RGB LED-en.
Megjegyzés: Ha összekötjük a FRDM-KL25Z kártya csatlakozóin a PTA1 és PTC12 pontokat, akkor a számítógépről küldött karakterek (UART0 RX) felfutó éleit számoltathatjuk.
11. lista: Program5_10/main.c listája
/* Program5_10
*
* Külső események számlálása a PTC12 bemenet használatával.
* Az MCGFLLCLK (20.97 MHz) órajelet használjuk a TPM modulok
* órajelének, s a TPM0 modul számlálójával a PTC12 (TPM_CLKIN0)
* A TPM0 modult a PTC12 (TPM_CLKIN0) bemenethez rendeljük, s a
* bejövő jel felfutó éleit számláljuk. A számláló kiolvasott
* pillanatnyi értékének legalsó három bitjét kijelezzük az RGB LED-en.
*
* A program forrása: Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Freescale_ARM_codes.htm
*/
#include <MKL25Z4.H>
int main (void) {
unsigned short count;
//--- GPIO kimenetek inicializálása az RGB LED-hez -----
SIM->SCGC5 |= 0x400; // B port engedélyezése
SIM->SCGC5 |= 0x1000; // D port engedélyezése
PORTB->PCR[18] = 0x100; // PTB18 GPIO módba állítása
PTB->PDDR |= 0x40000; // PTB18 kimenet legyen
PORTB->PCR[19] = 0x100; // PTB19 GPIO módba állítása
PTB->PDDR |= 0x80000; // PTB19 kimenet legyen
PORTD->PCR[1] = 0x100; // PTD1 GPIO módba
PTD->PDDR |= 0x02; // PTD1 kimenet legyen
//--- TPM0 és PCT12 inicializálása ---------------------
SIM->SCGC5 |= 0x0800; // C port engedélyezése
PORTC->PCR[12] = 0x400; // PTC12 legyen TPM_CLKIN0 bemenet
SIM->SOPT4 &= ~0x01000000; // TPM_CLKIN0 bemenetet használjuk
SIM->SCGC6 |= 0x01000000; // TPM0 engedélyezése
SIM->SOPT2 |= 0x01000000; // MCGFLLCLK legyen a TPM órajel
TPM0->SC = 0; // Időzítő letiltása konfiguráláshoz
TPM0->SC = 0x80; // Előszámláló /1 és TOF törlés
TPM0->MOD = 0xFFFF; // Szabadonfutó mód
TPM0->CNT = 0; // Számláló törlése
TPM0->SC |= 0x10; // Számlálás indítása külső órajellel
while (1) {
count = TPM0->CNT; // Számláló kiolvasása
//--- LED-ek beállítása a számláló legalsó bitjei szerint
if (count & 1) // Piros LED beállítása bit0 szerint
PTB->PCOR = 0x40000; // LED = be
else
PTB->PSOR = 0x40000; // LED = ki
if (count & 2) // Zöld LED beállítása bit1 szerint
PTB->PCOR = 0x80000;
else
PTB->PSOR = 0x80000;
if (count & 4) // Kék LED beállítása bit2 szerint
PTD->PCOR = 0x02;
else
PTD->PSOR = 0x02;
}
}
Felhasznált anyagok és ajánlott olvasmányok:
- Electronics tutorials: Counters
- Joseph Yiu: The Definitive Guide to ARM® Cortex®-M0 and Cortex-M0+ Processors (2nd Ed.)
- Muhammad Ali Mazidi, Shujen Chen, Sarmad Naimi, Sepehr Naimi: Freescale ARM Cortex-M Embedded Programming
- ARM University Program: Course/Lab Material for Teaching Embedded Systems/MCUs (for the FRDM-KL25Z board)
- Trevor Martin: The Designer’s Guide to the Cortex-M Processor Family
- Freescale: MKL25Z128VLK4 MCU datasheet
- Freescale: KL25 Sub-Family Reference Manual
- Freescale: FRDM-KL25Z User Manual
- Freescale: FRDM-KL25Z Pinouts
- Keil: Cortex-M0+
Devices - Generic User Guide (DUI0662a)