AVR ile PWM Kullanımı ve 16-Bit PWM Çıkışı Almak

AVR mikrodenetleyicilerin büyük bir kısmında iki adet 8-bit zamanlayıcı ve bir adet 16-bit zamanlayıcı bulunur. Zamanlayıcıların zamanlama işlemi yapması yanında frekans üretme, frekans okuma ve sinyal genişliği okuma gibi işlevleri vardır. Frekans üretme başlığı altında PWM sinyalini de desteklemektedirler. PWM sinyali modu görev döngüsünün genişliğini belirlemede çeşitli parametreleri kullanır. Bu parametreler BOTTOM ve TOP değerler gibi sabit değerlerle beraber giriş yakalama yazmacı ve çıkış karşılaştırma yazmacıdır. BOTTOM değeri dip değer olup sıfırdır. TOP değeri ise zamanlayıcıya göre değişmekle beraber 16-bit zamanlayıcı için 65535 değeridir. Bu alt ve üst değerler görev döngüsü için %0 ve %100 değerlerini temsil etmektedir. Bunların arasına bir değer koyarak %0 ve %100 arasında bir sinyal elde edebiliriz. TOP ve BOTTOM değerleri arasında belirli yazmaçlar bulunup bu yazmaçların değerine göre sinyal bir (1) ya da sıfır (0) konumuna sayaç değerinin zaman içerisinde artmasıyla beraber geçiş yapar. Sayaç değeri ise otomatik olarak artmakta ve bu artış frekansını doğrudan denetleyicinin saat sinyalinden almaktadır. Bu saat sinyali ön derecelendirici ünite ile belli değerlere bölünüp artış yavaşlatılabilir veya doğrudan saat sinyaline bağlanarak en hızlı artış sağlanabilir. PWM frekansı çözünürlüğe bağlı olduğu gibi ön derecelendirici değeri ile işlemcinin saat sinyaline de bağlıdır. Çözünürlük düşük ve saat hızı yüksek olunca yüksek frekanslı sinyal elde ederiz. Sinyalin yüksek veya düşük frekanslı olması görev döngüsüne etki etmemektedir. Görev döngüsü tamamen TOP ve BOTTOM sabitleri ve aradaki değer kaynaklarına (yazmaçlar) göre belirlenir.

Üzerindeki AVR mikrodenetleyici desteklemesine rağmen Arduino’da 16-bit PWM için herhangi bir fonksiyon yer almamaktadır. Bu desteği sağlama zahmetine de girmiş değiller. Her zamanlayıcı çıkış ayağından 8-bit PWM alabilsek de AVR’deki 16-bit zamanlayıcı ve 16-bit PWM desteği göz ardı edilmemelidir. Çünkü 8-bit PWM sinyali bazı durumlarda çözünürlük bakımından yetersiz kalabilmektedir. Örneğin bir ledi karartma uygulaması yaptığımızda görev döngüsü adımları oldukça büyük olduğu için yumuşak bir geçiş olamamaktadır. Bu gözle fark edilir bir seviyededir. Üzerindeki AVR mikrodenetleyicinin bunu desteklemesine rağmen neden Arduino’nun 16-bit PWM için bir fonksiyon getirmediğini anlamış değiliz.

Sadece TC1 zamanlayıcısına mahsus olmak üzere 16-bit PWM sinyali üretebileceğimiz gibi kendi çözünürlüğümüzü ayarlayarak 10-bit, 9-bit, 8-bit gibi bir çözünürlükte PWM sinyali elde edebiliriz. Üstelik frekansın yetersiz kaldığı durumlarda hızlı PWM seçeneği ile iki kat daha yüksek frekanslı PWM sinyali elde etmemiz mümkündür. Bütün bu ayarlamaları ve değerleri zamanlayıcı yazmaçlarına değer atayarak yaparız. Zamanlayıcılar PWM sinyalini işlemciden ve programdan bağımsız olarak üretip Arduino’nun PWM ayaklarına denk gelen zamanlayıcı çıkış ayaklarından sinyal olarak çıkış verir.

Şimdi bu yazmaçları kullanan bir örnek programı çalıştıralım ve teknik veri kitapçığı üzerinden anlatalım.

 

Program TCCR1A ve TCCR1B yazmaçlarına değer atayarak başlamaktadır. Bu değer atama işlemi bir kere olduğu için bunların ayar yazmacı olduğunu anlayabilirsiniz. Zamanlayıcı ve sayıcı denetim yazmaçları TC1 zamanlayıcısı için TCCR1A ve TCCR1B olmak üzere iki adettir. Bu yazmaçlardaki bitleri teknik veri sayfasındaki tablodan yararlanarak ayarlarız. AVR derslerimizde 10 kadar derste zamanlayıcıları anlattığımız için orada ayrıntılı bir şekilde görebilirsiniz. Bu programda bunlardan önce OC1A ayağına denk gelen PB1 bitini DDRB yazmacına bir şeklinde yazıyoruz. Bu bit bir yapılınca çıkış olmuş oluyor. Burası dikkat etmemiz gereken noktalardan biridir. Eğer kullanacağımız ayağı önceden çıkış olarak ayarlamazsak bir sinyal alamayız.

TCCR1A yazmacında COM1A1 bitini bir (1) yaptığımız görülüyor. Hemen teknik veri sayfasından bu bitin ne anlama geldiğini öğrenelim.

Burada COM1A1 bitini bir yaptıktan sonra COM1A0 bitine dokunmadık. Haliyle sıfır olduğundan 10 değerine denk gelen hücreye bakacağız. Burada OC1A ayağının yukarı sayımda eşleşme sağlandığında sıfır yapıldığı ve aşağı sayımda eşleşme sağlandığında bir yapıldığını görüyoruz. Kullanacağımız PWM modu eğer hızlı PWM modu olsaydı örneğin yukarı doğru sayım yapacak sonra sıfırlayıp tekrar yukarı doğru sayacaktı. Burada ise faz düzeltmeli olduğu için önce yukarı doğru sayıp üst sınır (TOP) değere varmakta sonra ise bu değerden aşağı doğru saymaya başlamakta ve alt sınır değere (BOTTOM) varmaktadır. Faz düzeltmeli PWM’yi sadece yazarak anlatamayacağımız için sizin için anlaşılır bir grafik göstermek istiyorum.

Resim: https://www.electronicwings.com/images/user_images/images/ATmega_20160622/ATmega_PWM/7_Non-Inverted%20Phase%20correct%20PWM.PNG

Burada göreceğiniz üzere OCR yazmacına yazdığımız değer eşik değeri oluyor ve bu değerden yukarıda yaptığımız ayara göre sıfır (0) ya da bir (1) sinyali alıyoruz. Terslenmemiş şekliyle bu eşik değerinden yukarıda sıfır sinyali alınmaktadır. Bu değer yükseldikçe sıfır zamanı düşmekte ve görev döngüsü artmaktadır. Eğer eşik değeri üst sınır değerine ulaşırsa bir  (1) sinyalini düz bir şekilde alırız. Eğer eşik değerini dip değere sabitlersek bu sefer de sıfır değerini alırız ve bu durumda görev döngüsü %0 olur. Kısacası bizim program boyunca ayarlayacağımız tek bir değer vardır o da eşik değeridir. Bu eşik değeri ise OCR yazmacının değeri olup TC1 zamanlayıcısı için 16 bittir.

Buraya kadar faz düzeltmeli PWM sinyalini ve OCR yazmacının önemini anlamış olduk. Şimdi ise diğer ayar bitlerinin ne işe yaradığına bir bakalım. TCCR1B yazmacında WGM13 bitini bir (1) yaptığımızı görüyoruz. WGM bitleri toplamda dört bit olup WGM10, WGM11, WGM12 ve WGM13 olarak adlandırılır. WGM13 biti TCCR1B yazmacında yer alır ve geri kalan bitler de TCCR1A yazmacında yer almaktadır. Bu dört biti ayarlayarak çeşitli dalga üretim ve çalışma modlarını kullanabiliriz. Bu modların ne olduğu ise yine teknik veri kitapçığında yer almaktadır.

