5 farklı frekansta Kare Dalga PWM

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

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=600,maxduty,minduty;


#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(50);
         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(50);
         if(sayac==minduty)    //yine buda sayac degerini sinirlama
            sayac=minduty+5;    
         
         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(0);                  //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(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=470;
         minduty=60;
         sayac=60;
         set_pwm1_duty(sayac);
      }
      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=290;
         sayac=40;
         minduty=40;
         set_pwm1_duty(sayac);
      }
      else if(!input(pin_a2)) ///a2 pinindeki butona basildi mi?
      {
         setup_timer_2(T2_DIV_BY_16,77,1); //200 Hz ikinci kez basilinca
         maxduty=235;
         sayac=30;
         set_pwm1_duty(sayac);
      }
      else if(!input(pin_a3)) ///a3 pinindeki butona basildi mi?
      {
         setup_timer_2(T2_DIV_BY_16,61,1);//250 Hz ikinci kez basilinca
         maxduty=190;
         minduty=25;
         sayac=25;
         set_pwm1_duty(sayac);
      }
      else if(!input(pin_a4)) ///a4 pinindeki butona basildi mi?
      {
         setup_timer_2(T2_DIV_BY_16,51,1);  //300 Hz ikinci kez basilinca
         maxduty=145;
         minduty=20;
         sayac=20;
         set_pwm1_duty(sayac);
      }
   }

}


soyle bir denermisiniz hocam...
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

oongit

Mükemmel olmuş, elinize sağlık, çok teşekkür ederim... Peki bu butonlar için buton gecikmesi de ekleyebilir miyiz? Yani duty butonlarına basılı tuttuğumda kendi kendine ilerlemesin... Bir de kontak sıçraması denilen olayı engellemek için çok küçük bir gecikme koyabilir miyiz?

justice_for_all

o zaman programi soyle degistirmeniz gerekiyor...

#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=600,maxduty,minduty;


#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(50);

         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(50);


         if(sayac==minduty)    //yine buda sayac degerini sinirlama
            sayac=minduty+5;    
         
         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(0);                  //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(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?
      {
         while(!input(pin_a0))
         delay_ms(50);
        
         setup_timer_2(T2_DIV_BY_16,155,1); //100 Hz butona bikez basilinca bu if e girer
         maxduty=470;
         minduty=60;
         sayac=60;
         set_pwm1_duty(sayac);
      }
      else if(!input(pin_a1)) ///a1 pinindeki butona basildi mi?
      {
         while(!input(pin_a1))
         delay_ms(50);

         setup_timer_2(T2_DIV_BY_16,103,1); //150 Hz ikinci kez basilinca
         maxduty=290;
         sayac=40;
         minduty=40;
         set_pwm1_duty(sayac);
      }
      else if(!input(pin_a2)) ///a2 pinindeki butona basildi mi?
      {
         while(!input(pin_a2))
         delay_ms(50);

         setup_timer_2(T2_DIV_BY_16,77,1); //200 Hz ikinci kez basilinca
         maxduty=235;
         sayac=30;
         set_pwm1_duty(sayac);
      }
      else if(!input(pin_a3)) ///a3 pinindeki butona basildi mi?
      {
         while(!input(pin_a3))
         delay_ms(50);

         setup_timer_2(T2_DIV_BY_16,61,1);//250 Hz ikinci kez basilinca
         maxduty=190;
         minduty=25;
         sayac=25;
         set_pwm1_duty(sayac);
      }
      else if(!input(pin_a4)) ///a4 pinindeki butona basildi mi?
      {
         while(!input(pin_a4))
         delay_ms(50);

         setup_timer_2(T2_DIV_BY_16,51,1);  //300 Hz ikinci kez basilinca
         maxduty=145;
         minduty=20;
         sayac=20;
         set_pwm1_duty(sayac);
      }
   }

}

Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

oongit

Çok teşekkür ederim, ellerinize sağlık... Yarın akşam görüşmek üzere, hoşçakalın...

oongit

#109
Kusuruma bakma... Bir kaç gündür olduka yoğundum. O yüzden nete pek girebilme fırsatım olmadı. Son yaptığımız revizyonu derledim ve PIC'e yükledim. Buton gecikmeleri çalışıyor, ancak %5'lik arttırma ve azaltma yapamıyorum. Çok daha düşük seviyelerde arttırma ve azaltma yapıyor. Belki %1'ler seviyesinde. Bunu nasıl düzeltebilirim? Bir de program ilk çalışmaya başladığında %10 ile başlaması gerekirken %0 ile başlıyor. Acaba şu en alttaki satırdan kaynaklanıyor olabilir mi?
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(0);


Bir de şu ilk satırdaki "INTERNAL ile T1" arasında kalan düz çizgi karakterini nasıl yazıyoruz. Klavyedeki tuş kombinasyonu nedir?
(T1_INTERNAL|T1_DIV_BY_1)

JKramer

Alıntı yapılan: oongit - 02 Aralık 2010, 00:27:09
Bir de şu ilk satırdaki "INTERNAL ile T1" arasında kalan düz çizgi karakterini nasıl yazıyoruz. Klavyedeki tuş kombinasyonu nedir?
(T1_INTERNAL|T1_DIV_BY_1)

Alt Gr+ (sol taraftaki shift tuşunun yanındaki tuş :) )

>
< |

gibi.

justice_for_all

klavyenize gore degisir egerki ingilizce klavye kullaniyosaniz shift+ soru isareti olan(sifirin hemen sag tarafindaki tus)..
eger turkce klavye kullanıyosanız shift + backspace tusunun sol tarafındakı tus...
Alıntı yapılan: oongit - 02 Aralık 2010, 00:27:09
Bir de program ilk çalışmaya başladığında %10 ile başlaması gerekirken %0 ile başlıyor. Acaba şu en alttaki satırdan kaynaklanıyor olabilir mi?
   set_pwm1_duty(0);

[/code]

evet bu satir yuzunden ben ilk basladiginda bi hata olmasin die sifirdan baslatmak istedim ama siz 0 yerine istediginiz sayiyi yazabilirsiniz..
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

oongit

Alıntı yapılan: JKramer - 02 Aralık 2010, 10:37:00
Alıntı yapılan: oongit - 02 Aralık 2010, 00:27:09
Bir de şu ilk satırdaki "INTERNAL ile T1" arasında kalan düz çizgi karakterini nasıl yazıyoruz. Klavyedeki tuş kombinasyonu nedir?
(T1_INTERNAL|T1_DIV_BY_1)

Alt Gr+ (sol taraftaki shift tuşunun yanındaki tuş :) )

>
< |

gibi.
Teşekkür ederim, öğrendiğim iyi oldu :)

oongit

Peki %5'lik değişimler için nasıl bir değişiklik yapmalıyım? Program şu anki haliyle %1'ler mertebesinde değiştiriyor Duty seviyesini...

justice_for_all

#114
http://www.4shared.com/file/8Rcx-Vp5/16f628a_ccs.html

programi biraz daha degistirdim bi bakarmisin...
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

oongit

Programa eklediğin artış değişkeni satırlarında yazan değerleri değiştirdiğim zaman sanırım istediğim gibi olacak. Çünkü 100 Hz'lik frekansa baktığımda, değişimlerin yaklaşık %2.8'er gibi oranlarla değiştiğini görüyorum.

Bir de şu;
#fuses reserved

satırı olduğu zaman kesinlikle derlemiyor. Ancak o satırı sildiğimde derleyebiliyorum. Bu satır ne demek istiyor?

justice_for_all

#116
iste odegerleri hesaplayip artis degiskenine atamalisiniz baska hic bi islem yapmaniza gerek kalmiyor...

o kodun ne oldugunu bilmiyorum bende hiz bi hata vermiyor...

ama sunu soyleyim ben degerleri dogru hesaplamistim calismasi gerek cunku proteusda deniyorum 20 kez arttirma butonuna basinca max degere,20 kex azaltma butonuna basinca min degere ulasiyorum...

yani %5lik artis * 20 =% 100 yapar...
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 - 02 Aralık 2010, 22:09:57
ama sunu soyleyim ben degerleri dogru hesaplamistim calismasi gerek cunku proteusda deniyorum 20 kez arttirma butonuna basinca max degere,20 kex azaltma butonuna basinca min degere ulasiyorum...

yani %5lik artis * 20 =% 100 yapar...

Ama maxduty değişkeni ile %75 ile sınırlamıştık...

justice_for_all

#118
%100 dedigim orda hasapladigin max deger varya ondan bahsediyorum yani %100 olan aslinda senin asil pwm frekansinin %75 i oluyor...

simdi nasil calisiyomu devre..

hesabida soyle (maxduty-minduty)* 5 / 100
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

oongit

Haklısın yaa... Bak ben işin orasını hiç düşünmemiştim... Söylediğinde haklısın. Evet çalışıyor. Sayende...
Teşekkürler...