Timer ve PWM’e Genel Bakış, STM32F4’de Timer ile PWM Çıkış Sinyali Oluşturma

ST’nin yayınladığı örneklerde Timer konusu üzerinde çok durulmamış. Birkaç örnek verilmiş fakat bu örnekler tam olarak açıklanmamış ve bazı kısımlarda görmezden gelinmiş. Bu sebeple Timer kodu yazdığım ilk zamanlarda sürekli hatalarla karşılaştım. Teoride çalışması gereken kod pratikte yanlış çalıştı. Örneğin 50 Hz’lik bir PWM sinyali üretmeye çalışırken 200 Hz’lik PWM sinyali üretmiş oluyordum. Uzun araştırmalar sonunda bunun clock ayarlarıyla alakalı olduğunun farkına vardım.

Bu yazıda genel olarak:

  • STM32F4’te Timer ve özelliklerinden,
  • Clock ayarlarının nasıl yapıldığı ve niçin önemli olduğundan,
  • Prescaler ve Period kavramlarından,
  • PWM sinyali ve özelliklerinden,
  • Keil’de PWM çıkış sinyalinin nasıl oluşturulduğundan bahsedeceğim.

Timer ile başlayalım.

Timer farklı amaçlar için kullanılabilir:

  • Timebase olarak: Periodik olarak bir kod blokunu gerçekleştiren bir sayaç gibi,
  • Bir PIN’in hangi sıklıkla HIGH ya da LOW olduğunu takip eden sayaç olarak,
  • Pulse-width modulation (çıkış ya da giriş) olarak…

STM32F4’te kullanabileceğimiz çeşitli özelliklerde 14 adet Timer bulunmakta. Bunların özelliklerini aşağıdaki tabloda görebilirsiniz.

timers

En basit olarak Timer’dan bahsetmek gerekirse, bir sayaç düşünün bu sayaç 0’dan başlar ve belirli bir sayıya kadar sayar. Bu sayıya ulaştığı zaman bir update event oluşturur. Sonra sayaç otomatik olarak tekrar sıfırlanır ve tekrar saymaya başlar bu döngü sonsuza kadar devam eder. Timer’ın gerçek zamanla senkron halde çalışabilmesi için gerekli clock ayarlarının yapılması çok önemlidir. Çünkü yapacağımız Period ve Prescaler ayarlamalarını bu clock ayarlarına göre yapacağız.

Örneğin Timer3 kullanalım. Tabloda da görebileceğiniz gibi Timer3 için maksimum timer clock’u 84 Mhz. Eğer clock ayarları yanlışsa 84 Mhz’den daha düşük bir clock’a ayarlanmış olma ihtimali var. Eğer 84 Mhz’den farklıysa ve biz hesaplamalarımızı 84 Mhz’e göre yaptıysak, işte bu durumda teori pratikle örtüşmez. Bu sebeple bir önceki yazımda bu konuya elimden geldiğim kadar değinmeye çalıştım.

STM32F4 mikroişlemcisi için gereken clock ayarlarını yaptıktan sonra artık Timer işlemlerini sorunsuz bir şekilde yapabiliriz. Clock ayarlarının nasıl yapıldığını bilmiyorsanız, bir önceki yazımda bu konu hakkında bilgi edinebilirsiniz.

“system_stm32f4xx.c” Dosyasında Clock Ayarlarının Yapılması

Prescaler ve Period Kavramları

Örnek olarak Timer3 kullanacağım. Timer3 Clock’unu 84 MHz’e ayarladık. 50 Hz’lik bir Timer oluşturalım. Yani her 20 ms’de bir kendini tekrarlayan bir Timer oluşturalım. Bunun için bir formül ürettim.

freq formula

Needed Frequency (ihtiyaç duyulan frekans) = 50 Hz. (Bu değeri biz belirliyoruz. İstediğimiz değeri yazabiliriz.)

TIMER CLOCK = 84 MHz (Timer3 için ayarlanmış clock değeri 84 MHz’den farklıysa formülde o değeri yazın. Eğer Timer3’den farklı bir Timer kullanırsanız, o Timer için ayarlanmış Clock değerini yazın.)

Prescaler = 84 – 1 ( Ön bölücü anlamına gelir. 84 ile orantılı olması için 83 değerini uygun buldum. 84 MHz’i 84’e bölersek 1 MHz kalır. 84 değerini kullanarak Period değerinin küsuratlı bir değer almasını engellemiş oluruz.)

Period = 20000 – 1 (Yukarıdaki değerleri formülde yerine koyduğumuzda Period değerini bulmuş oluruz. Prescaler sonrası kalan 1MHz’i Period değerine bölersek ihtiyaç duyduğumuz frekans değerine ulaşmış oluruz. Bu Period değerini, T = 1/F formülündeki periyot ile karıştırmayın.)

Not: Prescaler değerini Clock’a bölündüğünde 1 MHz kalacak şekilde ayarlarsanız, ihtiyaç duyduğumuz frekans ve Period değeri mikro saniye (us) cinsinden T=1/F formülünü sağlar. Örneğin, 50 Hz için Period değeri 20000 çıktı.  T=1/F = 1/50 = 0.02 saniye = 20 mili saniye = 20000 mikro saniye. Bu sebeple Prescaler seçimi çok önemlidir. Yazacağımız kodlarda hassasiyet için Period değerinin sonunda 0’ların bolca olaması çok önemli. Gittikçe 10’a, 100’e, 1000’e tam bölünmesi, yüzdelik ve bindelik işlemlerde hesaplamalarımızı kolaylaştırır ve hata payımızı azaltır.

Ayrıca dikkat edilmesi gereken bir konu da Prescaler 16 bit’ten, Period da 32 bit’ten büyük olamaz. Maksimum Prescaler değeri 65536 – 1, maksimum Period değeri de Timer Clock değerinden büyük olamaz. Eğer Prescaler 0 ise Period 84000000 olur. Bu durum da en büyük çözünürlük elde edilmiş olur.

Pulse-Width Modulation (PWM)

PWM, pulse’ın (sinyalin)  genişliğini başka bir deyişle sinyalin sürecini kontrol eden bir modülasyon tekniğidir. Kare dalgayla benzerlikler taşır.

Duty Cycle, sinyalin ON (açık, pozitif) olduğu zamanın sinyalin periyot zamanına oranıdır. Düşük duty cycle düşük güçle ilişkilendirilir çünkü güç periyotun büyük kısmında OFF (kapalı)’dır. Duty cycle yüzde olarak gösterilir. Aşağıdaki grafikte farklı oranlar gösterilmiştir.

pwm

KEIL’de PWM Kodu Tasarımı

Timer kullanılarak bir çok uygulama yapılabiliyor. Bunlardan biri de PWM(pulse width modulation) sinyali üretebiliniyor. Bunun için gerekli ayarlamaların nasıl yapılacağından bahsedeceğim.

STM32F4-Discovery Board’u Keil uVision MDK-ARM ile Kodlama yazımda Template Project olarak oluşturduğumuz LEDToggle klasörü kopyalayıp aynı klasöre yapıştıralım. LEDToggle – Kopya adında oluşan klasörün ismini TimerPWMOutput olarak değiştirelim. TimerPWMOutput > Project > Project.uvproj tıklayarak Keil projemizi açalım. Soldaki Project sekmesinden LEDToggle’ı TimerPWMOutput olarak değiştirelim.

Yine Project sekmesindeki StdPerip_Driver klasörüne sağ tıklayıp Add Existing Files to ‘StdPerip_Driver’… tıklayıp stm32f4xx_tim.c dosyasını ekleyelim. StdPeriph_Driver sekmesinin altında stm32f4xx_rcc.c , misc.c , stm32f4xx_gpio.c , stm32f4xx_syscfg.c , stm32f4xx_exti.c , stm32f4xx_tim.c dosyalarının bulunması gerekiyor. Bu dosyalar ekli olmazsa hata alırsınız. Project kısmı aşağıdaki gibi olmaşıdır.

project

stm32f4xx_tim.c dosyasını kullanmamızın sebebi bu dosya içinde Timer ile ilgili fonksiyonların bulunması ve bunları yazdığımız kodda kullanacak olmamızdır.

Yukarıda paylaştığım kod ile C PORT’unun 6, 7 ,8 ve 9. PIN’leri 50 Hz PWM sinyali çıkış olarak vermektedir.  Bunlar sırasıyla Timer3’ün 1, 2, 3 ve 4. kanallarına atanmıştır. Timer’lar ile yukarıda paylaştığım tabloda her Timer’ın sahip olduğu kanal sayısı gösterilmektedir. Timer3’ün 4 kanalı var. Yazdığım kodda 4 kanalı da kullandım.

Önemli olan bir başka konu da, kafamıza göre istediğimiz PIN’e Timer kanal bağlantısı yapamıyoruz. Her Timer ST’nin belirlediği PIN’lere bağlanabiliyor. Bu PIN’lere ve tüm detaylı bilgilere RM0090 Reference Manuel‘den ulaşabilirsiniz.

Ürettiğimiz bu PWM sinyallerinin Pulse genişliklerini değiştirmek için stm32f4xx_tim.c’de bulunan fonksiyonu kullanabilirsiniz.

Atadığınız Pulse değeri belirlediğiniz  Period değerinden büyük olmamalıdır. Çünkü Duty Cycle %100’den büyük olamaz.

% Duty Cycle = (Pulse Width / Period)  * 100

formülünden de anlaşılabileceği gibi Period değeri Pulse değerinden her zaman büyük olmalıdır.

Anlaşılmayan kısımları yorum kısmından sorabilirsiniz. Herkese iyi çalışmalar dilerim.

One thought on “Timer ve PWM’e Genel Bakış, STM32F4’de Timer ile PWM Çıkış Sinyali Oluşturma

Leave a Comment

%d bloggers like this: