Promjena PWM frekvencije na ATmega (328, 2560...)

Rasprava o AVR mikrokontrolerima, AVR projekti i drugo vezano za AVR...

Moderators: pedja089, stojke369, trax, InTheStillOfTheNight

Post Reply
sonata
Napredujem
Napredujem
Posts: 121
Joined: 08-01-2013, 18:01

Promjena PWM frekvencije na ATmega (328, 2560...)

Post by sonata »

Našao sam par tema koje se bave tajmerima i PWM-om, ali ne i ono što me konkretno zanima.

Dakle, jasno je da se prescalerima mogu odabrati neke "osnovne frekvencije" PWM-a na ATmega (arduino :-)) kontrolerima, a mene zanima kako podesiti PWM frekvenciju na neku proizvoljnu prema vlastitoj želji. Npr. 20 kHz. Timer2 se može podesiti tako da PWM daje 32kHz (prescaler 1) ili 4 kHz (prescaler 8) ili manje... Sad, kad bih odabrao ovih 4 kHz i skratio brojanje da ne ide do 255 nego do 51, dobio bih 20 kHz. No, nikako ne uspjevam u tome. Probao sam i fast PWM i CTC i phase correct PWM i svašta, mjenjati modove, mijenjati registre OCRxA i OCRxB, ali jedino što uspijem s tim igranjem je promjena Duty Cycle-a.

Nešto mi je gadno promaklo, očito, a google mi više ne pomaže jer sam pročitao sve što se može izguglati i sad mi više ništa nije jasno. Trenutno čitam datasheet samog procesora, ali to kao da je pisano kineski...

Dakle, treba mi C-kôd kojim ću podesiti PWM frekvenciju na 20 kHz (npr.) i kasnije u programu birati da li će izlaz biti na nuli, na 100%DC (stalno uključen) ili će biti na nekom DC-u (recimo 75%). Nije mi važna rezolucija, važna su mi ta tri stanja i važno je da bude na oko 20 kHz (4 mi je premalo, 32 previše)

Ima li netko kakvu ideju? Ja sam ostao bez ideje. Konkretno me zanima za ATmega 2560 kojeg trenutno imam, ali stvar bi trebala raditi i na Atmega328 (recimo, Arduino Nano)
Nullius addictus iurare in verba magistri
User avatar
Kizo
Pravo uznapredovao :)
Pravo uznapredovao :)
Posts: 387
Joined: 01-11-2009, 22:40
Location: Hrvatska

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by Kizo »

ATmega328 datasheet -> Timer2 poglavlje -> ispod gdje objašnjava TCCR2A registar nađi Tablicu 17-8 -> obrati pozornost na "TOP" stupac (hint: mod 5 ili 7) :wink:
sonata
Napredujem
Napredujem
Posts: 121
Joined: 08-01-2013, 18:01

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by sonata »

Kizo wrote:ATmega328 datasheet -> Timer2 poglavlje -> ispod gdje objašnjava TCCR2A registar nađi Tablicu 17-8 -> obrati pozornost na "TOP" stupac (hint: mod 5 ili 7) :wink:
Je, znam, samo nikako ne mogu posložiti registre na način da to zaista i proradi. Ima puno kodova na netu, napravim c/p, a uC se ponaša skroz drugačije. Znam jer gledam na osciloskopu.

Ako imaš neki c-kod, molim te da ga postaš jer sam već posijedio...
Nullius addictus iurare in verba magistri
User avatar
InTheStillOfTheNight
Odlično uznapredovao
Odlično uznapredovao
Posts: 938
Joined: 01-06-2006, 17:54
Location: Zagreb

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by InTheStillOfTheNight »

Aj, ak ne budeš rješio reci mi samo koji TIMER hoćeš i na koju frekvenciju pa ti ja napišem C source inicijalizacije. I naravno, napiši na kojoj frekvenciji radi MCU.
InTheStillOfTheNight
sonata
Napredujem
Napredujem
Posts: 121
Joined: 08-01-2013, 18:01

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by sonata »

