Fórum témák

» Több friss téma
Cikkek » Launchpad: ismerkedés az MSP430 mikrovezérlőkkel III.
Launchpad: ismerkedés az MSP430 mikrovezérlőkkel III.
Szerző: icserny, idő: Jún 19, 2012, Olvasva: 20471, Oldal olvasási idő: kb. 4 perc
Lapozás: OK   9 / 10

Impulzus-szélesség moduláció (PWM)

Az időzítő/számláló egységek egyik felhasználási területe a digitális jelsorozattal történő vezérlés, impulzus-szélesség moduláció segítségével (PWM = Pulse Width Modulation), amelynél olyan állandó frekvenciájú jeleket keltünk, ahol a szabályozás a jel kitöltési tényezőjének változtatásával történik. Néhány különböző kitöltési tényezőjű PWM jelet mutat be a következő ábra:

9_1. ábra: Azonos periódusú, de különböző kitöltésű impulzus-sorozatok
(az ábrát John Davies "MSP430 Microcontroller Basics" c. könyvéből kölcsönöztük)

A PWM üzemmódok részletes ismertetése az MSP430x2xx Family Users Guide kézikönyv 12. fejezetében, valamint a cikksorozatom második részének 8. oldalán található. Itt most csak a korábbi példaprogramok új kiadású Launchpad kártyára történő adaptálására szorítkozunk.

2_pwm_soft

A PWM alapjainak megértéséhez először szoftveresen állítunk elő PWM jelet, az időzítésekhez  LED villogtatásnál már megszokott késleltető függvényeket használva. A programban a PWM jel segítségével a LED1 fényerejét  változtatjuk folyamatosan, mintha a LED "lélegezne".

A szükséges változtatások: A program nem igényel módosítást (csak a mikrovezérlő típusát kell átállítani a projektben).

2_pwm_led

Ebben a programban már felhasználjuk a Timer_A modul nyújtotta hardveres támogatást a PWM jel előállítására. Most LED2 fényerejét  változtatjuk, mivel ehhez a LED-hez kapcsolódik hardveres Compare kimenet (a TA0.1 kimenet). A PWM frekvenciát 100 Hz-nek választottuk meg (kisebb frekvencia esetén a szemünk már észrevenné a "repkedést"), a kitöltést pedig ~2 s alatt 0-tól 200-ig (pontosabban csak 198-ig) változtatjuk. A kitöltést nem lineárisan, hanem négyzetesen növekedő számokkal állítjuk be, tehát a 0, 1, 4, 9, 16, 25, ... stb. sorozatot állítjuk elő.A szemünk így egyenletesebbnek érzékeli a fényerő változásokat.

Üzemmód beállítások

  • A PWM frekvenciát 100 Hz-nek választottuk meg (kisebb frekvencia esetén a szemünk már észrevenné a "repkedést"), a kitöltést pedig ~2 s alatt 0-tól 200-ig (pontosabban csak 198-ig) változtatjuk.
  • Timer:  MCx=1 (felfelé számlálás), megszakítást nem használunk
  • CCR0: üzemmód állítás nincs, kimenetet és interruptot nem használunk. TACCR0 = 10 000 - 1 (a periódus)
  • CCR1: OUTMOD = 7 (reset/set mód). A kimenetet P1.6-ra irányítjuk, így LED2 közvetlenül vezérelhető a PWM jellel. CCIFG1 megszakítását engedélyezzük, s a megszakításokban változtatjuk a kitöltést.

A PWM mód beállításához TACCR0-ba írjuk a periódust megszabó számot, 10 000 - 1-et, mivel a periódus TACCR0 + 1 lesz. A TACCR1 regiszterbe pedig a kitöltést írjuk. A kitöltés értéke egy 0 és TACCR0 közötti szám lehet. Előbbi a 0, utóbbi a 100 %-os kitöltési tényezőnek felel meg. Arra azonban ügyelnünk kell, hogy TACCR1 ne haladja meg TACCR0 értékét, mert akkor nem kapunk megszakítást (TAR sohasem éri el TACCR1 értékét)!

