5 farklı frekansta Kare Dalga PWM

Başlatan oongit, 20 Kasım 2010, 22:14:43

justice_for_all

yazılımında bikac hata var donanımına gore if(!input(pin)) gibi kullanman gerek...her ifde setup_ccp demen gerek yok main fonksionunda bikez demen yeterli ayrıca frekanslanların max dutysini bul demiştim bulabildinmi...
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

oongit

Alıntı yapılan: justice_for_all - 26 Kasım 2010, 20:34:17
ayrıca frekanslanların max dutysini bul demiştim bulabildinmi...

Aklımdan çıkmış, üzgünüm... Şöyle olacak:
Hangi frekans seçilirse seçilsin, Duty değeri %10 ile başlayıp, %90'da son bulacak... Yani; ne %10'un altına inecek, ne de %90'ın üzerine çıkacak... Sanırım bu iş için de, her frekans için ayrı ayrı Duty değiştirme programı yazmak zorunda kalabilirim belki... Tabii başka mantıklı bir yolu yoksa...

justice_for_all

mantıklı bir yolu var senden istediğim tek sey frekansların %90 nında duty degeri kac olması gerek...
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

oongit

100 Hz PWM ve %90 Duty için:
setup_timer_2(T2_DIV_BY_16, 155, 1);
set_pwm1_duty(562);

150 Hz PWM ve %90 Duty için:
setup_timer_2(T2_DIV_BY_16, 103, 1);
set_pwm1_duty(375);

200 Hz PWM ve %90 Duty için:
setup_timer_2(T2_DIV_BY_16, 77, 1);
set_pwm1_duty(281);

250 Hz PWM ve %90 Duty için:
setup_timer_2(T2_DIV_BY_16, 61, 1);
set_pwm1_duty(225);

300 Hz PWM ve %90 Duty için:
setup_timer_2(T2_DIV_BY_16, 51, 1);
set_pwm1_duty(187);

justice_for_all

ok ben yapar linkini gonderirim simdi cıkmam gerek...
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

oongit


oongit

#66
int8 i=0,sayac=0;