InTheStillOfTheNight wrote:Aj, ak ne budeš rješio reci mi samo koji TIMER hoćeš i na koju frekvenciju pa ti ja napišem C source inicijalizacije. I naravno, napiši na kojoj frekvenciji radi MCU.
Timer2, 20kHz. I bez poziva interrupta, a posebno ne bitbanging. Dakle, normalna upotreba pwm izlaza, po mogućnosti preko analogWrite()...

Mcu je 2560, 16MHz (arduino).
Nullius addictus iurare in verba magistri
sonata
Napredujem
Napredujem
Posts: 121
Joined: 08-01-2013, 18:01

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by sonata »

Sve skupa mi izgleda kao neki bug u hardveru. OCR2A bi trebao istovremeno koristiti kao TOP brojača (fast PWM) i kao granica prelaska iz high u low stanje. Dakle, istovremeno treba definirati frekvenciju i duty cycle. Jasno da stvar ne funkcionira.

Samo još da netko napiše uputu kako da ipak profunkcionira...
Nullius addictus iurare in verba magistri
User avatar
InTheStillOfTheNight
Odlično uznapredovao
Odlično uznapredovao
Posts: 938
Joined: 01-06-2006, 17:54
Location: Zagreb

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by InTheStillOfTheNight »

Pozdrav,
u gostima sam ovih dana pa nisam bio na forumu, danas idem doma pa ću ti napisati inicijalizaciju u C-u nevečer, ne stignem sada kopati po datasheet-u.

Nema tu nikakav HW bug, nešto si krivo shvatio iz područja TIMER-a. Trebaš dobro podesiti samo nekoliko stvari, budem ti to sve večeras lijepo objasnio.

Pozdrav,
Josip Štivić
InTheStillOfTheNight
User avatar
InTheStillOfTheNight
Odlično uznapredovao
Odlično uznapredovao
Posts: 938
Joined: 01-06-2006, 17:54
Location: Zagreb

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by InTheStillOfTheNight »

Naveo si 16 Mhz MCU clock, želiš 20 khz PWM i želiš to napraviti korištenjem TIMERA 2.

1. Najprije izračunaš period PWM-a na 20 Khz formulom T=1/f = 1/20000 Hz = 0.00005 S ili 50 us. Dakle, 8 Bitni TIMER 2 ne smije napraviti overflow prije nego li prođe 50 us vremena.

2. Pronađeš tablicu prescalera TIMER 2 i izračunaš prescaler na kojemu TIMER neće napraviti overflow prije nego li prođe 50 us vremena. Tablica prescalera nalazi se na stranici 186 datasheeta. Kako znaš da ti je ulazna frekvencija 16 MHz računaš overflow TIMER-a od najmanjeg prema većim prescelerima:

Prescaler 1 (clk/1):
Dijeliš 16 Mhz sa prescalerom clk/1 i dobiješ 16 Mhz frekvenciju koja ulazi u TIMER 2. Izračunaš period te frekvencije T=1/f = 1/16000000 = 62.5 nS i pomnožiš jedan period sa 256 stanja 8 bitnog TIMER-a da bi on napravio overflow. 62.5 ns * 256 = 16us (Overflow je nakon 16 us -> Timer mora brojati sporije!)

Prescaler 2 (clk/8):
Dijeliš 16 Mhz sa prescalerom clk/8 i dobiješ 2Mhz frekvenciju koja ulazi u TIMER 2. Izračunaš period te frekvencije T=1/f = 1/2000000 = 500 ns i pomnožiš jedan period sa 256 stanja 8 bitnog TIMER-a da bi on napravio overflow. 500 ns * 256 = 128 us (Overflow je nakon 128 us -> Ovaj prescaler koristiš!)

Odabir prescalera vrši se putem CS bitova (Clock Select) tako da pronađeš tablicu koja opisuje ove bitove za TIMER 2. To ti se nalazi na stranici 191 datasheeta. Iz tablice možeš vidjeti da je za clk/8 potrebno podesiti CS bitove na sljedeće postavke:
CS22 = 0
CS21 = 1
CS20 = 0


Na stranici 190 imaš registar koji sadrži sve CS bitove za TIMER 2 i zove se TCCR2B. U ovom trenutku možeš napisati liniju programa koja podešava CS bitove, a kako je potrebno samo CS21 postaviti u log 1 u C-u to napraviš ovako:

Code: Select all

#include <avr\io.h>

int main(void){

     TCCR2B |= (1<<CS21);        /* Run TIMER 2 from prescaler clk/8 = 2 Mhz */
     
     while(1){
     }
}
Generirati PWM 20 kHz možeš u svim načinima rada TIMER-a osim u NORMAL. To nas vodi do tablice "Waveform Generation Mode Bit Description" koja se nalazi na stranici 189 datasheet-a. Svi načini rada "CTC, Phase Correct i Fast PWM" mogu osim hardware TOP vrijednosti brojača (255) postaviti novu TOP vrijednost korištenjem OCR2A registra. U ovom slučaju imaš 3 načina na koja možeš podesiti TIMER:

Mode 2: CTC sa gornjom vrijednosti TIMER-a OCR2A
Mode 5: PWM s, Phase Correct sa gornjom vrijednosti TIMER-a OCR2A
Mode 7: Fast PWM sa gornjom vrijednosti TIMER-a OCR2A


WGM bitovima TIMER-a određuješ način rada u kojemu će raditi TIMER. Da sad ne pišem sva 3 načina kako ovo možeš napraviti opisati ću ti kako to napraviti u Fast PWM načinu rada TIMER-a. Na stranici 189 datasheeta možeš pronaći konfiguraciju WGM bitova za MODE 7 (Fast PWM sa top vrijednosti OCR2A). Po tablici je vidljivo da WGM bitove moraš postaviti na sljedeće postavke:
WGM2 = 1
WGM1 = 1
WGM0 = 1


Ono što te može zbuniti je razlika između WGM2 i WGM22. To je mali propust tehničke dokumentacije. Kako su CS bitove nazvali CS22, CS21 i CS20 trebali su i WGM bitove nazvati WGM22, WGM21 i WGM20, ali to su malo čudno zapisali u tablici WGM bitova... Broj 2 govori da se radi o TIMER-u 2, pa ti onda ostaju samo bitovi imena WGM2, WGM1 i WGM0, a zapravo se radi u WGM22, WGM21 i WGM20.

Na stranici 187 datasheeta imaš registar TCCR2A u kojemu se nalaze 2 WGM bita za konfiguraciju TIMER-a WGM20 i WGM21 i njih trebaš podići u log 1. Osim toga na stranici 190 imaš TCCR2B registar u kojemu se nalazi WGM22 bit i njega moraš podići u log1. To bi u software-u izgledalo ovako:

Code: Select all

#include <avr\io.h>

int main(void){
     
     TCCR2A |= (1<<WGM20)|(1<<WGM21);   /* Fast PWM, TOP OCR2A                     */
     TCCR2B |= (1<<WGM22);
     TCCR2B |= (1<<CS21);               /* Run TIMER 2 from prescaler clk/8, 2 Mhz */
     
     while(1){
     }
}
Ono što sada moraš znati je činjenica da je TIMER u modu Fast PWM sa TOP vrijednosti OCR2A registra. Kako će TIMER 2 uvijek brojati samo do OCR2A registra njime podešavaš frekvenciju PWM-a koju želiš. Potrebno je izračunati koju vrijednost upisati u OCR2A registar da bi dobio točno 20 kHz PWM. To računaš ovako:

Ako je jedna clock TIMER-a 0.5 us (freq 2Mhz, clk/64), onda podjeliš svoj željeni period 50 us sa jednim clockom TIMER-a 0,5 us. 50us/0,5us = 100. U tartufima sam već objašnjavao zašto se u OCR2A registar ne upisuje vrijednost 100 nego umanjena za 1, dakle 99. Timer broji od 0, ali i kada nabroji do vrijedosti 100 on će na vrijednosti 100 biti još jedan clock. Zato u OCR2A registar upisuješ 99 kako bi dobio točno 20 khz izlazni PWM. Sljedećom naredbom podešavaš gornju vrijednost TIMER-a i nakon toga TIMER će napraviti overflow nakon točno 50us što odgovara frekvenciji 20 khz.

Code: Select all

#include <avr\io.h>

int main(void){
     OCR2A = 99;                        /* new TOP: (99+1)*0,5us = 50us -> 20kHz   */
     TCCR2A |= (1<<WGM20)|(1<<WGM21);   /* Fast PWM, TOP OCR2A                     */
     TCCR2B |= (1<<WGM22);
     TCCR2B |= (1<<CS21);               /* Run TIMER 2 from prescaler clk/8, 2 Mhz */
     
     while(1){
     }
}
Ono što mislim da si najviše fulao u ovoj priči je činjenica da pokušavaš promjenom OCR2A registra mjenjati duty PWM-a, to se radi na sasvim drugi način. OCR2A registar je gornja vrijednost tvog TIMER-a i kada jedamput podesiš TIMER na 20 kHz ovaj registar više ne diraš. Ako promjeniš gornju vrijedost TIMER-a u OCR2A registru odmah promjeniš i izlaznu frekvenciju PWM-a, a to ne želiš.

Tvoj TIMER uvijek broji od 0 do vrijednosti upisane u OCR2A registar i to više nikada ne mjenjaš. Kod AVR-a imaš i OCR2B registar kojeg trebaš iskoristiti za Duty PWM-a. Prvenstveno trebaš podesiti TIMER da ti OCR2B registar upravlja izlaznim pinom mikrokontrolera. Za to ti služe COM bitovi TIMER-a. U svakom modu TIMER-a COM bitovi znače drugačiju konfiguraciju, stoga moraš naći tablicu COM bitova za TIMER 2 u Fast PWM načinu rada. Ova tablica nalazi se na stranici 188 datasheeta imena "Compare Output Mode, Fast PWM mode". U toj tablici izabereš kakav PWM želiš, inverting ili non-inverting. Tebi je zapravo svejedno jeli inverting ili non inverting-mod. Jedina razlika ovih modova je što će PWM na resetu TIMER-a biti u 0 ili 1, a na compare match sa registrom OCR2B promjeniti stanje.

Za ovaj primjer odabrati ćemo mod u kojemu TIMER postavlja izlaz PWM-a na 1 kada se resetira na 0. Ovaj način rada po datasheetu se zove: "Clear OC2B on Compare Match, set OC2B at BOTTOM", a bitovi koji ga opisuju su:
COM2B1 = 1
COM2B0 = 0


Oba bita nazale se u registru TCCR2A opisani na stranici 187 datasheet-a. U ovom slučaju moraš samo COM2B1 podići u log 1 i to u software-u izgleda ovako:

Code: Select all

#include <avr\io.h>

int main(void){
     OCR2A = 99;                        /* new TOP: (99+1)*0,5us = 50us -> 20kHz   */
     TCCR2A |= (1<<WGM20)|(1<<WGM21);   /* Fast PWM, TOP OCR2A                     */
     TCCR2B |= (1<<WGM22); 
     TCCR2A |= (1<<COM2B1);             /* Clear OC2B on Compare Match, set at BOT */
     TCCR2B |= (1<<CS21);               /* Run TIMER 2 from prescaler clk/8, 2 Mhz */
     
     while(1){
     }
}
Kada si podesio COM bitove na ovu konfiguraciju TIMER će u slučaju kada dođe na vrijednost 0 uvijek postaviti izlaz PWM-a na logičku jedinicu, a spustiti će ga na nulu kada TIMER nabroji do OCR2B registra. Upozoravam "OCR2B" registra, a ne "OCR2A" registra. OCR2A registar je onaj koji ti osigurava 20 khz PWM.

OCR2B registar je onaj kojim upravljaš duty PWM-a, njega postavljaš u interval [0-OCR2A] registra. Sve što još moraš napraviti da bi dobio PWM je konfigurirati DUTY u OCR2B registru i postaviti OC2B pin kao izlaz.

Kako vidim po pinovima MCU-a (OC2B) je PH6 i na njemu ćeš generirati PWM, stoga PH6 moraš postaviti kao izlaz:

Code: Select all

#include <avr\io.h>

