PIC Programlama – 9 – Zamanlayıcılar (Timers) 2

Merhabalar, görece uzunca bir aradan sonra yazılarımıza kaldığımız yerden devam ediyoruz. Önceki yazıda tam da bir takım soru işaretleri bırakarak ayrılmıştık. Gün, bunların olabildiğince yanıtlanacağı gündür.

Öncelikle şu 1.06ms meselesinin çözümünü ve cevabını verelim. Evet efendim, kodumuzda yaptığımız tek satırlık bir modifikasyon ile özlenen tabloyu öncelikle kamu huzuruna sunalım.

1.00 ms zamanlayıcı çıktısı

Gördüğünüz üzere tam 1.00 ms’lik çıktıyı yakaladık. Tabi burada tam’dan kasıt, mikrosaniye mertebesindeki ölçüme ithafen bir tamlık. Neyse, şimdi hemen ilk aşamada bu uygulamanın kodlarını paylaşalım.

Kütüphanemiz yine aynı, orada bir değişikliğe ihtiyaç yok. Şimdi burada neyin değiştiğini ve neden değiştiğini açıklayalım. Bir önceki yazıdaki koddan farklı olan tek satır şu:

Bu değerin normal şartlar altında 125 olması gerektiğini açıklamıştık. Ancak gelgelelim kesme fonksiyonu içinde yazdığımız kodlar, ister istemez bir miktar gecikmeye neden oluyor. Bu sebeple bu gecikmeyi tolere edemiyorsak, timer0’a yüklenecek değeri kalibre etmemiz elzem oluyor. Denemeler ile görüyoruz ki kesme fonksiyondaki kodlarımız 7 timer0 cycle kadar bir gecikmeyi doğuruyor. Bunu kompanze etmek için 125 cycle yerine 118 cycle saydığımızda tam 1.o0 ms’lik bir zamanlama elde ediyoruz. Tabi ki bu süreç yalnızca PIC gibi çok kısıtlı kaynaklı ve görece yavaş ortamlarda yaşanıyor. Örneğin ARM Cortex M3-M4 gibi platformlarda bu süreler ihmal edilecek kadar kısalır ve böyle bir istisnai kodlama yapmanız gerekmez. Yine uygulamanız zaman kritik değilse, böyle bir istisnai kodlamaya ihtiyaç duymazsınız. Ama yine de bu önemli konuyu akılda tutmakta fayda var 🙂

Şimdi, önceki yazıdaki defteri kapattığımıza göre bu yazının esas konusuna gelebiliriz. Bu yazımızda zamanlayıcıların bir başka önemli kullanım alanına değineceğiz: PWM (Pulse Width Modulation). Nedir efendim PWM? Çevirisini yapacak olursak dalga genişliği modülasyonudur. PWM’in ne olduğu detaylıca ŞURADA anlatıldığından daha fazla açıklama yapmaya gerek duymuyorum.

Çoğu mikrokontrolörde, zamanlayıcılar üzerinde çalışan PWM modülleri donanımsal olarak bulunur. PIC’in bazı modellerinde de bu imkan sağlanmış. Onların kullanımına da elbet değineceğiz ama daha önemlisi donanımsal PWM modülü olmasa da bu modülasyonu nasıl gerçekleyebileceğimiz. Bu yazıda zamanlayıcı kullanarak PWM gerçekleyeceğiz.

Zamanlayıcılar ve GPIO ile PWM

PWM dediğimiz nane sayısız işe yarıyor. Örneğin bir motorun dönüş hızını, bir LED’in ışık şiddetini ve daha bir çok benzer şeyi PWM ile yapabiliyoruz. PWM, işaretin etkin değerini değiştirmeye yönelik bir modülasyon olduğundan, fiziksel çıktı farketmeksizin “şiddet ayarlama” işini yapar. Ne demek istiyorum?

  • Bir motoru sabit 5V ile beslediğinizde o motor 5 birim hızla dönüyorsa, o motoru sabit 2.5V ile beslediğinizde motor 2.5 birim hızla döner.
  • Bir LED’i sabit 5V ile beslediğinizde o LED 5 birim ışık şiddeti ile yanıyorsa, o LED’i sabit 2.5V ile beslediğinizde LED 2.5 birim ışık şiddeti ile yanar.
  • Bir buzzer’ı sabit 5V ile beslediğinizde o buzzer 5 birim şiddetle ses çıkarıyorsa, o buzzer’ı sabit 2.5V ile beslediğinizde buzzer 2.5 birim şiddetle ses çıkarır.

