top of page

PWM #3 - Kodlama Sürecine Geçiş

Güncelleme tarihi: 15 May 2023

Merhaba! Önceki bölümlerde, teknik dokümanları detaylıca inceledik ve kendi algoritmamızı oluşturduk. Şimdi ise kodlama sürecine geçiyoruz. Bu işlem için M031TB geliştirme kitini ve Keil uvision IDE'sini kullanacağız.

Kodlamaya başlamadan önce PWM sinyalinden beklentimizi netleştirmemiz gerekiyor. Yani, bizim için asıl önemli olan PWM sinyalinin frekansı mı, yoksa çözünürlüğü mü? Genellikle, PWM sinyalleri bu iki parametre üzerinden değerlendirilir. Bizim örneğimizde, PWM frekansı çok kritik bir öneme sahip değil; ancak frekansı belirli bir aralıkta değiştirebiliriz. 16-bit çözünürlüğe sahip PWM sinyalini, örneğimizde 0-1000 arasında bir değer alacak şekilde ayarlayacağız.


Şimdi, bu gereksinimlerimize göre PWM biriminde yapmamız gereken ayarlamaları belirleyelim:

  • PWM0_CLK0 değeri HXT'den 32MHz olarak gelir.

  • İstediğimiz çözünürlüğü yakalamak için CNT değerini 999 (saymaya 0 da dahil olduğu için) olarak ayarlıyoruz.

  • PWM sinyalinin frekansı (PWM0_CLK0) / ((Prescaler+1) * (CNT+1)) formülü ile hesaplanır.

  • CNT değeri 999 olduğu için PWM frekansı 32kHz'e düşer. 1kHz PWM frekansı için Prescaler değeri 31 olmalıdır.

  • Comparator değeri döngü içerisinde değiştirilir. Biz başlangıç ayarlarında Comparator değerini 0 olarak ayarlarız.

  • Pulse Generator ayarlarında Zero Point HIGH, CMPU değerini LOW ve Period Point değerini NOTHING olarak ayarlarız.

  • Enable birimini aktif edip, Counter birimini saydırmaya başlayınca PWM biriminin başlangıç ayarları tamamlanmış olur.

  • Döngü içerisinde CMP değerinin değişimiyle Duty Cycle değişir.

İlk olarak clock ayarları yapılır. Bu bölümde PWM konusuna odaklandığımız için clock ayarlarını başka bir yazıda inceleriz.

CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);
CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);

CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));
CLK->PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV1 | CLK_PCLKDIV_APB1DIV_DIV1);

CLK_EnableModuleClock(PWM0_MODULE);
CLK_SetModuleClock(PWM0_MODULE, CLK_CLKSEL2_PWM0SEL_PCLK0, MODULE_NoMsk);

SystemCoreClockUpdate();

Daha sonra pin ayarlarını yapıyoruz.

SYS->GPA_MFPL = SYS_GPA_MFPL_PA1MFP_PWM0_CH0;

Başlangıç ayarlamalarını yapıyoruz.

PWM_SetClockSource(PWM0, 2, PWM_CLKSRC_PWM_CLK); // PWM0_CLK0 kaynağı seçilir
PWM_SET_PRESCALER(PWM0, 2, 0x1F); // Prescaler değeri 31 olarak ayarlanır
PWM_SET_CNR(PWM0, 2, 0x3E7); // Counter değeri 999 olarak ayarlanır
PWM0->CTL1 &= ~(0x3ul << 4 ); // Counter birimi Up Counter moduna ayarlanır
PWM_SET_CMR(PWM0, 2, 0x00); // Başlangıçta %0 Duty Cycle için ayarlanır
PWM_SET_OUTPUT_LEVEL(PWM0, PWM_CH_2_MASK, PWM_OUTPUT_NOTHING,         
                           PWM_OUTPUT_LOW, PWM_OUTPUT_HIGH, 
                           PWM_OUTPUT_NOTHING); // Pulse Generator birimi ayarlanır
PWM_EnableOutput(PWM0, PWM_CH_2_MASK); // Output Control birimindeki anahtar aktifleştirilir
PWM_Start(PWM0, PWM_CH_2_MASK); // Counter birimi aktifleştirilir

Ve nihayet, istediğimiz noktada Duty Cycle değerini değiştirebilmek için CMR değerini değiştiririz. 0 ila 1000 arasında bir değer vererek istediğimiz Duty Cycle değerini elde edebiliriz.

PWM_SET_CMR(PWM0, 2, 0x1F4); // %50 Duty Cycle

Sonraki yazımızda, bu kodları test etmeyi ve sonuçlarını analiz etmeyi planlıyoruz. Umarım bu yazı sizin için faydalı olmuştur, herhangi bir sorunuz olursa sormaktan çekinmeyin!

 
 
 

Comentarios


bottom of page