int main(void){
     
     DDRH |= (1<<PH6);                  /* set output -> PWM 20 Khz                */
     OCR2A = 99;                        /* new TOP: (99+1)*0,5us = 50us -> 20kHz   */
     TCCR2A |= (1<<WGM20)|(1<<WGM21);   /* Fast PWM, TOP OCR2A                     */
     TCCR2B |= (1<<WGM22); 
     TCCR2A |= (1<<COM2B1);             /* Clear OC2B on Compare Match, set at BOT */
     TCCR2B |= (1<<CS21);               /* Run TIMER 2 from prescaler clk/8, 2 Mhz */
     
     while(1){
     }
}
Stvari bi sada trebale biti jednostavne. Duty podešavaš u OCR2B registu jer će TIMER promijeniti stanje OC2B pina svaki puta kada dođe do vrijedosti OCR2B registra. Timer ti uvijek broji do TOP vrijednosti zadane OCR2A registrom i ona je 20 kHz. Tvoj duty PWM-a ide od 0 do 99, jer je 99 i maksimalna vrijednost TIMER-a pošto čitav cirkus nakon toga počinje iz nule.

Ja ću čisto reda radi staviti duty na vrijedost 50% što bi trebalo biti upis 49 u OCR2B registar. To bi bilo PWM 20 khz duty 50%. SW izgleda ovako:

Code: Select all

#include <avr\io.h>

int main(void){
     
     DDRH |= (1<<PH6);                  /* set output -> PWM 20 Khz                */
     OCR2A = 99;                        /* new TOP: (99+1)*0,5us = 50us -> 20kHz   */
     OCR2B = 49;                        /* set duty 50% (freq 20 khz)              */
     TCCR2A |= (1<<WGM20)|(1<<WGM21);   /* Fast PWM, TOP OCR2A                     */
     TCCR2B |= (1<<WGM22); 
     TCCR2A |= (1<<COM2B1);             /* Clear OC2B on Compare Match, set at BOT */
     TCCR2B |= (1<<CS21);               /* Run TIMER 2 from prescaler clk/8, 2 Mhz */
     
     while(1){
     }
}
Ovo nisam testirao jer nemam hardware, ali vrlo je mala mogućnost da sam se negdje zeznuo u proračunima. Nadam se da ćeš iz ovog teksta shvatiti u čemu je trik tvog problema. Ima tu još sitnica za objasniti, ali danas mi se više neda pisati... Mislio sam da ću i ovo natipkati brzo, ali izgubih više od sat vremena...

Pozdrav,
Josip Štivić
InTheStillOfTheNight
User avatar
InTheStillOfTheNight
Odlično uznapredovao
Odlično uznapredovao
Posts: 938
Joined: 01-06-2006, 17:54
Location: Zagreb

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by InTheStillOfTheNight »

InTheStillOfTheNight wrote: Ako je jedna clock TIMER-a 0.5 us (freq 2Mhz, clk/64)
:azdaja: nije clk/64 nego clk/8 :)

Još sam ti nešto htio navesti, ali zaboravih... Ako ti MCU ima bootloader a MCU starta s adrese bootloadera postoji mogućnost da bootloader koristi TIMER2. Moguće je da on podesiti registre TIMER-a ali ih ne resetira na 0 pa bi bilo poželjno da u inicijalizaciji TCCR2A i TCCR2B registre najprije postaviš na 0, a tek onda radiš inicijalizaciju "ILI" operatorima.

Pozdrav,
Josip Štivić
InTheStillOfTheNight
User avatar
InTheStillOfTheNight
Odlično uznapredovao
Odlično uznapredovao
Posts: 938
Joined: 01-06-2006, 17:54
Location: Zagreb

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by InTheStillOfTheNight »

Baš naletim bez veze na forum i kolega @sonata nestao, bez traga... Pa kome sam ja sve ovo pisao, sebi sigurno ne. I onda se čudimo zašto dosta forumaša, koji i znaju što i kako napraviti, jednostavno ne žele gubiti vrijeme pisanjem. Vidim kolega @kizo je odustao i prije mene. Baš bez veze ispisah 4 stranice teksta. Ovo mi je već drugi opširan tekst koji sam napisao, kako se čini, samo za sebe.

:azdaja:
InTheStillOfTheNight
Maki
Odlično uznapredovao
Odlično uznapredovao
Posts: 766
Joined: 02-07-2012, 12:54

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by Maki »

