Pulse Width Modulation (Darbe Genişlik Modülasyonu ya da Sinyal Genişlik Modülasyonu) olarak da bilinen PWM, analog bir sinyalin dijital bir cihaz ile kontrol edilmesi için kullanılan bir sinyal işleme tekniğidir. PWM sinyali, düzenli aralıklarla tekrarlanan darbelerden oluşur. PWM sinyalde bir darbenin yüksek seviyede kalma süresi darbe genişliği, bu darbe genişliğinin bir periyotta olan yüzdesine "Duty Cycle" yani görev oranı veya görev döngüsü adı verilir. Bir periyotta sinyal sürekli olarak yüksek ise; Duty Cycle %100, sürekli olarak düşük ise; %0’dır. Duty Cycle değiştirilerek sinyalin etkili ortalaması kontrol edilir. Genişlik arttıkça ortalama değer de artar ve genişlik azaldıkça ortalama değer de düşer. Görev döngüsünün genişliği iletilen güç ile doğru orantılıdır. Güçteki diğer bir faktör de anahtarlama frekansıdır. Anahtarlama frekansı ne kadar büyükse, PWM ile aktarılan sinyalin gücü de o kadar artar.
Modülasyon işlemi gerçekleştiren bu tekniğin asıl amacı cihazlara verilen elektriğin gücünü kontrol altında tutmaktır.
Düşük bir frekans ile üretilen darbe sinyalleri ve bunlarla kontrol edilen bir lambada, lambanın yanma ve sönme zamanları hissedilebilecektir. Bu durum ışığın titremesi şeklinde görünecektir. Bunu engellemek için anahtarlama frekansı yükseltilmelidir.
Dijital cihazlar, 0’lar ve 1’ler (0V ve 5V, 3.3V) dışında çıkış olarak başka voltaj seviyeleri üretemezler. O halde 0V ile 5V arasında başka bir voltaj elde etmenin yolu nedir? İşte PWM bunun cevabıdır. Darbelerin genişliklerini ve frekanslarını değiştirerek, ara voltaj seviyelerini kolayca taklit edebiliriz. Saniyede yaklaşık 100 döngüde %50 duty cycle sahip bir pwm sinyali örneğini ele aldığımızda 2.5V çıkış elde etmiş oluruz.
PWM tekniği, düşük anahtarlama kaybı, yüksek verimlilik, dijital kontrole uyum ve sinyal kontrolü gibi birçok alanda avantaj sağlar. PWM tekniği, analog sinyallerin dijital cihazlar ile kontrol edilmesi, değişken güç ve hız ihtiyacı olan pek çok uygulamada kullanılması açısından önemlidir. Yüksek verimlilik ve enerji tasarrufu sağlayan PWM, elektronik sistemlerin temel bir parçasıdır ve modern teknolojilerde yaygın olarak kullanılmaktadır.
Anahtarlama için kullanılan donanımlar
Hızın önemli olduğu yerde MOSFET, kayıpların az olması istenen yerde transistör (BJT) veya her ikisinin de avantajlarına sahip IGBT kullanılır. IGBT(Insulated Gate Bipolar Transistor ); izole edilmiş kapılı, iki kutuplu transistör anlamına gelir. Temel olarak 3 bacaklı bir yarı iletken devre elemanıdır. 4 katmandan (P-N-P-N) oluşur ve metal oksit yarı iletken (MOS) ile kontrol edilir. Yalıtılmış transistör de denir.
Duty Cycle Hesabı
Bilindiği gibi, doğru akım devrelerinde gerilim değeri olarak ortalama gerilim değeri ele alınır. Bu nedenle anahtarın kapalı kalma süresi ve/veya açık kalma süresi değiştirilerek, elde edilen gerilimin alacağı ortalama gerilim değeri değiştirilir. Anahtarlama ne kadar hızlı yapılırsa, PWM ile aktarılan sinyalin ortalama gerilimi ve gücü o kadar da artar. PWM yönteminde çıkış gerilimi ile giriş gerilimi arasındaki oran Görev Oranı (Duty Cycle) şöyle hesaplanır:
Anahtarın iletimde kalma süresinin iletimde ve kesimde kalma süresinin toplamına oranı olarak da ifade edilebilir.
PWM sinyallerinin yükselme süresi ve iniş süresi, sinyalin yüksek seviyeden düşük seviyeye veya tam tersine geçiş sürelerini belirtir. Daha hızlı yükselme ve iniş süreleri, daha hızlı geçiş ve daha keskin kenarlar sağlar.
PWM Sinyalinin Hesabı
Üretilen kare dalga darbe sinyallerinin genişliklerinin ortalaması, çıkışta üretilecek olan analog değerin elde edilmesini sağlar. Bu analog değer:
Formülde süreleri yerine koyduğumuzda;
Ymin = 0 olduğunu kabul edersek;
olur.
Örnek:
5V yüksek 0V düşük olan bir kare dalga için;
%60'lık bir duty cycle ile; 5V x 0.6 = 3V elde edilir.
%80'lik bir duty cycle ile; 4V x 0,8 = 4V elde edilir.
PWM dalgası elde etme yöntemleri
Delta: Delta modülasyonlu PWM sinyali, integral alıcı ve limitleyici devre yapıları ile elde edilir. İntegral sonucunun limitlere değmesi "off", diğer durumlarda "on" durumu oluştuğu için kare dalga oluşur.
Sigma - Delta: Bu modülasyonda ise çıkış sinyali, referans alınan sinyalden çıkartılır. Böylece hata sinyali elde edilmiş olur. Hata sinyalinin integralinin sonucuna göre eğer limite değiyorsa "off", değmiyorsa "on" durumu oluşturularak kare dalga elde edilir.
Boşluk - Vektör: 3 fazlı AC uygulamalar için algoritma kullanılarak kare dalga elde edilir.
Direkt Tork Kontrol (DTC): AC motorlarda kullanılmak üzere geliştirilen bir PWM tekniğidir. Delta modülasyon tekniğinden üretilmiştir. Motora gönderilen sinyal belirli bir filtreden geçirilir ve motorun torku ile manyetik akı kontrol altında tutulur.
Zaman Bölücü: Özellikle mikroişlemcilerin PWM çıkışları tarafından kullanılırlar. Değişken görev döngüsüne sahip devrelerde de kullanılabilirler.
PWM Uygulama Alanları
Yüksek frekanslı devrelerde PWM sinyal kontrolü sayesinde, güç kontrolü ve aktarılan güç miktarının ayarlanması sağlanır.
Mikro denetleyici ile DC motor kontrolü veya servo motor kontrolü gerçekleştirmek için PWM tekniğini kullanılır.
Voltaj regülatör devrelerinde de PWM tekniğine başvurulur. Uygun görev döngüsünde anahtarlama yaparak voltajı kesme-verme işlemleri ile voltaj istenen bir seviyede tutulur. Bunun sonucunda elektronik gürültü oluşur; ancak LC filtre ile bu durumu aşmak mümkündür.
Osilatörler ile birlikte bazı ses efektlerini elde etmek için PWM tekniği kullanılabilir. Aynı zamanda yükseltici devrelerinde ve amfilerde kontrol amacıyla da PWM tekniğine başvurulur.
Güneş enerji sistemlerinde ve rüzgâr enerjisi sistemlerinde kullanılan mikro invertörlerin tasarımı PWM tekniğine uygun olarak gerçekleştirilir.
Bir Analog Sinyal Ve Eşdeğeri Olan PWM Sinyali:
AC Motor İçin PWM Tekniği ile Sinüs'e Yakın Bir Dalga Eldesi:
Arduino PWM Sinyali Üretme
Arduino’daki PWM çıkış pinleri olan 3, 5, 6, 9, 10, 11 nolu pinlerden analogWrite(); komutu ile PWM sinyali üretebildiğimizi daha önceki konularda işlemiştik. Fakat bu komut ile bu pinlerde sadece belirli frekanslarda PWM sinyali üretebiliyorduk. Bunlar; 5 ve 6 nolu pinlerden yaklaşık 980Hz; 3, 9, 10, 11 nolu pinlerden ise yaklaşık 490 Hz’di. Bu pinlerden istediğimiz frekanslarda PWM sinyali alabilmek için Arduino içindeki Timer’ları kullanmamız gerekiyor. Bu Timer’ları kullanmak için hazır kütüphaneler bulunmasının yanı sıra, Timer’lara direk ulaşarak da bu işlemi yapmak mümkündür. Biz her iki konuyu da burada işleyeceğiz.
Kütüphane Kullanarak PWM Üretme
PWM üretmek için gerekli olan kütüphane Arduino içerisinde olmadığı için haricen eklememiz gerekmektedir. GitHub’dan “terryjmyers” kullanıcısının oluşturduğu PWM kütüphanesini https://github.com/terryjmyers/PWM linkinden indirdik. Arduino IDE’sinde “Taslak > library ekle > .ZIP kitaplığı ekle” yaparak klasör içerisinde ZIP olarak bulunan PWM kütüphane dosyasını Arduino’ya ekliyoruz. Ardından #include <PWM.h> komutu ile kütüphaneyi projemize dahil ediyoruz. Bu kütüphane Timer1’i kullandığı için sadece 9 ve 10 nolu pinleri kullanabiliriz.
InitTimersSafe();
Timer kesmesindeki registerları sıfırlayarak gerekli kurulumları yapar.
SetPinFrequencySafe(pwm_pin, frekans);
Belirtilen pine gönderilecek PWM sinyalinin frekansını belirler. Pin, Arduino’nun PWM pinlerinden biridir. Frekansın birimi Hz’dir. Frekans en küçük 1 Hz olabilir.
Örnek: SetPinFrequencySafe(9, 10000); //9. pine 10kHz PWM sinyali gönder.
pwmWrite(pwm_pin, duty_cycle);
Belirtilen pine ait Duty Cycle değerini belirler. duty_cycle değeri = 0 ise; Duty Cycle’ın %0 olduğunu, 127 ise; Duty Cycle’ın %50 olduğunu, 255 ise; Duty Cycle’ın %100 olduğunu gösterir. duty_cycle değişkeni 8 bittir. Bunun için 0 – 255 arasında olabilir.
Örnek: pwmWrite(9, 127);
pwmWriteHR(pwm_pin, duty_cycle);
Bir önceki komut ile aynı işlevi görür. Fakat burada farklı olan; bu komuttaki duty_cycle değişkeninin 16 bit olması ve bundan dolayı 0 – 65535 arasında değer alabilmesidir. Böylelikle Duty Cycle değişkeni daha hassas değerler alabilir.
Örnek: pwmWriteHR(9, 528);
Timer’ları Kullanarak PWM Üretme
Timer’lar ile PWM sinyali üretme konusuna başlamadan önce “interrupt_kesme_kullanımı” konusundaki “timer kesmeleri” konusunun incelenmesi önem arz etmektedir.
Arduino Uno’da 3 adet Timer vardır. Timer0 🡪 8 bit, Timer1 🡪 16 bit ve Timer2 🡪 8 bittir.
İki Adet Timer Kullanarak PWM Üretme
İstenilen frekans ve Duty Cycle’da PWM sinyali üretmek için Timer’ları kullanabiliriz. Zaman sayaçlarını ve kayıtçıları ayarlayarak, saat frekansını bölerek farklı değerlerde PWM üretmek mümkündür. Bunun için 2 adet Timer kullanılır. Timer’ın bir tanesi HIGH durumunu kontrol ederken, diğeri LOW durumunu kontrol eder. Arduino Uno’da yaptığımız uygulamada; Timer1 ile PWM sinyalin HIGH durumu, Timer0 ile PWM sinyalin LOW durumu kontrol ederiz. void setup() kısmında portu HIGH durumuna getirdik. Frekans 50hz ve Duty Cycle %5 olması için; Timer1’e 20ms olacak şekilde, Timer0’a da 1ms olacak şekilde değer verdik.
Program çalışmaya başladığında 1ms sonra Timer0 kesmesi oluşur ve port LOW yapılır. Ardından 19ms sonra Timer1 kesmesi oluşur ve port HIGH yapılır. Burada kayıtçılardan, Timer1’e 20ms olacak şekilde, Timer0’a da 1ms olacak şekilde yeniden değerler verilir ve senkronizasyon sağlanmış olur. Ardından 1ms sonra Timer0 kesmesi oluşur ve port LOW yapılır. Ardından yine 19ms sonra Timer1 kesmesi oluşur ve port HIGH yapılır. Yani Timer1 her 20ms de bir portu HIGH yaparken, Timer0 her 1 ms de bir portu LOW yapar.
Burada önemli bir nokta var. Timer0 her 1ms de bir porta LOW gönderirken 20. ms’ye geldiğimizde yine Timer0 portu LOW yapmaya çalışırken, Timer1 de portu HIGH yapmaya çalışır. Burada LOW ve HIGH çakışması olabilir ama kayıtçılara yüklenen değerler ile 1 ms ve 20 ms süreleri tam olarak virgülü virgülüne denk gelmediği için çakışma olmuyor. Fakat Timer0’a 156 değeri yüklendiğinde PWM’de bir karışıklık oluşuyor.
Timer’ların Çıkış Portlarından PWM Sinyali Alma
ATmega328P'de Timer0, Timer1 ve Timer2 olmak üzere 3 adet zamanlayıcı vardır. Her Timer’ın 2 adet çıkış portu vardır. Timer, karşılaştırma kayıtçısına(OCRxA veya OCRxB) yüklenen değere ulaştığında, portların çıkışı değiştirilir(HIGH ise LOW, LOW ise HIGH şeklinde). Her Timer’ın iki çıkışı da normalde aynı frekansa sahiptir. Ancak karşılaştırma kayıtçısındaki değere göre farklı görev döngülerine sahip olabilir. Timer’ların her birinin sistem frekansını bölen 1, 8, 64, 128, 256 veya 1024 prescaler(bölme değeri ya da ön ölçekleme) değerleri vardır.
Ana PWM modları, aşağıda açıklanacak olan "Hızlı PWM(Fast PWM)" ve "Faz-doğrultmalı PWM(Phase Correct PWM Mode)" dir. Zamanlayıcı 0 ile 255 arasında veya 0 ile sabit bir değer arasında çalışabilir.
Timer’ları kontrol eden zamanlayıcı/sayaç kontrol kayıtçıları TCCRnA ve TCCRnB’ler vardır. Bu kayıtçılar üzerindeki bitler ile kontrol sağlanır. Bunlar:
WGM: Zamanlayıcının modunu ayarlar. (Bu bitler TCCRnA ve TCCRnB arasında bölünür)
CS: Sistem frekansını bölen ön ölçekleme kontrol bitleridir.
COMnAx: Compare Match Output A (Karşılaştırma Eşleşme Çıkışı A) anlamına gelir. Çıkış A'yı etkinleştirir/devre dışı bırakır/tersine çevirir.
COMnBx: Compare Match Output B (Karşılaştırma Eşleşme Çıkışı B) anlamına gelir. Çıkış B'yi etkinleştirir/devre dışı bırakır/tersine çevirir.
OCRnA: Çıkış A için karşılaştırma değerini tutan kayıtçıdır. Sayaç değeri ile bu kayıtçının değeri eşit olduğunda bu kayıtçıya ait çıkış, mod tarafından belirtildiği şekilde değiştirilir.
OCRnB: Çıkış B için karşılaştırma değerini tutan kayıtçıdır. Sayaç değeri ile bu kayıtçının değeri eşit olduğunda bu kayıtçıya ait çıkış, mod tarafından belirtildiği şekilde değiştirilir.
OCnA: OCRnA karşılaştırma kayıtçısı çıkış portu.
OCnB: OCRnB karşılaştırma kayıtçısı çıkış portu.
NOT: Timer1, 16 bitlik bir zamanlayıcıdır ve ek modlara sahiptir. Timer2'nin farklı ön ölçekleyici değerleri vardır.
NOT: Kayıtçıların bitlerinde değişiklik yapmak için: “|=” (veya eşit), “&=” (ve eşit),”=” (eşit) şeklindeki bitsel operatörler kullanılabilir. Kayıtçıdaki herhangi bir biti 1 yapmak için; “|=” i, 0 yapmak için; “&=” i kullanabiliriz. Bu bitsel operatörler kullanıldığında, kayıtçıdaki 0 yapılacak bitler önce, 1 yapılacak bitler ise en son ayarlanmalıdır. Çünkü bazı kayıtçılarda bu operatörlerle bir bit sıfır yapıldığında, tüm kayıtçıyı sıfırladığı görüldü. Bu nedenlerden dolayı bu operatörler yerine kayıtçı_adı=0b10010001 şeklinde ya da bitSet() ve bitClear() komutlarının kullanımı daha sağlıklı olmaktadır.
Arduino’da Timer’ların Çıkışları ve Kullandıkları PWM Pinleri:
Fast PWM Mode
Hızlı darbe genişliği modülasyonu veya hızlı PWM modu olarak tanımlanır. Yüksek frekanslı bir PWM dalga formu oluşturma seçeneği sunar. Hızlı PWM, tek eğimli çalışmasıyla, çift eğimli çalışma kullanan Phase Correct PWM seçeneğinden farklıdır. Hızlı PWM modunun frekansı, Phase Correct PWM frekansının 2 katıdır. Bu yüksek frekans, hızlı PWM modunu güç düzenlemesi ve DAC uygulamaları için çok uygun hale getirir. Yüksek frekans, fiziksel olarak küçük boyutlu harici bileşenlere (bobinler, kapasitörler) izin verir ve bu nedenle toplam sistem maliyetini azaltır.
Fast PWM’de Sayaç 0’dan başlar. Ayarlanan moda göre sayaç; OCRnA karşılaştırma değerine kadar(OCRnB’de böyle bir özellik yoktur) ya da Timer’ın maximum değerine kadar sayar (sayacın maximum değerinin Timer’ın bit sayısına bağlı olduğunu unutmayın). Sonra tekrar 0’dan başlayarak devam eder. Bu şekilde Timer sinyali üretilmiş olur. TCNTx kayıtçısında herhangi bir değer yüklenmez. Sayacın OCRnA karşılaştırma değerine kadar saydığı modda PWM için yalnız OCRnB çıkışı kullanılabilir. OCRnA hem en üst değer hem de PWM karşılaştırma değeri olarak kullanılamaz. OCRnA karşılaştırma kayıtçısı çıkışı OCnA’nın PWM frekansı %50 Duty Cycle’dadır. Sayaç karşılaştırma değerine ya da maximum değere kadar ulaştığında taşma bayrağı (TOV0) set edilir ve kesmeler aktif edilirse kesme oluşur. Fakat kesme şuan ki konumuz değildir.
a.1- Timer’ın Maximum Değerine Kadar Saydığı Mod
Yukarıdaki grafikte görüldüğü üzere Timer sayacı 0’dayken port çıkışları HIGH olur. Sayaç, karşılaştırma kayıtçısı değerine ulaştığında ise port çıkışları LOW olur. Bu işlem sürekli olarak devam eder. Her iki çıkış da aynı frekans değerindedir. Karşılaştırma kaydındaki değer ne kadar yüksekse, Duty Cycle(Görev Döngüsü) de o kadar yüksek olur.
Burada Timer başlangıç değeri = 0’dır. Timer bitiş değeri ise; Timer’ın maximum değeridir.
a.2 - Timer’ın OCRnA Karşılaştırma Değerine Kadar Saydığı Mod
Karşılaştırma değerine ulaşıldığında çıkışın değiştirildiği(HIGH ise LOW, LOW ise HIGH şeklinde) durumu göz önüne aldığımızda; yukarıdaki grafikte görüldüğü üzere Timer sayacı 0’dayken OCnA ve OCnB çıkışları HIGH durumundadır. OCRnB karşılaştırma değerine ulaşıldığında OCnB çıkışı LOW olur. Sayaç devam eder ve OCRnA karşılaştırma değerine ulaşıldığında OCnA çıkışı LOW olur. Aynı anda sayaç tekrar 0’a döndüğü için OCnB çıkışı değişir ve HIGH olur. OCnA çıkışı ise bir sonraki OCRnA karşılaştırma değerine kadar LOW olmaya devam eder.
Buradan anlaşılır ki; OCnA çıkışında 1 periyot oluştuğu sürede, OCnB çıkışında 2 periyot oluşur. Bundan dolayı OCnA çıkış frekansı OCnB çıkış frekansının yarısı kadar olur. Aşağıdaki formüller de buna göre hesaplanır:
Burada Timer başlangıç değeri = 0’dır. Timer bitiş değeri ise; OCRnA karşılaştırma kayıtçısına yüklenen değerdir.
Yaptığımız Fast_PWM-1 uygulamasında Timer2’yi kullandık ve Timer2’nin maximum değerine ulaştığı modu kullandık. Timer2, 8 bit olduğu için sayaç 0 – 255 arasında sayar ve Timer’ın ve PWM’in frekans değeri buna göre belirlenir.
Klasördeki Timer kayıtçı ayarlarının olduğu resim dosyasına baktığımızda; TCCR2A ve TCCR2B kayıtçılarındaki COM2A1=1, COM2A0=0, COM2B1=1, COM2B0=0, WGM22=0, WGM21=1, WGM20=1 yaparak, OCR2A ve OCR2B karşılaştırma kayıtçılarının OC2A ve OC2B çıkışlarının invert(tersleme) olmayan, Timer2 sayacının maximum değerine kadar saydığı Fast PWM modunu etkinleştirdik. Bu bitlerin değerlerini değiştirerek invert edilmiş PWM de alabiliriz.
Ardından CS22=1, CS21=1, CS20=1 yaparak prescaler(bölme oranı) değerini 1024 yaptık.
Uygulamayı proteus’ta denedik. Proteus’ta Arduino kartı yerine Atmega328p çipini kullanmak zorunda kaldık. Çünkü Arduino OC2A çıkışından PWM verirken OC2B çıkışında PWM sinyali vermedi. Sonuç olarak Atmega328p çipi ile aşağıdaki gibi PWM çıkışı elde edildi.
Yaptığımız Fast_PWM-2 uygulamasında ise yine Timer2’yi kullandık. Bu sefer Timer2’nin OCR2A karşılaştırma değerine ulaştığı modu kullandık. Artık Timer sinyalimizi ve Timer frekansımızı OCR2A karşılaştırma kayıtçısında yüklediğimiz değer belirler. Timer sinyalimizin Duty Cycle değeri %50 olur. Bu nedenle bu karşılaştırma modunda PWM için OCRnB çıkışını kullanabiliriz. OCR2A karşılaştırma kayıtçısını Timer sinyali üretmek için kullanmış olduk.
Klasördeki Timer kayıtçı ayarlarının olduğu resim dosyasına baktığımızda; TCCR2A ve TCCR2B kayıtçılarındaki COM2A1=0, COM2A0=1, COM2B1=1, COM2B0=0, WGM22=1, WGM21=1, WGM20=1 yaparak, Timer2 sayacının OCR2A karşılaştırma kayıtçısı değerine kadar saydığı Fast PWM modunu etkinleştirdik.
Ardından CS22=1, CS21=1, CS20=1 yaparak prescaler(bölme oranı) değerini 1024 yaptık.
Uygulamayı proteus’ta denedik. Proteus’ta Arduino kartı yerine Atmega328p çipini kullanmak zorunda kaldık. Çünkü Arduino OC2A çıkışından PWM verirken OC2B çıkışında PWM sinyali vermedi. Sonuç olarak Atmega328p çipi ile aşağıdaki gibi PWM çıkışı elde edildi.
NOT: Timer’ların ve Timer kayıtçılarının ayarlarıyla, kayıtçılardaki bitlerin fonksiyonlarıyla ilgili bilgiler klasör içerisindeki “Timer0 kayıtçı ayarları.png”, “Timer1 kayıtçı ayarları.png”, “Timer2 kayıtçı ayarları.png” resim dosyalarında yer almaktadır.
Ayrıca Atmega328’in datasheet’inde:
Timer0 ile ilgili ayarlar; 14. Konu, 74. Sayfadan itibaren
Timer1 ile ilgili ayarlar; 15. Konu, 89. Sayfadan itibaren
Timer2 ile ilgili ayarlar; 17. Konu, 116. Sayfadan itibaren yer almaktadır.
Phase Correct PWM Mode
İkinci PWM modu Faz Düzeltmeli PWM olarak adlandırılır. Bu modda daha simetrik bir çıkış alınır. Bu mod çift eğimli bir çalışmaya dayanır. Çıkış frekansı, zamanlayıcı hem yukarı hem aşağı doğru çalıştığı için hızlı PWM modu frekansının yaklaşık yarısı kadar olacaktır. Ancak, çift eğimli PWM modlarının simetrik özelliği nedeniyle, bu modlar motor kontrol uygulamaları için tercih edilir.
Phase Correct PWM’de Sayaç 0’dan başlar. Ayarlanan moda göre sayaç; OCRnA karşılaştırma değerine kadar(OCRnB’de böyle bir özellik yoktur) ya da Timer’ın maximum değerine kadar sayar (sayacın maximum değerinin Timer’ın bit sayısına bağlı olduğunu unutmayın). Sonra bu karşılaştırma değerinden ya da maximum değerden 0’a kadar saymaya devam eder. Bu şekilde Timer sinyali üretilmiş olur. TCNTx kayıtçısında herhangi bir değer yüklenmez. Sayacın OCRnA karşılaştırma değerine kadar saydığı modda PWM için yalnız OCRnB çıkışı kullanılabilir. OCRnA hem en üst değer hem de PWM karşılaştırma değeri olarak kullanılamaz. OCRnA karşılaştırma kayıtçısı çıkışı OCnA’nın PWM frekansı %50 Duty Cycle’dadır. Sayaç 0 değerine her ulaştığında sayaç taşma bayrağı (TOV0) set edilir ve kesmeler aktif edilirse kesme oluşur. Fakat kesme şuan ki konumuz değildir.
b.1- Timer’ın Maximum Değerine Kadar Saydığı Mod
Yukarıdaki grafikte görüldüğü üzere Timer sayacı 0’dayken port çıkışı HIGH olur. Sayaç, karşılaştırma kayıtçısı değerine ulaştığında ise port çıkışı LOW olur. Timer maximum değeri olan 255’e çıkıp sonra 0’a doğru saymaya devam eder. Karşılaştırma kayıtçısı değerine tekrar ulaştığında ise çıkış HIGH olur. Bu işlem sürekli olarak devam eder. Her iki çıkış da aynı frekans değerindedir. Karşılaştırma kaydındaki değer ne kadar yüksekse, Duty Cycle(Görev Döngüsü) de o kadar yüksek olur.
Phase Correct PWM’de, zamanlayıcı hem yukarı hem aşağı gittiği için frekans Fast PWM'e kıyasla ikiye bölünür. Biraz şaşırtıcı bir şekilde, frekans 256 yerine 255'e bölünür ve frekans hesaplamalarında Fast PWM'de olduğu gibi formüle 1 eklenmez.
Burada Timer başlangıç değeri = 0’dır. Timer, 0’dan Timer’ın maximum değerine ve buradan 0’a kadar saydığı için Timer bitiş değeri ifadesi 2 ile çarpılır. Sonuç olarak aşağıdaki formül elde edilir.
b.2 - Timer’ın OCRnA Karşılaştırma Değerine Kadar Saydığı Mod
Karşılaştırma değerine ulaşıldığında çıkışın değiştirildiği(HIGH ise LOW, LOW ise HIGH şeklinde) durumu göz önüne aldığımızda; yukarıdaki grafikte görüldüğü üzere Timer sayacı 0’dayken OCnA ve OCnB çıkışları HIGH durumundadır. OCRnB karşılaştırma değerine ulaşıldığında OCnB çıkışı LOW olur. Sayaç devam eder ve OCRnA karşılaştırma değerine ulaşıldığında OCnA çıkışı LOW olur. Sayaç 0’a doğru devam eder. Tekrar OCRnB karşılaştırma değerine ulaştığında OCnB çıkışı HIGH olur. OCnA çıkışı ise hala LOW durumundadır. Sayaç 0’a gelir ve buradan yukarı doğru tekrar saymaya başlar. Yine OCRnA ve OCRnB karşılaştırma değerlerine geldiğinde çıkışlar terslenir. Sayaç bir kez daha 0’a geldiğinde 1 periyot tamamlanmış olur.
Buradan anlaşılır ki; OCnA çıkışında 1 periyot oluştuğu sürede, OCnB çıkışında 2 periyot oluşur. Bundan dolayı OCnA çıkış frekansı OCnB çıkış frekansının yarısı kadar olur. Aşağıdaki formüller de buna göre hesaplanır:
Burada Timer başlangıç değeri = 0’dır. Timer bitiş değeri ise; OCRnA karşılaştırma kayıtçısına yüklenen değerdir.
Yaptığımız Phase_Correct_PWM-1 uygulamasında Timer0’ı kullandık ve Timer0’ın maximum değerine ulaştığı modu kullandık. Timer0, 8 bit olduğu için sayaç 0 – 255 - 0 arasında sayar ve Timer’ın ve PWM’in frekans değeri buna göre belirlenir.
Klasördeki Timer kayıtçı ayarlarının olduğu resim dosyasına baktığımızda; TCCR0A ve TCCR0B kayıtçılarındaki COM0A1=1, COM0A0=0, COM0B1=1, COM0B0=0, WGM02=0, WGM01=0, WGM00=1 yaparak, OCR0A ve OCR0B karşılaştırma kayıtçılarının OC0A ve OC0B çıkışlarının invert(tersleme) olmayan, Timer0 sayacının maximum değerine kadar saydığı Phase Correct PWM modunu etkinleştirdik. Bu bitlerin değerlerini değiştirerek invert edilmiş PWM de alabiliriz.
Ardından CS02=1, CS01=0, CS00=1 yaparak prescaler(bölme oranı) değerini 1024 yaptık.
Uygulamayı proteus’ta denedik. Proteus’ta Arduino kartı yerine Atmega328p çipini kullanmak zorunda kaldık. Çünkü Arduino OC0A çıkışından PWM verirken OC0B çıkışında PWM sinyali vermedi. Sonuç olarak Atmega328p çipi ile aşağıdaki gibi PWM çıkışı elde edildi.
Yaptığımız Phase_Correct_PWM-2 uygulamasında Timer0’ı kullandık. Bu sefer Timer0’ın OCR0A karşılaştırma değerine ulaştığı modu kullandık. Artık Timer sinyalimizi ve Timer frekansımızı OCR0A karşılaştırma kayıtçısında yüklediğimiz değer belirler. Timer sinyalimizin Duty Cycle değeri %50 olur. Bu nedenle bu karşılaştırma modunda PWM için OCRnB çıkışını kullanabiliriz. OCR0A karşılaştırma kayıtçısını Timer sinyali üretmek için kullanmış olduk.
Klasördeki Timer kayıtçı ayarlarının olduğu resim dosyasına baktığımızda; TCCR0A ve TCCR0B kayıtçılarındaki COM0A1=0, COM0A0=1, COM2B1=1, COM0B0=0, WGM02=1, WGM01=0, WGM00=1 yaparak, Timer0 sayacının OCR0A karşılaştırma kayıtçısı değerine kadar saydığı Phase Correct PWM modunu etkinleştirdik.
Ardından CS02=1, CS01=0, CS00=1 yaparak prescaler(bölme oranı) değerini 1024 yaptık.
Uygulamayı proteus’ta denedik. Proteus’ta Arduino kartı yerine Atmega328p çipini kullanmak zorunda kaldık. Çünkü Arduino OC0A çıkışından PWM verirken OC0B çıkışında PWM sinyali vermedi. Sonuç olarak Atmega328p çipi ile aşağıdaki gibi PWM çıkışı elde edildi.
NOT: Timer’ların ve Timer kayıtçılarının ayarlarıyla, kayıtçılardaki bitlerin fonksiyonlarıyla ilgili bilgiler klasör içerisindeki “Timer0 kayıtçı ayarları.png”, “Timer1 kayıtçı ayarları.png”, “Timer2 kayıtçı ayarları.png” resim dosyalarında yer almaktadır.
Ayrıca Atmega328’in datasheet’inde:
Timer0 ile ilgili ayarlar; 14. Konu, 74. Sayfadan itibaren
Timer1 ile ilgili ayarlar; 15. Konu, 89. Sayfadan itibaren
Timer2 ile ilgili ayarlar; 17. Konu, 116. Sayfadan itibaren yer almaktadır.
0 comments:
Yorum Gönder