A beállítások után a főprogramnak nem lesz több dolga, ezért aludni küldhetjük (MCLK lekapcsolható). Vigyáznunk kell azonban arra, hogy SMCLK és  DCO nem kapcsolható le, ezért itt most csak az LPM0 módot használhatjuk. Az energiatakarékos módot beállító __low_power_mode_0() függvényhívás egyúttal az interrupt engedélyezését is elvégzi (az SR státusz regiszter GIE bitjét is '1'-be állítja.

A szükséges változtatások:   A megszakítási vektor neve: TIMERA1_VECTOR helyett TIMER0_A1_VECTOR.

2_pwm_led2 

Ez az előző példa módosított változata, amelyben a TIMERA0_VECTOR (CCIFG0)  megszakításakor frissítjük a PWM kitöltés értékét.  Itt arra kell ügyelnünk, hogy a kis kitöltési értékeket beállításával ne késsük le azt, hogy a Timer számlálója túlcsordul, majd felfelé lépkedve meghaladja a kitöltés értéket.  Ehhez az MCLK értékét minél magasabbra frekvenciájúnak, Timer_A bemenőjelét pedig minél alacsonyabb frekvenciájúnak célszerű megválasztani,  Ebben a példában MCLK = 1 MHz (DCO), Timer_A bemenőjelét pedig az ACLK, a VLO 12 kHz-es órajele szolgáltatja.  Az ACLK = 12 kHz-es órajel miatt a 100 Hz-es PWM frekvencia biztosításához 1200 impulzust kell leszámolni, tehát TACCR0 = 119 legyen. A LED kb. 2 s-os félperiódusa alatt 200 lépésben négyzetesen növekvő kitöltést adunk meg, a következő 200 periódusban pedig csökkenő kitöltéssel lépkedünk vissza. Most  végrehajthatunk 200 lépést, nem kell a TACCR1 < TACCR0 feltétel teljesülésével foglalkoznunk, mert a 0. sorszámú Capture/Compare csatornából garantáltan kapunk megszakítást, 100 %-os kitöltésnél sem "akad el" a programunk!

Üzemmód beállítások

  • Timer:  MCx=1 (felfelé számlálás), megszakítást nem használunk
  • CCR0: üzemmód állítás nincs, a CCIFG0 megszakítást engedélyezzük, s a megszakításokban változtatjuk a kitöltést (a TACCR1 regiszter tartalmát). A PWM frekvencia 100 Hz, ennek beállításához TACCR0 = 120 - 1 = 119
  • CCR1: OUTMOD = 7 (reset/set mód). A kimenetet P1.6-ra irányítjuk, így LED2 közvetlenül vezérelhető a PWM jellel. A CCIFG1 megszakítást most nem engedélyezzük.

A szükséges változtatások:   A megszakítási vektor neve: TIMERA0_VECTOR helyett TIMER0_A0_VECTOR.

2_pwm_cont

A PWM üzemmódoknál a TACCR0 csatorna hivatalosan a PWM frekvencia beállítására szolgál (a Timer modul TAR számlálja a futó időt, TACCR0 pedig a periódust állítja be). Egy kis trükközéssel azonban megoldható, hogy TACCR0 felszabaduljon, és egy további PWM csatorna vezérlésre használhassuk: a számlálót szabadonfutó módban járatjuk, s a TACCR0 és TACCR1 regiszterekbe mindig a következő rész-ciklus (a bekapcsolt vagy kikapcsolt állapot időtartama) időzítését írjuk (a TAR regiszter pillanatnyi állapotához hozzáadva a kívánt várakozási időhöz tartozó óraütések számát).

Erre mutatunk be most egy példát, amelyben LED1 1 s-os periódussal villog, állandó 1/60 kitöltéssel. Ez ugyan nem a szokványos módja a PWM használatának, de nem akartam bonyolítani a programot a kitöltési tényező változtatásával.  LED2 pedig a korábbiakhoz hasonlóan a "lélegző LED" műsorát adja elő: fényereje fokozatosan erősödik, majd elhalványul. Periódusa ~3,4 s

Üzemmód beállítások

  • Timer:  MCx=2 (szabadonfutó mód), órajele ACLK/VLO=12 kHz, megszakítást nem használunk
  • CCR0: OUTMOD=4 (Toggle, azaz átbillentés üzemmód ), a CCIFG0 megszakítást engedélyezzük. A PWM frekvencia itt 1 Hz, ami 12000 óraütés. Az 1/60 kitöltésnek megfelelően felváltva 200, illetve 11800-at adunk hozzá TACCR0 korábbi állapotához. Mivel P1.0 kimenet, ahová LED1 csatlakozik, nem állítható be TA0 kimenetnek, ezért a megszakításban szoftveresen billentjük át LED1 állapotát. Ez az interrupt késedelme miatt tartalmaz némi bizonytalanságot, nem ad olyan hardveres pontosságú időzítést, mint a TA0 kimenet.
  • CCR1: OUTMOD=4 (Toggle, azaz átbillentés üzemmód ), a CCIFG1 megszakítást engedélyezzük. A PWM frekvencia itt 100 Hz, ami 120 óraütés. A kitöltési tényező kiszámítása ugyanúgy történik, mint az előző két programban. A TACCR1 regisztert felváltva vagy a kiszámolt kitöltéssel, vagy a kitöltést a periódusra kiegészítő számmal kell feltölteni.
  • A beállítások után a főprogramnak nincs több teendője, ezért energiatakarékos módba tehetjük. Mivel a számláló működéséhez csak az ACLK órajel szükséges, az LPM3 módot használjuk.

A szükséges változtatások:  A megszakítási vektorok neve TIMERA0_VECTOR helyett TIMER0_A0_VECTOR,TIMERA1_VECTOR helyett pedig TIMER0_A1_VECTOR.


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

Belépés

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