Nije samo za tebe :)
Forum je otvoren za "javnost" mozda netko naide na isti ili slican problem . Osobno cesto puta navratim na forum samo da vidim ima li novih dikusija kako bi malo prosirio svoje znanje :P makar da povrsno ulovim naslov nove teme pa kad naidem na problem znam gdije trazit odgovor.
A ko zna zasto kolega sonata nije odgovorio :roll:
User avatar
Kizo
Pravo uznapredovao :)
Pravo uznapredovao :)
Posts: 387
Joined: 01-11-2009, 22:40
Location: Hrvatska

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by Kizo »

Kada postoji problem, onda se fino posta dio kôda koji ne radi i objasni se po čemu se ponaša drugačije od zamišljenog.
Respekt Noćnom na tako detaljnom odgovoru kao i uvijek. ;-)
sonata
Napredujem
Napredujem
Posts: 121
Joined: 08-01-2013, 18:01

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by sonata »

InTheStillOfTheNight wrote:Baš naletim bez veze na forum i kolega @sonata nestao, bez traga... Pa kome sam ja sve ovo pisao, sebi sigurno ne. I onda se čudimo zašto dosta forumaša, koji i znaju što i kako napraviti, jednostavno ne žele gubiti vrijeme pisanjem. Vidim kolega @kizo je odustao i prije mene. Baš bez veze ispisah 4 stranice teksta. Ovo mi je već drugi opširan tekst koji sam napisao, kako se čini, samo za sebe.

:azdaja:
Sori, tek sam jučer stigao izvući osciloskop na stol, malo sam u nekoj drugoj gužvi ovih dana. Hvala puno na opisu, to je otprilike isto što piše u datasheet-ovima i na raznim sajtovima, doduše, nigdje nije ovako detaljno objašnjeno i to na ne-engleskom :-)

Probao sam kôd iz zadnjeg prozora, čisti C/P, da bih se nakon početnog čuđenja sjetio da sam prije koji dan skurio pin 9, k'o za vraga, baš taj kojeg trebam :roll:

"Preselio" sam kôd na tajmer 4 i koristio izlaz 7 (PH4, tako da bude isto "B" izlaz kao što je i pin9-PH6):

Code: Select all

     DDRH |= (1<<PH4);         
     OCR4A = 99;                   
     OCR4B = 49;                   
     TCCR4A |= (1<<WGM40)|(1<<WGM41); 
     TCCR4B |= (1<<WGM42);
     TCCR4A |= (1<<COM4B1);          
     TCCR4B |= (1<<CS41);
Kasnije sam "skužio" da je to 16-bitni timer pa sam omjere frekvencije i top-counter vrijednosti dijelio sa 65535, a ne sa 255, tako da je OCR4A = 25344.

No, i ovdje mi se događalo isto što mi se događalo na tajmeru2 (dok nisam skurio pin 9) - što god da upišem u registre OCRxA i OCRxB, na neutvrđen način mi se mijenja samo duty cycle. Frekvencija je bila konstantna, ako se dobro sjećam, oko 1 kHz.

Nisam imao vremena gledati u datasheet da li su registri jednaki i za tajmer 4 kao i za tajmer2, možda neke bitove treba drugačije postaviti. U svakom slučaju, sve sam to "odrađivao" već ranije, na slične načine, ali rezultat je uvijek bio fiksna frekvencija i čudno mijenjanje duty cycle-a. Ili mi osciloskop ne valja, što već spada u SF...

Probat ću još danas, ako stignem, iskoristiti tajmer 0 (iako njega ne volim dirati zbog drugih funkcija, ali samo za probu), obzirom da je taj isto 8-bitni. Javim čim isprobam.

Čekam sa ebay-a još dvije pločice sa 328 čipom pa kad to dođe, probat ću i to, možda je ovaj moj 2560 neki defektni primjerak (pin 9 svakako je defektan, iako ima zaštitu, nema zaštitu od mojih egzibicija)

Još jednom isprika na "zakašnjeloj reakciji"...

P.S. Ako netko ima osciloskop i ATmega2560, bio bih zahvalan da proba natjerati pin9 na 20kHz.
Nullius addictus iurare in verba magistri
sonata
Napredujem
Napredujem
Posts: 121
Joined: 08-01-2013, 18:01

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by sonata »

