PWM SİNYALİ ÜRETİMİ

Başlatan PICaso, 12 Şubat 2019, 10:18:28

PICaso

Arkadaşlar Merhaba,

Pic 18f4520 kullanarak 1Hz - 300kHz aralığında buton ile kontrol edebileceğim sabit %50 duty pwm sinyali üretmek istiyorum. Osilatör frekansım 20Mhz. CCS C de yazdığım programa göre buton ile artış azalış yaptığımda duty de değişmektedir. Bu istediğim frekans aralığını Pic ile yapmak mümkün müdür?

Herkese iyi çalışmalar.

#include <18f4520.h>     // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.

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

#use delay (clock=20000000) // 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=125; // Tamsayı tipinde değişken tanımlanıyor

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

void main ( )
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_spi(SPI_SS_DISABLED);     // SPI 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);   // C portu komple çıkış

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

   setup_timer_2(T2_DIV_BY_1,i,1); // Timer2 ayarları yapılıyor

   set_pwm1_duty(50); // PWM1 çı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++; // i=i+1 anlamındadır.

         if (i>254) // i değeri 250'dan büyükse i değeri 250 olsun
            i=254;
         setup_timer_2(T2_DIV_BY_1,i,1); // Timer2 ayarları yapılıyor
          set_pwm1_duty(50); // PWM1 çı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--;  // i=i-1 anlamındadır.

         if (i<2) // i değeri 65'den küçük ise i değeri 65 olsun
            i=2;
         setup_timer_2(T2_DIV_BY_1,i,1); // Timer2 ayarları yapılıyor
          set_pwm1_duty(50); // PWM1 çıkışı görev saykılı belirleniyor
      }
   }
}

izturk

set_pwm1_duty(50); deki 50 %50 değil.

onu set_pwm_duty((unsigned int)(i/2)); yapmalısın yani timerin sayacağı değer değiştiğinde duty değeri de değişmeli.

tam %50 istiyorsan i değeri çift sayı olmalı. i yi 2 şer artırıp azaltabilirsin.

PICaso

#include <18f4520.h>     // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.

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

#use delay (clock=20000000) // 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

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

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

void main ( )
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_spi(SPI_SS_DISABLED);     // SPI 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);   // C portu komple çıkış

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

   setup_timer_2(T2_DIV_BY_1,i,1); // Timer2 ayarları yapılıyor

 set_pwm1_duty((unsigned int)(i/2)); // PWM1 çı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=i+2; // i=i+2 anlamındadır.

         if (i>255) // i değeri 250'dan büyükse i değeri 250 olsun
            i=255;
         setup_timer_2(T2_DIV_BY_1,i,1); // Timer2 ayarları yapılıyor
    
      }

      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=i-2;  // i=i-2 anlamındadır.

         if (i<15) // i değeri 65'den küçük ise i değeri 65 olsun
            i=15;
         setup_timer_2(T2_DIV_BY_1,i,1); // Timer2 ayarları yapılıyor

      }
   }
}

değişiklikleri yaptım fakat i değeri 120 den başlatıp azalttığımda i=60 değerinde duty %100 oluyor. Aynı şekilde 120 de %50 olan duty değeri i değeri 255e doğru yaklaşınca duty %0 yaklaşmaktadır.

PICaso


RaMu

CcsC ide nin help kısmına PWM yazıp,
çıkan başlıklardan "pwm_set_duty_percent" a bak.

#USE PWM(OUTPUT=PIN_C2, FREQUENCY=10kHz, DUTY=25)

pwm_set_duty_percent(500);   //set PWM duty cycle to 50%

Bu komut ile:
0    verirsen %0,
1000 verirsen %100 duty olur.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

mehmet

Burada anlamadığım; pwm frekansı
mı ayarlanacak, yoksa belli bir
frekansda dalga oranı mı?
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr
https://creativecommons.org/licenses/by/4.0/deed.tr "CC BY"

RaMu

Olur mu kısmına bakmamıştım, onuda yazayım:
Alıntı YapEQUATION 15-1:
PWM Period = [(PR2) + 1] • 4 • TOSC •(TMR2 Prescale Value)
Tosc = 1 / [Kristal Frekansı]

20MHz kristal ile minimum 1.2kHz PWM üretebilirsin,
32768Hz lik saat kristali kullansan bile
minimum ancak 2Hz PWM frekansına düşebilirsin.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

PICaso

Alıntı yapılan: mehmet - 14 Şubat 2019, 23:58:23Burada anlamadığım; pwm frekansı
mı ayarlanacak, yoksa belli bir
frekansda dalga oranı mı?
Hocam şu şekilde Pwm duty sabit %50 olacak ben butonlarla frekansı azaltıp ya da artıracağım. Yukarıda da belirttiğim şekilde frekans değişiyor fakat duty de değişiyor, sabit kalmıyor.

mehmet

Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr
https://creativecommons.org/licenses/by/4.0/deed.tr "CC BY"

PICaso

Alıntı yapılan: RaMu - 15 Şubat 2019, 00:57:17Olur mu kısmına bakmamıştım, onuda yazayım:Tosc = 1 / [Kristal Frekansı]

20MHz kristal ile minimum 1.2kHz PWM üretebilirsin,
32768Hz lik saat kristali kullansan bile
minimum ancak 2Hz PWM frekansına düşebilirsin.

Tpwm= 1/Fkomut X (PR2 + 1) X (TMR2 BÖLME ORANI)    Fpwm=1/Tpwm

PR2: 15 ile 255 arasında değerler alıyor.
TMR2: 1
Bu hesaba göre
Minimum frekansım: 19531 Hz
Maksimum frekansım: 312500 Hz
Bu değerleri dahi göremedim.

PICaso

Alıntı yapılan: mehmet - 15 Şubat 2019, 10:12:08http://eng-serve.com/pic/pwm_functions.html

Hocam siteyi inceledim. CCS C  kullandığım için registerları örnekteki gibi kullanmama izin vermiyor derleyiciç