PWM (Pulse Width Modulation), darbe genişlik modülasyonu anlamına gelir. Dijital elektronikte motor hız kontrol uygulamalarında, ışık parlaklık uygulamalarında, servo motor açı uygulamalarında sıklıkla kullanılmaktadır.
PWMde darbenin lojik 1 ve lojik 0 zaman aralıkları değiştirilerek farklı voltajlar elde edilmektedir. Örneğin 100hz 5v kare dalganın lojik 1 süresi %50, lojik 0 süresi %50 olursa çıkış gerilimi 2,5V olmaktadır.
PWM Dalganın etkin değerini hesaplamak için Veff = (darbe doluluk süresi * 5) / periyot süresi
Örnek: Periyot 1 msn, Lojik 1 süresi 250 usn olan kare dalganın etkin değeri?
(250usn*5)/1msn = 1,25V olur. Yani %25 PWM darbesi üretilmiştir.
Aşağıda ki resimde PWM dalganın %lik olarak çıkışı verilmiştir.
Bazı PIC modellerinde donanımsal olarak PWM pini bulunmaktadır. Ancak PWM pin sayısı oldukça azdır. Bunun için yazılımsal PWM oluşturacağız.
LED’in parlaklığının çoğalıp azalması, motorun hızının çoğalıp azalması için sinüs şeklinde PWM üretmemiz lazım. Doğrusal bir PWM oluşturursak göze pek hoş gelmemektedir. Bunun için 0-1000 aralığında sinüs dalgası elde edelim. Bu sayıları excelde formül ile oluşturabilirsiniz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ 510,520,531,541,552,562,573,583,593,603,614,624,634,644,654,664,674,684, 693,703,712,722,731,740,750,759,767,776,785,793,802,810,818,826,834,842, 849,857,864,871,878,885,891,898,904,910,916,922,927,933,938,943,947,952, 956,960,964,968,972,975,978,981,984,986,989,991,992,994,996,997,998,999, 999,999,1000,999,999,999,998,997,996,994,992,991,989,986,984,981,978,975, 972,968,964,960,956,952,947,943,938,933,927,922,916,910,904,898,891,885, 878,871,864,857,849,842,834,826,818,810,802,793,785,776,767,759,750,740, 731,722,712,703,693,684,674,664,654,644,634,624,614,603,593,583,573,562, 552,541,531,520,510,500,489,479,468,458,447,437,426,416,406,396,385,375, 365,355,345,335,325,315,306,296,287,277,268,259,250,240,232,223,214,206, 197,189,181,173,165,157,150,142,135,128,121,114,108,101,95,89,83,77,72,66, 61,56,52,47,43,39,35,31,27,24,21,18,15,13,10,8,7,5,3,2,1,0,0,0,0,0,0,0,1, 2,3,5,7,8,10,13,15,18,21,24,27,31,35,39,43,47,52,56,61,66,72,77,83,89,95, 101,108,114,121,128,135,142,150,157,165,173,181,189,197,206,214,223,232, 240,250,259,268,277,287,296,306,315,325,335,345,355,365,375,385,396,406, 416,426,437,447,458,468,479,489,500}; |
Görüldüğü gibi 500 den başlayıp 1000e ardında hafif bir eğimle 0a inip tekrar 500e çıkan, 300 elemanlı dizi oluşturmuş olduk.
Grafiksel olarak bakacak olursak;
Oluşturulan bu sayıları da Lojik 1 ve Lojik 0 olarak pine aktardığımız zaman yazılımsal sinüs şeklini elde etmiş oluruz.
Sinüsün simülasyonda görülebilmesi için PWM pini çıkışına seri 10k ve şaseye 1000nF kondansatör bağlamamız gerekmektedir. Ancak gerçekte böyle bi bağlantıya gerek yoktur.
Devre;
Yazılım;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
#include <16F84a.h> #FUSES NOWDT,XT,NOPUT,NOPROTECT #use delay(clock=4000000) #use fast_io(B) #define pwm PIN_B0 const unsigned int16 sinus1[300]={ 510,520,531,541,552,562,573,583,593,603,614,624,634,644,654,664,674,684, 693,703,712,722,731,740,750,759,767,776,785,793,802,810,818,826,834,842, 849,857,864,871,878,885,891,898,904,910,916,922,927,933,938,943,947,952, 956,960,964,968,972,975,978,981,984,986,989,991,992,994,996,997,998,999, 999,999,1000,999,999,999,998,997,996,994,992,991,989,986,984,981,978,975, 972,968,964,960,956,952,947,943,938,933,927,922,916,910,904,898,891,885, 878,871,864,857,849,842,834,826,818,810,802,793,785,776,767,759,750,740, 731,722,712,703,693,684,674,664,654,644,634,624,614,603,593,583,573,562, 552,541,531,520,510,500,489,479,468,458,447,437,426,416,406,396,385,375, 365,355,345,335,325,315,306,296,287,277,268,259,250,240,232,223,214,206, 197,189,181,173,165,157,150,142,135,128,121,114,108,101,95,89,83,77,72,66, 61,56,52,47,43,39,35,31,27,24,21,18,15,13,10,8,7,5,3,2,1,0,0,0,0,0,0,0,1, 2,3,5,7,8,10,13,15,18,21,24,27,31,35,39,43,47,52,56,61,66,72,77,83,89,95, 101,108,114,121,128,135,142,150,157,165,173,181,189,197,206,214,223,232, 240,250,259,268,277,287,296,306,315,325,335,345,355,365,375,385,396,406, 416,426,437,447,458,468,479,489,500}; void main() { int16 n1,sayac,mark1,t1,t2,mark1_sayac; set_tris_b(0x00); output_b(0x00); output_low(pwm); mark1_sayac=0; n1=1; while(true) { if (mark1_sayac<300) mark1=(sinus1[mark1_sayac]); mark1_sayac++; if(mark1_sayac==300) mark1_sayac=0; t1=mark1; t2=1000-mark1; for(sayac=0;sayac<15;sayac++) { output_high(pwm); delay_us(t1); output_low(pwm); delay_us(t2); } } } |
Yazılımı çalıştırdığımız zaman osilaskop ekranında aşağıdaki gibi PWM sinyali görülmektedir.
Gördüğünüzü gibi düzgün bir sinüs elde etmiş olduk. Frekansı arttırmak veya azaltmak isterseniz for döngüsü içindeki sayaç limiti değiştirmeniz gerekir ben standart olarak 15 verdim.
Sinüs için excel tablosu: Sin Dalga