Update: Evo, pogledah u datasheet, timer 2 ima 7 waveform modova, a timer4 15 pa treba još jedan bit (WGM3) postaviti u jedinicu da se dobije fast PWM kojem je "top" smješten u registru OCRxA. Ovo što sam ja jučer probao je bio Fast PWM sa 10-bitnim brojanjem i granicom u 1024. Tako da nije nikakvo čudo što je frekvencija bila fiksna :oops:

Jučer se nisam stigao pozabaviti time jer sam izvadio osciloskop zbog nečeg drugog :D

Znači, u inicijalizaciju treba dodati još "paljenje" bita WGM43 i stvar bi trebala proraditi. Ako stignem danas popodne, javim rezultate.
Nullius addictus iurare in verba magistri
User avatar
InTheStillOfTheNight
Odlično uznapredovao
Odlično uznapredovao
Posts: 938
Joined: 01-06-2006, 17:54
Location: Zagreb

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by InTheStillOfTheNight »

Ja sam testirao svoj zadnji source na ATMEGA2560 16 MHz clock. pregledao sve osciloskopom i radi. Objašnjenje imaš pa sad istim principom podesiš bilo koji TIMER. Jedino opet moraš proći datasheet jer uvijek postoje nekakve razlike između TIMER-a.
InTheStillOfTheNight
sonata
Napredujem
Napredujem
Posts: 121
Joined: 08-01-2013, 18:01

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by sonata »

Hvala još jednom i oprosti na kašnjenju s odgovorom. Kad probam ponovo, sve po PS-u, javim rezultate.
Nullius addictus iurare in verba magistri
sonata
Napredujem
Napredujem
Posts: 121
Joined: 08-01-2013, 18:01

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by sonata »

Probao sam na brzinu uključiti još WGM3 bit tako da na 16-bitnom timeru dobijem fast PWM sa TOP-om u OCRxA registru i nije uspjelo - frekvencija uopće ne ovisi o vrijednosti OCRxA registra (konkretno za tajmer4, OCR4A na Mega 2560) iako su svi WGM bitovi (0 do 3) bili postavljeni u "1" tako da je trebao biti odabran mod "Fast PWM" sa brojanjem do OCRxA, a ne do 1024 (10-bitni fast PWM kad su bitovi WGM postavljeni u 0111) ili ne znam do kud.

Ne znam više ništa. Kad mi sa ebay-a stignu nove pločice Arduino Nano (328), probat ću na njima, možda je meni na ovom 2560 stvarno nešto krepalo (svakako znam da sam skurio izlaz 9, a možda je skureno još nešto)...
Nullius addictus iurare in verba magistri
User avatar
InTheStillOfTheNight
Odlično uznapredovao
Odlično uznapredovao
Posts: 938
Joined: 01-06-2006, 17:54
Location: Zagreb

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by InTheStillOfTheNight »

Sam si rekao TIMER2 na 20 khz PWM... Za TIMER 4 ne da mi se otvoriti datasheet i tražiti što si mogao zeznuti. Čekaj drugi board i probaj na njemu, možda si zapalio MCU, a možda si nešto krivo programirao, ne znam...
InTheStillOfTheNight
sonata
Napredujem
Napredujem
Posts: 121
Joined: 08-01-2013, 18:01

Re: Promjena PWM frekvencije na ATmega (328, 2560...)

Post by sonata »

Kao što sam napisao, timer 4 je 16-bitni i ima 15 umjesto 7 modova "generacije valnih oblika". Za Fast PWM sa gornjom granicom countera u OCR4A treba podesiti sva četiri WGM bita u "1", a za timer2 ne postoji "četvrti" bit za WGM. I kad upalim sva 4 bita (WGM40 do WGM43), nemam "odabrani mod" nego nešto fiksne frekvencije, a promjena OCR4A utječe samo na duty cycle. Programski kod je onaj kojeg sam postao (modifikacija tvog), samo što sam još dodao i "paljenje" WGM43 bita.

Niš', kad stignu novi, probam ponovo.

U međuvremenu sam zaključio da mi nije previše ni 32 kHz pa mi sve skupa više ne treba, ali sad me baš zaintrigiralo... Ne volim stvari ostaviti bez objašnjenja :D
Nullius addictus iurare in verba magistri
Post Reply