Základný princíp pulzne-šírkovej modulácie(PWM), generovanie frekvencií a PWM pomocou AVR mikrokontroléra
Význam PWM na rozdiel od spojitej regulácie je hlavne v eliminovaní strát na regulátore. Pri PWM regulujeme dodávaný výkon do záťaže pomocou striedy. Strieda je pomer času zopnutia ku celkovej perióde spínacieho prvku.
D = (t_on /t_p)
D- strieda
T_on – čas zopnutia
T_p – perióda
Pre lepšie porozumenie uvediem príklad:
Nech máme napájacie napätie 12V a žiarovku s parametrami 6V/1A. Pri klasickej spojitej regulácií by sme na regulátore (tranzistore) museli vytvoriť úbytok napätia 6V pri prúde 1A ,čo by spôsobilo tepelnú stratu na tranzistore 6W. Efektivita tejto regulácie by bola teda 50%, teda rovná polovica energie by sa premenila na teplo.
Pri PWM regulácií vytvoríme striedu D=0,5, teda tranzistor bude zopnutý polovicu času. Straty na tranzistore budú najvyššie pri zopínaní a rozopínaní tranzistora. Pri zopnutom tranzistore ním bude tiecť ,ale tranzistor bude v saturácií ,takže sa na ňom vytvorí malý úbytok napätia, tým pádom bude aj výkonová strata malá. Pomocou PWM teda môžeme dosiahnúť vysokú účinnosť regulácie (obvykle nad 90%).
Pozn.: Pri takomto zapojení však nebude na výstupe konštantné napätie 6V! Na výstupe bude určitú časť periody napájacie napätie 12V ale žiarovka sa neprepáli vďaka jej tepelnej zotrvačnosti. Polovodičové prvky by však takéto pulzy asi neprežili, preto v týchto prípadoch treba na výstup zaradiť RC filter ktorý výstupne napätie vyhladí na hodnotu napätia danú veľkosťou striedy.
Táto regulácia má v súčasnej dobe veľké využitie v elektronike. Využívame ju hlavne na reguláciu žiaroviek, motorov, v spínaných zdrojoch alebo dokonca v audio technike ako zosilňovač triedy D.
Problematika PWM je bližšie vysvetlená v tomto článku.
TCCR1A (Timer/counter 1 control register A): Využíva sa na nastavenie PWM:
COM1A1, COM1A0 – slúžia na nastavenie správania výstupného pinu OC1A
COM1B1, COM1B0 – slúžia na nastavenie správania výstupného pinu OC1B
Nastavenie týchto bitov má odlišnú funkciu v závislosti od nastavenia režimu PWM.
Normálny režim:
Pri normálnom režime (nie v režimoch PWM), môžeme nastaviť správanie pinov OC1A a OC1B pri zhode porovnávacieho registra OCR1n s registrom TCNT1 nasledovne:
– (0,0)Piny OC1A a OC1B sú odpojené od čítača
– (0,1) Zmena log. úrovne pri zhode registrov
– (1,0) Nastaví výstup OC1A/OC1B do log.0 pri zhode registrov
– (1,1) Nastaví výstup OC1A/OC1B do log.1 pri zhode registrov
Režim rýchlej PWM (Fast PWM):
– (0,0) Piny OC1A a OC1B sú odpojené od čítača
– (0,1) Zmena log. úrovne na pine 0C1A pri režime 15, OC1B odpojený. V ostatných režimoch sú OC1A a OC1B odpojené od čítača
– (1,0) Nastaví výstup OC1A/OC1B do log.0 pri zhode registrov a log.1 pri BOTTOM hodnote.
– (1,1) Nastaví výstup OC1A/OC1B do log.1 pri zhode registrov a log 0 pri BOTTOM hodnote.
Režim Phase correct a Phase and Frequency correct PWM:
– (0,0) Piny OC1A a OC1B sú odpojené od čítača
– (0,1) Zmena log. úrovne na pine 0C1A pri režime 9 a 14, OC1B odpojený od čítača. V ostatných režimoch sú OC1A a OC1B odpojené
– (1,0) Nastaví výstup OC1A/OC1B do log.0 pri zhode registrov počas inkrementácie a log. 1 počas dekrementácie registra TCNT1
– (1,1) Nastaví výstup OC1A/OC1B do log.1 pri zhode registrov počas inkrementácie a log. 0 počas dekrementácie registra TCNT1
FOC1A, FOCA1B – pri zapísaní log.1 vyvolá compare match udalosť (FOC1A na OC1A a FOC1A na OC1B) s tým rozdielom že na tuto udalosť reaguje len Waveform Generation jednotka, ktorá riadi výstupné OCx piny, takže sa nenastaví flag OCFx a nevyvolá sa prerušenie a takisto sa nevykoná vynulovanie hodnoty citaca v CTC móde.
WGM11,10 a WGM13,12 s registra TCCR1B (Waveform generation mode):
Z tabuľky vidno, že čítač/časovač 1 na ATmega8 dokáže pracovať v 15 režimoch v závislosti od nastavenia bitov WGM. Z toho sú 3 základné režimy PWM (Fast PWM, Phase correct PWM a Phase and Frequency correct PWM) a jeden režim pre generovanie frekvencie – CTC.
Žiadosť o prerušenie môže byť generovaná vždy, keď obsah čítača dosiahne hodnotu TOP definovanú obsahom OCR1A, alebo ICR1. Ak je prerušenie povolené, potom v rámci obslužnej rutiny môže byť zmenená príslušná hodnota TOP.
Výstupnú frekvenciu vypočítame podľa vzťahu:
, kde fclk je frekvencia hodín, N je preddelička a OCRnA je hodnota porovnávacieho registra.
Príklad č.1: Striedaj 5 periód s frekvenciou 1000 Hz a 500 Hz.
Využijeme CTC režim. Podľa vzorca vypočítame, že hodnota OCR1A registra bude 499 pre frekvenciu 1000Hz a 249 pre 2000Hz, pri nastavenej preddeličke 8 a frekvencií hodín 8MHz. V prerušení na udalosť zhody OCR1A a TCNT1 registra po 5 periódach striedame hodnoty OCR1A registra, čím striedame aj frekvencie 1000 a 2000Hz.
Zdrojový kód:
// pocet period danej frekvencie
volatile unsigned char n;
//pretečenie TCNT1
ISR (TIMER1_COMPA_vect){
// 5 period (dve zmeny)
if(n == 10){
// zmen hodnotu OCR1A po 5 period
OCR1A = ((OCR1A == 499) ? 249 : 499);
n=0;
}
n++;
}
int main(){
DDRB |= (1 << PB1); // OC1A ako výstupný
// REZIM 4 (CTC), nastavenie zmeny log. úrovne zhode OCR1A a TCNT1
TCCR1A |= (1 << COM1A0);
TCCR1B |= (1 << WGM12) | (1 << CS11); // preddelička 8 pri 8 MHz = (1us)
OCR1A |= 499;
TIMSK |= (1 << OCIE1A); //povol prerušenie pri zhode OCR1A a TCNT1
OSCCAL = 0xA5; // nastavenie kalibracneho bajtu interneho RC oscilatora
sei(); // povol globalne prerušenia
while(1); // nekonečná slučka
return 0;
}
Výstupný priebeh:
2) Režim „ rýchla PWM“ (Fast Pulse Width Modulation)
Režimy z tabuľky: 5, 6, 7, 14 alebo 15.
Generuje impulzný šírkovo modulovaný signál (PWM). V tomto režime sa obsah čítača zvyšuje od hodnoty BOTTOM do hodnoty TOP. V neinvertujúcom režime sa výstup OC1x nastaví pri zhode obsahov čítača TCNT1 a OCR1x a vynuluje sa pri dosiahnutí hodnoty TOP. Pri invertujúcom režime je to obrátene (viď časť registre).
Rozlíšenie rýchlej PWM môže byť pevné, 8, 9, alebo 10 bitov, prípadne definované obsahom ICR1, alebo OCR1A. Minimálne povolené rozlíšenie je 2 bity (ICR1, alebo OCR1A je nastavené na hodnotu 0x0003). Maximálne rozlíšenie je 16 bitov (ICR1, alebo OCR1A je nastavené na hodnotu MAX).
Rozlíšenie PWM je dané nasledujúcim vzťahom:
V režime rýchlej PWM sa čítač inkrementuje pokiaľ jeho hodnota nenadobudne jednu z definovaných hodnôt 0x00FF, 0x01FF, alebo 0x03FF (režimy 5, 6, alebo 7), hodnotu v ICR1 (režim 14), alebo hodnotu v OCR1A (režim 15). V nasledujúcom hodinovom cykle po dosiahnutí definovanej hodnoty sa jeho obsah vynuluje.
Príznak pretečenia sa nastaví, keď obsah čítača dosiahne hodnotu TOP. Ak je obsluha prerušenia povolená, potom pomocou obslužného programu prerušenia môžeme zmeniť hodnotu TOP, prípadne porovnávaciu hodnotu.
Frekvenciu PWM môžeme určiť na základe nasledujúceho vzťahu:
, kde fclk je frekvencia hodín, N je preddelička a TOP je max. hodnota čítača/časovača.
Príklad č.1: Plynule rozsvecovanie žiarovky
Použité je 8-bitové PWM. Zmena striedy sa realizuje v nekonečnej slučke v 10ms intervaloch
Zdrojový kód:
int main(){
DDRB |= (1 << PB1); // OC1A ako výstupný
// REZIM 5 - Fast PWM 8bit,
TCCR1A |= (1 << COM1A1) | (1 << WGM10);
TCCR1B |= (1 << WGM12) | (1 << CS11); // preddelička 8 pri 8 MHz = (1us)
OCR1A = 0;
OSCCAL = 0xA5; // nastavenie kalibracneho bajtu interneho RC oscilatora
sei(); // povol globalne prerušenia
while(1){ // nekonečná slučka
// rozsvecuj ziarovku zmenou striedy
OCR1A++;
if(OCR1A == 255) OCR1A=0;
_delay_ms(10);
}
return 0;
}
Youtube video:
Príklad č.2: Ovládanie jasu žiarovky pomocou 2 tlačidiel
Využili sme vedomosti z časti venujúcej sa externému prerušeniu. Dve tlačidlá sú použité ako zdroj externého prerušenia piny (INT0 a INT1). Prvým tlačidlom pridávame striedy, druhým uberáme. Použité je 8-bitové PWM.
Zdrojový kód:
ISR(INT0_vect){
if(OCR1A < 245) OCR1A+=10;
}
ISR(INT1_vect){
if(OCR1A > 10) OCR1A-=10;
}
int main(){
DDRB |= (1 << PB1); // OC1A ako výstupný
// REZIM 5 - Fast PWM 8bit,
TCCR1A |= (1 << COM1A1) | (1 << WGM10);
TCCR1B |= (1 << WGM12) | (1 << CS11); // preddelička 8 pri 8 MHz = (1us)
// PD2,PD3 ako vstupné (ext. prerušenia)
DDRD &= ~((1 << PD2) | (1 << PD3));
// Zapnutie interného pull-up rezistora
PORTD |= (1 << PD2) | (1 << PD3);
MCUCR |= (1 << ISC01); // dobežná hrana INT0
MCUCR |= (1 << ISC11); // dobežná hrana INT1
GICR |= (1 << INT1) | (1 << INT0); // povol prerušenia od INT1 a INT0
OSCCAL = 0xA5; // nastavenie kalibracneho bajtu interneho RC oscilatora
sei(); // povol globalne prerušenia
while(1);
return 0;
}
Youtube video:
Príklad č.3: Generovanie sínusu:
Na začiatku vygenerujeme pole hodnôt cez funkciu generate_sin(); kde vstupným parametrom je želaná frekvencia. Sínusovka sa rozkúskuje na časti o dĺžke 32.768us, čo je vzorkovacia frekvencia a k týmto častiam sínusovky sa pridelí hodnota striedy. Potom cez prerušenie na udalosť pretečenia TCNT1 sa postupne tieto hodnoty nahrávajú do registra OCR1.
Aby sme dostali sínusový priebeh musíme na výstup pripojiť dolnopriepustný RC filter, vypočítaný približne na dvojnásobnú frekvenciu zadaného signálu f= 1/(2*pi*R*C). S rastúcou frekvenciou klesá počet vzoriek na periódu. Pri frekvencii 1000Hz je to zhruba 30 vzoriek na periódu.
V príklade som generoval frekvenciu 1000Hz, teda hodnoty prvkom mi vyšli R=1000R,C=82nF
Zdrojový kód:
Výstupný priebeh:
Horný priebeh je PWM signál a spodný priebeh je sínus získaný z PWM cez dolnopriepustný RC filter.
3) fázovo korektná PWM (Phase correct PWM)
Režimy 1,2,3,10,11.
V tomto režime sa hodnota čítača zvyšuje (inkrementuje) od hodnoty BOTTOM (0x0000) až po hodnotu TOP a potom sa následne dekrementuje po hodnotu BOTTOM. V neinvertujúcom výstupnom porovnávacom režime je výstup OC1x vynulovaný v prípade rovnosti obsahov TCNT1 a OCR1x pri počítaní smerom nahor a nastavuje sa pri počítaní smerom nadol. V invertujúcom režime je situácia opačná. Maximálna dosiahnuteľná základná frekvencia fázovo korektnej PWM je nižšia než pri rýchlej PWM.
Tento režim je často používaný pri riadení motorov. Rozlíšenie PWM je pevné 8, 9, alebo 10 bitov, prípadne definované obsahom registrov ICR1, alebo OCR1A. Najmenšie použiteľné rozlíšenie je 2 bity (ICR1, alebo OCR1A je nastavené na hodnotu 0x0003). Maximálne rozlíšenie je 16 bitov (ICR1, alebo OCR1A je nastavené na hodnotu MAX).
Rozlíšenie PWM je dané nasledujúcim vzťahom
Ak je obsluha prerušenia povolená prerušenie môže v závislosti od nastavenia nastať pri hodnote TOP alebo BOTTOM. V obslužnom programe prerušenia môžeme potom zmeniť hodnotu TOP, prípadne porovnávaciu hodnotu.
Pri definovaní novej TOP hodnoty je potrebné zabezpečiť, aby bola väčšia, alebo rovná než hodnoty v porovnávacích registroch.
Frekvenciu fázovo korektnej PWM môžeme určiť na základe nasledujúceho vzťahu:
, kde N je preddelička, TOP je max. hodnota čítača/časovača a fclk je frekvencia hodín.
4) fázovo a frekvenčne korektná PWM (Phase and frequency correct PWM)
Sú to režimy 8 a 9.
V tomto režime sa hodnota čítača inkrementuje od hodnoty BOTTOM (0x0000) až po hodnotu TOP a potom sa následne dekrementuje po hodnotu BOTTOM. V neinvertujúcom režime je pri počítaní smerom nahor výstup OC1x nulovaný v prípade rovnosti obsahov TCNT1 a OCR1x. Pri dekrementácií sa výstup nastaví v prípade zhody do log.1 V invertujúcom režime je situácia opačná.
Maximálna dosiahnuteľná základná frekvencia fázovo a frekvenčne korektnej PWM je nižšia než pri rýchlej PWM. Tento režim je často používaný pri riadení motorov. Rozlíšenie PWM je definované obsahom registrov ICR1, alebo OCR1A. Najmenšie použiteľné rozlíšenie je 2 bity. Vtedy je ICR1, alebo OCR1A nastavené na hodnotu 0x0003. Maximálne rozlíšenie je 16 bitov, ak ICR1, alebo OCR1A je nastavené na hodnotu MAX.
Rozlíšenie PWM je dané nasledujúcim vzťahom:
V režime fázovo a frekvenčne korektnej PWM je obsah čítača inkrementovaný až do okamžiku, v ktorom nedosiahne jednu z hodnôt nastavených v registri ICR1 (režim 8), alebo v registri OCR1A (režim 9). Ak čítač dosiahne hodnotu TOP zmení smer počítania. Obsah čítača bude rovný hodnote TOP práve jeden hodinový cyklus.
Na definovanie hodnoty TOP použitý register OCR1A, alebo ICR1. Príznaky prerušenia môžu byť využité na generovanie prerušení v časových okamžikoch, v ktorých obsah TCNT1 dosiahne hodnotu TOP, alebo BOTTOM.
Frekvenciu fázovo a frekvenčne korektnej PWM môžeme určiť na základe nasledujúceho vzťahu:
, kde fclk je frekvencia hodín, N je preddelička a TOP je max. hodnota čítača.
Príklad č.1: Generujte PWM signál pomocou režimu 3 (fázovo aj frekvenčne korektné PWM).
Jedná sa o 10-bitové PWM, takže TOP hodnota bude 1024. Obsah porovnávacieho registra OCR1A nesmie presiahnuť teda túto hodnotu. Pri frekvencií hodín a preddeličke 8 bude TCNT1 inkrementovaný za čas 1us. Pretečenie nastane za čas 2048us, pretože z max. hodnoty neprejde čítač/časovač do hodnoty 0 ale dekrementuje sa, takže čas treba násobiť dvoma.
Zdrojový kód:
int i;
//pretečenie nastane za čas 2048us
ISR(TIMER1_OVF_vect){
OCR1A = i;
i+=10;
if(i>1024) i=0;
}
int main(){
DDRB |= (1 << PB1); // OC1A ako výstupný
// REZIM 3 - Phase and Freq. correct PWM - 10bit
TCCR1A |= (1 << COM1A1) | (1 << COM1A0) | (1 << WGM10) | (1 << WGM11);
TCCR1B |= (1 << CS11); // preddelička 8 pri 8 MHz = (1us)
TIMSK |= (1 << TOIE1); //prerušenie na pretečenie
OSCCAL = 0xA5; // nastavenie kalibracneho bajtu interneho RC oscilatora
sei(); // povol globalne prerušenia
while(1);
return 0;
}
Výstupný priebeh:
Záver:
Na záver dodám ,že ATmega8 dokáže generovať PWM aj pomocou čítača/časovača 2, princíp ostáva rovnaký avšak nastavenie registrov je odlišné. V ďalšom pokračovaní seriálu si povieme viac o pripojení a práci zo znakovým LCD displejom.
Ďakujem všetkým, čo sa podieľali na tvorbe tejto časti seriálu!
Prepáčte, ale pred zanechaním komentára sa musíte prihlásiť.
Veľmi pekný článok, konečne niečo čo má ja blahodárne využitie a kde aplikujeme doterajšie teóriu. Teším sa keď si to vyskúšam.
tu namiesto
COM1A1, COM1A0 – slúžia na nastavenie správania výstupného pinu OC1A
COM1A1, COM1A0 – slúžia na nastavenie správania výstupného pinu OC1B
nemá byť
COM1A1, COM1A0 – slúžia na nastavenie správania výstupného pinu OC1A
COM1B1, COM1B0 – slúžia na nastavenie správania výstupného pinu OC1B
?
Dakujem za upozornenie. Chybu som opravil.
Prosím, plánujete to dat aj do pdf-ka?
jednoduchá rada, nainstaluj si doplňek WebPage ScreenShot, vyfoť si celou stránku, v nějakém grafickém programu se jí uprav a dej do pdf 🙂
ja uz 12rokov pouzivam volny program pdf995 a vrelo odporucam. Nic jednoduchsie a spolahlivejsie som nenasiel ako toto. Nainstaluje sa ti to ako dalsia tlaciaren a jednoducho das tlacit cez pdf995.
Zdravím,
jenom otázečka, hodněkrát v tomto díle používate proměnnou i. Všimnul sjem si, že ji deklarujete bez inciování (pouze int i; místo int i =0;) a potom ji neinicializovanou používáte …
třeba:
Príklad č.3: Generovanie sínusu:
předpokládá se že mikrokontroléry mají po restartu paměť vynulovanou ? je to tak ?
Ak by som chcel vyuzit OCR1A aj OCR1B dajme tomu na regulaciu dvoch ziaroviek tak ako to urobim? Ja uz som nieco skusal ale neuspesne 🙁
Uz som na to prisel 😀
TCCR2A = 0xA3;
TCCR2B = 0x02;
OCR2A = OCR2B = 0;
Zdravim.
Mam otazku. Potrebujem riadit jednosmerny motor. V com sa bude beh motora lisit ak pouzijem FastPWM alebo Phase and frequency correct PWM?
Vysledny priebeh PWM by mal byt rovnaky. Bude to mat nejaky vplyv na beh motora (plynulost, rusenie. Pri PaFc_PWM sa pise, ze je vhodna na riadenie motorov – preco?
Dik za odpoved.