Yani çıktının fiziksel şekli farketmeksizin, genelde bu iş böyle yürür. Gelgelelim biz dijital dünyada öyle kolay kolay 2.5V veremiyoruz. Bunun yerine işareti zamanda modüle ederek işimizi görmek istiyoruz. Nasıl yani?

Yani elinizde olan yalnızca 5V ise, bundan 2.5V etkin gerilim değeri elde etmenin başka bir yolu var. 1ms süreyle 5V, 1ms süreyle 0V verip bunu sürekli tekrarlarsanız bu işaretin etkin gerilim değeri (5V*1ms +0V*1ms)/2ms = 2.5V olur. 5V lojik 1, 0V lojik 0 olduğundan ve işaret zamanın %50sinde lojik 1 değerini aldığından bu işarete %50 PWM denir.

Benzer şekilde  8ms süreyle 5V, 2ms süreyle 0V verip bunu sürekli tekrarlarsanız bu işaretin etkin gerilim değeri  (5V*8ms + 0V*2ms) /10ms= 4V olur. Hesap açık efendim. Zamanın %80’inde işaret lojik 1 değerini aldığından bu işarete %80 PWM denir. PWM’de işaretin 1 olduğu zamana duty cycle denir. Tekrar eden toplam zaman, periyottur ve burada işaretin periyodu 10ms’dir. Frekans = (1 / Periyot[sn]) olduğundan burada frekans 1/10[ms] = 1/0.01[sn] = 100 Hz olur.   Periyot ve duty cycle kontrol edilerek dalga genişliği modülasyonu (PWM) yapılabilir.

PWM’i anlatmaya gerek yok dedim ama anlatmadan da duramadım. Şimdi lafı bırakıp icraate geçelim. Peki ne yapacağız, PWM’in %1’lik çözünürlükle kontrol edilebildiği bir uygulama yazalım.

Kütüphanemizde bir değişiklik yapmaksızın main.c dosyamızı aşağıdaki gibi yazarsak olay tamam oluyor.

Ve bu şirin mi şirin ama bir o kadar da acımasız kodun çıktısı aşağıdaki gibi oluyor.

%50 PWM

Gördüğünüz üzere periyodu ~100ms olan %50’lik bir PWM işareti elde etmiş olduk. Gelin şimdi %25’lik PWM elde etmek için ne yapmamız gerektiğini görelim.

Yalnızca şu satırı değiştirmek yeterli:

Bu durumda simülasyon çıktısı da aşağıdaki gibi oluyor.

%25 PWM

Her iki çıktıda da periyodun 100ms olduğuna yani frekansın 10Hz olduğuna dikkat ediniz. PWM frekansını örneğin 20HZ yapmak için aşağıdaki değişikliği yapmanız yeterli.

Bu değişiklik ile zamanlayıcının birim zamanını 1ms’den 0.5ms’ye düşürdük. Bu da frekansı iki katına çıkardı.

Bu uygulama ile artık bir motorun hızını kontrol etmek mümkün. Robotçu arkadaşlar varsa bu kısım faydalı olacaktır diye düşünüyorum.

Projenin kaynak kodlarını BURADAN indirebilirsiniz.

Bu günlük de bu kadar. İleride yeni ibretlerle ve yeni yazılarla devam edeceğiz.

Yazıları beğendiyseniz, faydalanabilecek tanıdıklarınızla paylaşmayı unutmayınız.

Önceki Sayfa   Sonraki Sayfa

2 thoughts on “PIC Programlama – 9 – Zamanlayıcılar (Timers) 2

  1. FURKAN

    Hocam vaktinizi ayırıp bu çok özel bilgileri ve tecrübelerinizi bizlerle paylaştığınız için çok teşekkür ederim. Devamını sabırsızlıkla bekliyorum 🙂

Leave a Reply