Ynt: Arduino PWM Frekansı

Başlatan burak54, 31 Aralık 2015, 03:28:46

burak54

Merhaba Arkadaşlar,
Arduinonun kullandığı ATMEL Atmega 2560 ya da 328P serili Mikrodenetleyicilerden düşük frekanslı PWM oluşturuyorum ancak benim için bu yetersiz. Bildiginiz yaklaşık 20 kHz oluşturup ayarlayabileceğim bir yöntem var mı? i2c ile haberleşen PWM chip i olabilir tek kanal TR de bulunabilen ya da başka bir şekilde nasıl ayarlayabilirim.Fikirlerinizi bekliyorum.

Teşekkürler.İyi Çalışmalar.

mesaj birleştirme:: 31 Aralık 2015, 03:37:49

http://forum.arduino.cc/index.php?topic=72092.0
Sitesinde bu yorumu buldum bunu inceleceğim ve deneyeceğim, sizde göz gezdirirseniz faydalı olur ve denediğimde umarım çalışır =) Yorumlarınız için şimdiden teşekkürler.

Hi guys! After some day, I finally managed to change the PWM frequency of all PWM pins of my Arduino Mega 2560.
All the explanations are foundamentally here:
http://usethearduino.blogspot.com/2008/11/changing-pwm-frequency-on-arduino.html
In this brief article the author explains very clearly how to change some values in Arduino Diecimila registers, in order to enhance the PWM frequency.
Here I simply modified a little bit the author'code to make it match with Arduino 2560.
Here follows my brief instructions and descriptions!

1) Arduino 2560 has 12 pins supporting PWM. They are from 2 to 13 included.

2) the PWM default frequency is 490 Hz for all pins, with the exception of pin 13 and 4,
whose frequency is 980 Hz (I checked with an oscilloscope).

3) In order to change frequency on pin 'A', we have to change some value in the timer
(or register), controlling pin 'A'. This is the list of timers in Arduino Mega 2560:

timer 0 (controls pin 13, 4);
timer 1 (controls pin 12, 11);
timer 2 (controls pin 10, 9);
timer 3 (controls pin 5, 3, 2);
timer 4 (controls pin 8, 7, 6);

As you can see, a given timer controls more than one pin (every change about a timer will affect all pins depending on it!).

4) You can access a timer simply changing in your code (tipically in the setup()), the value of variable TCCRnB, where 'n' is the number of register. So, if we want  to change the PWM frequency of pins 10 and 9,  we will have to act on TCCR2B .

5) The TCCRnB is a 8 bit number.  The first three bits (from right to left!) are called CS02, CS01, CS00, and they are the bits we have to change.
Those bits in fact represent an integer number (from 0 to 7) called 'prescaler' , that Arduino uses to generate the frequency for PWM.

6) First of all, we have to clear these three bits, i.e they must be all set to 0:

int myEraser = 7;             // this is 111 in binary and is used as an eraser
TCCR2B &= ~myEraser;   // this operation (AND plus NOT),  set the three bits in TCCR2B to 0

7) now that CS02, CS01, CS00  are clear, we write on them a new value:

int myPrescaler = 3;         // this could be a number in [1 , 6]. In this case, 3 corresponds in binary to 011.   
TCCR2B |= myPrescaler;  //this operation (OR), replaces the last three bits in TCCR2B with our new value 011

8) now we have a new PWM frequency on pin 9 and 10!


I registered those values on all PWM pins, changing the value of prescaler (the only exception are pins 13 and 14, see later):

prescaler = 1 ---> PWM frequency is 31000 Hz
prescaler = 2 ---> PWM frequency is 4000 Hz
prescaler = 3 ---> PWM frequency is 490 Hz (default value)
prescaler = 4 ---> PWM frequency is 120 Hz
prescaler = 5 ---> PWM frequency is 30 Hz
prescaler = 6 ---> PWM frequency is <20 Hz

(prescalers equal t 0  or 7 are useless).

Those prescaler values are good for all timers (TCCR1B, TCCR2B, TCCR3B, TCCR4B) except for timer 0 (TCCR0B). In this case the values are:

prescaler = 1 ---> PWM frequency is 62000 Hz
prescaler = 2 ---> PWM frequency is 7800 Hz
prescaler = 3 ---> PWM frequency is 980 Hz (default value)
prescaler = 4 ---> PWM frequency is 250 Hz
prescaler = 5 ---> PWM frequency is 60 Hz
prescaler = 6 ---> PWM frequency is <20 Hz

Note that timer 0 is the one on which rely all time functions in Arduino: i.e., if you change this timer, function like delay() or millis() will continue to work but at a different timescale (quicker or slower!!!)

Ok, I hope it will help!
Cheers, Valerio 

94onur94

DDRB = 0xFF;
PORTB = 0; 
ICR1 = 799;
OCR1A = 399;
OCR1B = 399;
TCCR1A = 0xA2;
TCCR1B = 0x19;

9 ve 10 nolu pinlerden 20 KHz verir.

burak54

Merhaba @94onur94 ,
Cevabın için teşekkür ederim. Bu ayarlamaları Arduino nun IDe sinde mi yoksa Atmel Studio da mı ? Yapmalıyım.
İyi çalışmalar.

94onur94

İkisinde de olur direk arduino idesine komut olarak yaz bunları.

burak54

Tamamdır deneyeceğim teşekkür ederim.

pax

neden 20Khz?
PWM frekansının düşük veya yüksek olması arasında bariz bir fark mıdır?

burak54

#6
Motoru bir 2 khz de bir de 100 khz de surmenizi tavsiye ederim.Motorun sesine yari iletkenin isinmasina ve acilip kapanabilme suresine gore onem kazanmaktadir frekans benim bildigim.Bu konuda tecrubeli arkadaslarin yorumlarini okumak isterim.20kHz Pwm in sistem uzerinde tararken ozelikle Duty i kisinca titreme olup olmayacagini gormek icin 20kHz i denemek istedim. 1khz de olmaya basladi.

mesaj birleştirme:: 01 Ocak 2016, 02:44:35

@94onur94 Denedim 20kHz frekans oluştu . Daha sonra Registerlara baktım TCCR1B nin "CS" son 3 bitini değiştirerek yani TCCR1B = 0x1A; Prescale değiştirebildiğimizi öğrendim ve 8 e bölerek 2.5Khz oluşturdum ancak Timer için verdiğin değerlerden nasıl bir hesaplama ile Frekansı istediğimiz frekansa ulaşıldığını anlamadım.Mesela 1.5Khz oluşturmak istesem ne yapmalıyım bir bilgin var mı ? Teşekkürler.

mehmet

Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr

burak54

Bu Pwm oluşturmayı yaptıktan sonra SPI dan veri yolluyordum çalışmamaya başladı sanırım onun timeri nı etkiliyor. Timer1 ile de interrupt kullanıyordum.Bir fikri olan var mı bu konuda arkadaşlar ?

mehmet

Timer1 yerine başka birini seçip deneyiniz.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr

burak54

Timer 2 i seçip onun ilgili pini ile pwm oluşturdum şu anda çalışıyor teşekkür ederim. İyi çalışmalar

best23

arkadaşlar ben matlab simulink üzerinde arduino kullanıyorum ve frekansı değiştirmek istiyorum nasıl yapabilirim Yardım edebilirmisiniz.