Biz WGM13 bitini bir yaptığımız için geri kalan bitler sıfır olacak. Bu durumda 8 numaralı modu kullanacağız. 8 numaralı modun açıklamasında faz  ve frekans düzeltmeli PWM çıkışı olduğunu görüyoruz. TOP değeri ise ICR1 yazmacına yazacağımız değer oluyor. Bu TOP değeri PWM’nin kaç bit olacağını belirlediği gibi frekansını da belirlemektedir. Düşük olunca çözünürlük azalmakta ve frekans artmaktadır. Tabloda göreceğiniz üzere 8-bit PWM’nin TOP değerinin 0x00FF değerine yani 256 değerine sabitlendiğini görmekteyiz. Çözünürlük düşünce sayılacak değer de azalmaktadir. Örneğin 16-bit PWM kullandığımızda sayaç 65535 kere sayması gerekirken 8-bit PWM kullanınca bu sayı 256’ya düşer. Buradan işlemcinin saat hızıyla bölerek frekans hesaplamak da mümkündür. Frekans hesaplama formüllerini AVR derslerinde anlattığım için burada tekrarlamayacağım.

Buraya kadar çıkış ayağını ve modunu ve dalga üreteci modunu seçmiş olduk. Geriye ise bir ayar daha kaldı. Zamanlayıcının saat ayarını yapmadıkça zamanlayıcımız çalışmayacaktır. Zamanlayıcının çalışması için bütün bu ayarların yanında ön derecelendirici ayarına da ihtiyaç vardır. Bu aynı zamanda zamanlayıcıya giden saat sinyalini etkinleştirmektedir. Biz programımızda CS10 bitini bir (1) yapmaktayız. İlgili tabloya bakarak ne anlama geldiğini öğrenelim.

Burada sadece ön derecelendirici ayarını değil saat ayarlarını da görmekteyiz. Örneğin giriş yakalama modunda giriş yakalama ayağına kendi sinyalimizi vererek zamanlayıcıyı sayaç modunda çalıştırabiliriz. Aşağıdaki iki satırda harici saat kaynağı ayarının olduğunu görmekteyiz. Örneğin bir düğmeye kaç kere basıldığı, kaç saniye basılı tutulduğu veya frekans okuma gibi uygulamalarda bu ayarı yapmamız gerekir. CS bitlerinin “000” olması durumunda ise zamanlayıcıya giden saat sinyali kesilir ve zamanlayıcı tamamen durur. Güç tasarrufu seçeneği için uygulama esnasında da kullanabiliriz. Ön derecelendirici ise işlemciden gelen saat sinyalini bölerek zamanlayıcıya saat sinyali olarak verir. PWM sinyalini yüksek frekanslı istediğimiz için sadece CS10 ayağını bir yaparak zamanlayıcıyı doğrudan işlemci saatinden sinyal alır hale getirdik.

Program döngüsü içerisinde ise OCR yazmacının değerini birer birer artırarak PWM sinyalinin görev döngüsünü zaman içerisinde değiştirdik ve fark edilebilir hale getirdik. Programın çalışma görüntüsü aşağıdaki gibidir. Arduino kullananlar Arduino’nun dijital 9 numaralı ayağına bir led bağlayarak çıkışı görebilir. Videoda led parlaklığı pürüzsüzce artsa da ledin yapısından dolayı göze doğrusal bir parlaklık gelmemektedir. Osiloskoptan sinyali incelediğimizde sinyalin düzgün ve olması gerektiği gibi olduğunu görebiliriz.

Bizi Facebook grubumuzda takip etmeyi unutmayın. Bilgili ve öğrenmeye hevesli bir topluluk oluşturmak istiyoruz.

https://www.facebook.com/groups/1233336523490761/

UYARI!!

 

Gökhan Dökmetaş

"Arduino Eğitim Kitabı" ve "Arduino ve Raspberry PI ile Nesnelerin İnterneti" kitaplarının yazarı. Başkent Teknoloji ve Dedektör Merkezi'nde Ar-ge Sorumlusu. Araştırmacı-Yazar.

You may also like...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.