#int_rb                    //PORTB'de B4-B7 pinlerinde oluşan kesme vektörü
void rb_isr(void)          //Kesme fonksiyonu
{
   if(!input(pin_b6))      //B6 pinindeki butona basıldı mı?
   {
      if(sayac==150)       //Sayaç değerini sınırlamak için
      sayac=140;
      sayac+=10;

Buradaki int8 i=0,sayac=0 bloğu ve
if(sayac==150)       //Sayaç değerini sınırlamak için
      sayac=140;
      sayac+=10;
bloğundaki "i" ve "sayac" ifadelerinin ne anlama geldiğini ve ne amaçla kullanıldığını bir türlü anlayamıyorum... Bunları benim anlayabileceğim bir şekilde yazabilir misiniz rica etsem  :(

justice_for_all

Alıntı yapılan: oongit - 26 Kasım 2010, 23:20:12
Buradaki int8 i=0,sayac=0 bloğu

yukarda sadece degisken tanimlamisim ve ilk deger atamasi yapmisim..

i degiskeni butona kackez basildigi degerini tutuyo...

sayac degiskeni ise duty nin max degerini asmasini engelliyo...

yeni programini yaptim birazdan kodu buraya yazcam burdan kopyalarsin ama maz duty degerleri yalnis max degeri asiyo...

Alıntı yapılan: oongit - 26 Kasım 2010, 23:20:12
if(sayac==150)       //Sayaç değerini sınırlamak için
      sayac=140;
      sayac+=10;

yukaridaki kod ise duty degerini max 150 degerinde tutmak icin yapilmistir yani duty degeri 150 de iken arttirma butonuna basildi ise degeri yukselmesin 150de sabit kalsin die...
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

oongit

Sanırım biraz daha iyi anladım. Ama halâ tam olarak çözebilmiş değilim. O kodları kendim hesaplamadım. PWM Calculator diye bir program var ya ona hesaplattırdım...  :(

justice_for_all

#include <16F628A.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES RESERVED                 //Used to set the reserved FUSE bits

#use delay(clock=1000000)

int16 i=0,sayac=70,maxduty;


#int_RB    /////PORTB de b4-b7 pinlerinde olusan kesme vektoru
void  RB_isr(void) //kesme fonksiyonu
{
   if(!input(pin_b6)) ///b6 pinindeki butona basildi mi?
   {
     while(!input(pin_b6))
     {
         delay_ms(100);
         if(sayac==maxduty)  //sayac degerinin sinirlamak icin
            sayac=maxduty-5;
         
         sayac+=5;      //duty degerini arttirmak icin...
         set_pwm1_duty(sayac); //hesaplanan sayac degerini duty'e yansit..
     }
   }
   if(!input(pin_b7)) ///b7 pinindeki butona basildi mi?
   {
      
      while(!input(pin_b7))
      {
         delay_ms(100);
         if(sayac==5)    //yine buda sayac degerini sinirlama
            sayac=10;    
         
         sayac-=5;      //duty degerini azalt
         set_pwm1_duty(sayac); //hesaplanan sayac degerini duty'e yansit..
      }
   }
}
void main()
{

   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);  //bu satir timer0 icin kullanmadigin icin seni ilgilendirmiyo...
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);   //bu satirda timer1 icin buda ilgilendirmiyo..
   setup_timer_2(T2_DIV_BY_16,155,1);      //bu satir pwmin frekansini ayarlamak icin pwm periyodu=(PR2(bu satirda degeri 155)+1)*4*TOSC*timer bolucu orani(bu satirda degeri 16)
                                 //TOSC=1/FOSC (FOSC=1000000)
   setup_ccp1(CCP_PWM);                  //CCP modulu PWM olarak kullaniliyo demek.
   set_pwm1_duty(sayac);                  //baslangicta pwm duty si  %50 dir demek..bunu sen istedigin miktarda yapabilirsin...
   setup_comparator(NC_NC_NC_NC);         //Analog karsilastirici yok
   setup_vref(FALSE);                  
   enable_interrupts(INT_RB);            //b4-b7 pinlerindeki kesme aktif
   enable_interrupts(INT_EXT);            //b0 pinindeki kesme aktif
   enable_interrupts(GLOBAL);            //aktif olan butun kesmelere izin ver..
   
   set_tris_b(0xF7);                  //11110111 pin_b3 cikis diger pinler giris olarak ayarlandi..
   set_tris_a(0xFF);
   
   
   while(1)
   {
      if(!input(pin_a0)) ///a0 pinindeki butona basildi mi?
      {
         setup_timer_2(T2_DIV_BY_16,155,1); //100 Hz butona bikez basilinca bu if e girer
         maxduty=560;
         set_pwm1_duty(62);
      }
      else if(!input(pin_a1)) ///a1 pinindeki butona basildi mi?
      {
         setup_timer_2(T2_DIV_BY_16,103,1); //150 Hz ikinci kez basilinca
         maxduty=375;
         set_pwm1_duty(41);
      }
      else if(!input(pin_a2)) ///a2 pinindeki butona basildi mi?
      {
         setup_timer_2(T2_DIV_BY_16,103,1); //150 Hz ikinci kez basilinca
         maxduty=280;
         set_pwm1_duty(31);
      }
      else if(!input(pin_a3)) ///a3 pinindeki butona basildi mi?
      {
         setup_timer_2(T2_DIV_BY_16,103,1); //150 Hz ikinci kez basilinca
         maxduty=225;
         set_pwm1_duty(25);
      }
      else if(!input(pin_a4)) ///a4 pinindeki butona basildi mi?
      {
         setup_timer_2(T2_DIV_BY_16,103,1); //150 Hz ikinci kez basilinca
         maxduty=185;
         set_pwm1_duty(20);
      }
   }

}


max degerleri 5in katlari seklinde yazinca duzeldi arkadasim simdi bu programi derleyip denermisin...
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

oongit

Hemen deniyorum... Allah razı olsun, emeğinize sağlık...

oongit

#71
Programı kontrol ettim... 100 ve 150 Hz.'den sonra 200-250-300 diye devam etmesi gerekirken, 100-150-150-150-150 diye devam ediyordu. Sanırım küçük bir yanlışlık olmuş.

O kodların 100-150-200-250 ve 300 olacak şekilde değişmesi için o kodları düzelttim. Şu an 5 frekansı da sorunsuz olarak değiştirebiliyorum. Ancak Duty Arttır ve Duty Azalt butonları çalışmıyor...

Bir de her frekansın %10 Duty ile başlaması gerekiyordu ya... İşte o sadece simülasyon ilk başladığında 100 hz ve %10 olarak başlıyor...
http://img249.imageshack.us/i/65723804.jpg/
100 hz butonuna tıkladığımda duty yaklaşık 40 lara çıkıyor.
http://img337.imageshack.us/i/100hztkla.jpg/
150 de yaklaşık %40 civarlarında
http://img34.imageshack.us/i/150hztkla.jpg/
200 de yaklaşık %40 civarlarında
http://img189.imageshack.us/i/200hztkla.jpg/
250 de yaklaşık %40 civarlarında
http://img10.imageshack.us/i/250hztkla.jpg/
300 de yaklaşık %40 civarlarında
http://img517.imageshack.us/i/300hztkla.jpg/

Hiçbiri şu an için %10 olarak başlamıyor...

Bir de;
int16 i=0,sayac=70,maxduty;

burada i=0 için değişken atamışız ama i değişkenini hiç bir yerde kullanmamışız. Acaba bu satırla alakalı bir sorun olabilir mi?

Bir de şu anki güncel kod şu şekilde:
#include <16f628a.h>
#fuses xt,nowdt,noput,noprotect,nobrownout,mclr,nolvp,nocpd
#use delay(clock=1000000)
#define pwm100       pin_a0
#define pwm150       pin_a1
#define pwm200       pin_a2
#define pwm250       pin_a3
#define pwm300       pin_a4
#define duty_arttir  pin_b6
#define duty_azalt   pin_b7

int16 i=0,sayac=70,maxduty;

#int_RB                          //PORTB'de B4..B7 pinlerinde oluşan kesme
void RB_isr(void)                //Kesme fonksiyonu
{
   if(!input(duty_arttir))       //Duty Arttır butonuna basıldı mı?
   {
      while(!input(duty_arttir))
      {
         delay_ms(100);
         if(sayac==maxduty)      //Sayac değerini sınırlamak için
         sayac=maxduty-5;
         sayac+=5;               //Duty değerini arttırmak için
         set_pwm1_duty(sayac);   //Hesaplanan sayaç değerini Duty'e yansıt
      }
   }
   
   if(!input(duty_azalt))        //Duty Azalt butonuna basıldı mı?
   {
      while(!input(duty_azalt))
      {
         delay_ms(100);
         if(sayac==5)            //Yine bu da sayac değerini sınırlama
         sayac=10;
         sayac-=5;               //Duty değerini azalt
         set_pwm1_duty(sayac);   //Hesaplanan sayaç değerini Duty'e yansıt
      }
   }
}

void main()
{
   setup_timer_0(rtcc_internal|rtcc_div_1);
   setup_timer_1(t1_internal|t1_div_by_1);
   setup_timer_2(t2_div_by_16,155,1);
   setup_ccp1(CCP_PWM);
   set_pwm1_duty(sayac);   //Başlangıçta Duty %50'dir demek
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_RB);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
   set_tris_b(0xF7);
   set_tris_a(0xFF);
 
   while(1)
   {
      if(!input(pwm100))   //A0 pinindeki butona basildi mi?
      {
         setup_timer_2(T2_DIV_BY_16,155,1);  //100 Hz butona bikez basilinca bu if e girer
         maxduty=560;
         set_pwm1_duty(62);
      }
      
      else if(!input(pwm150)) //A1 pinindeki butona basildi mi?
      {
         setup_timer_2(T2_DIV_BY_16,103,1); //150 Hz ikinci kez basilinca
         maxduty=375;
         set_pwm1_duty(41);
      }
         
      else if(!input(pwm200)) ///a2 pinindeki butona basildi mi?
      {
         setup_timer_2(T2_DIV_BY_16,77,1); //200 Hz ikinci kez basilinca
         maxduty=280;
         set_pwm1_duty(31);
      }
            
      else if(!input(pwm250)) ///a3 pinindeki butona basildi mi?
      {
         setup_timer_2(T2_DIV_BY_16,61,1); //150 Hz ikinci kez basilinca
         maxduty=225;
         set_pwm1_duty(25);
      }
         
      else if(!input(pwm300)) ///a4 pinindeki butona basildi mi?
      {
         setup_timer_2(T2_DIV_BY_16,51,1); //300 Hz ikinci kez basilinca
         maxduty=185;
         set_pwm1_duty(20);
      }
   }
}

justice_for_all

sayac=deger
set_pwm1_duty(sayac)

While dongusu içindeki if lerin içine yazın deger yerine baslangıc duty degerlerini yazın...
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

oongit

Alıntı yapılan: justice_for_all - 28 Kasım 2010, 13:43:00
sayac=deger
set_pwm1_duty(sayac)

While dongusu içindeki if lerin içine yazın deger yerine baslangıc duty degerlerini yazın...
Özür dilerim ama anlayamadım...

justice_for_all

programınızda while(1) donguu içindeki iflerin parantez içlerini yazdığım kodu yazım...
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay