PWM & PIC 16F877

Başlatan temelal, 29 Nisan 2011, 15:23:36

temelal

iyi günler
ben evx-2 esc yi pic 16f877a ile sürmek istiyorum.
şimdi sorun şu.
bendeki örnek pic projelerde 4 mega hz lik kristaller kullanılmış.
bana 50 hz lik pwm için ne yapabileceğim yapabileceğim konusunda yardımcı olabilir misiniz... 50 hz lik kristal mi takayım???
birde bu aşağıda donanımsal pwm yapılıyor sanırım.
bunu yaparken pic ile başka işlemler yapsam yavaşlama olur mu?
kodlar:
kitaptaki örnek kodu deniyorum zaten.
/******************************************************
      PIC16F877 ile PWM Modu Uygulaması-1
*******************************************************/
#include <16f877.h>     // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.

// Denetleyici konfigürasyon ayarları
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD

#use delay (clock=4000000) // Gecikme fonksiyonu için kullanılacak osilatör frekansı belirtiliyor.

#use fast_io(a) //Port yönlendirme komutları A portu için geçerli
#use fast_io(c) //Port yönlendirme komutları C portu için geçerli

int i=5; // Tamsayı tipinde değişken tanımlanıyor

/********* ANA PROGRAM FONKSİYONU********/

void main ( )
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı

   set_tris_a(0x03);   // RA0 ve RA1 pinleri giriş
   set_tris_c(0x00);   // RC0, RC1 ve RC2 pini giriş

   setup_ccp1(CCP_PWM);  // CCP1 birimi PWM çıkışı için ayarlandı
   setup_ccp2(CCP_PWM);  // CCP2 birimi PWM çıkışı için ayarlandı

   setup_timer_2(T2_DIV_BY_16,170,1); // Timer2 ayarları yapılıyor

   set_pwm1_duty(i); // PWM1 çıkışı görev saykılı belirleniyor
   set_pwm2_duty(i); // PWM2 çıkışı görev saykılı belirleniyor

   while(1) // Sonsuz döngü
   {
      if (input(pin_a0)) // Eğer RA0 girişine bağlı butona basılırsa
      {
         delay_ms(20);   // Buton arkı önleme gecikmesi
         while(input(pin_a0)); // Basılı butondan el çekile kadar bekle
         i+=3; // i=i+3 anlamındadır.

         if (i>=170) // i değeri 170'dan büyükse i değeri 170 olsun
            i=170;

         set_pwm1_duty(i); // PWM1 çıkışı görev saykılı belirleniyor
         set_pwm2_duty(i); // PWM2 çıkışı görev saykılı belirleniyor
      }

      if (input(pin_a1)) // Eğer RA1 girişine bağlı butona basılırsa
      {
         delay_ms(20);  // Buton arkı önleme gecikmesi
         while(input(pin_a1)); // Basılı butondan el çekile kadar bekle
         i-=3;  // i=i-3 anlamındadır.

         if (i<5) // i değeri 5'den küçük ise i değeri 10 olsun
            i=5;

         set_pwm1_duty(i); // PWM1 çıkışı görev saykılı belirleniyor
         set_pwm2_duty(i); // PWM2 çıkışı görev saykılı belirleniyor
      }
   }
}

Tagli

Bu iş için donanımsal PWM modülünü kullanamazsın. Sebebini biliyorsun zaten: PIC o kadar yavaş çalışamıyor. Evet, düşük frekanslı bir kristal PWM modülünü kullanmana olanak verebilir, ama PIC'i yavaş çalıştırırsan da daha büyük sorunlarla karşılaşabilirsin.

Sorunun çözümü için sayaçları senin uygun şekilde ayarlayıp programı yazman gerekli. Ancak bu şekilde PWM üreten kodun ana programa ayak bağı olmasını engelleyebilirsin. Yakın bir tarihte bu konuyla ilgili bir soru benim de kafama takılmış ve sormuştum. İlgili başlığa buradan ulaşabilirsin. İncelemeni tavsiye ederim.

Diğer soruna gelince; hayır, donanımsal PWM modülü kod işleyişinden bağımsız çalıştığından ana programı yavaşlatmaz. Zaten bu sebeple tercih ediliyor. Ancak yukarıda da anlattığım üzere, malesef ESC ve RC Servo kontrolü için bunu kullanamıyoruz. En azından 16F877 için durum böyle.
Gökçe Tağlıoğlu