12f675 PWM Frekans sorunu (timer0 sorunu)

Başlatan mcn, 10 Mart 2011, 23:10:58

mcn

12f675 ile RGB çalışması yapıyorum.Tabi ki pwm leri timer0 ile oluşturdum.

Ancak şöyle bir sorunum var.

Timer0 ayarlarındaki "setup_timer_0(RTCC_INTERNAL | RTCC_DIV_2); " satırında en sondaki bölme oranını,kesme süresi en düşük olması ve böylece pwm frekansımın olabildiğince yüksek olması için,aşağıdaki formule göre en düşük olanını seçmem gerek:

"Kesme Süresi=Tosc x Bölme Oranı x (256-timer değeri)"

Ancak aşağıdaki resimlerden de görüleceği üzere,değişik bölme oranı değerlerinde çok saçma sonuçlar elde ettim.1 den 256 ya kadar pic in kütüphanesindeki değerleri deniyorum ancak en yüksek frekansı "64" de elde ettim.

Sorun nedir,neden böyle yapar bir türlü anlayamadım?Neyi yanlış yapıyorum?Yoksa olur mu öyle?

[IMG]http://img88.imageshack.us/img88/607/90578391.jpg[/img]

Uploaded with ImageShack.us

[IMG]http://img121.imageshack.us/img121/230/60432219.jpg[/img]

Uploaded with ImageShack.us

[IMG]http://img98.imageshack.us/img98/990/91559564.jpg[/img]

Uploaded with ImageShack.us

www.teknikyazi.com --üşenme,erteleme,vazgeçme...

fahri-

12f683 kullansan. HW pwm var. sadece öneri...

mcn

Önerin için teşekkürler ancak 3 pinden pwm almam gerekiyor,yani gene değişen bişey olmayacak.

Olsa bile elimde çok fazla 12f675 var  :)
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

mdemir

Merhaba,
Ne yapmaya çalıştığınızı anladım ama nasıl yapmaya çalıştığınız açık değil. Yazdığınız kodu buraya koyarsanız sorununuzun ne olduğunu gösterebilirim.

mcn

Nasıl açık değil ki yapmaya çalıştığım,yazılımsal pwm oluşturuyorum ve pwm leride timer0 kesmesi kullanarak yapıyorum.Sorunum timer0 ın kesme süresi ile frekansımı ayarlayamamak?Neden ayarladığımı da yukarda yazdım.Daha ne diyeyim?
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

drmp

maalesef c bilmiyorum ama dediğin loayın aynısını bende yaşadım sonra oturup yeni baştan yazdım programı evet hata değil bu bir bug
derleyici manuelinde byte olarak gössterdiği pwm değeri deneme yaparak word olarak girdiğimde sorun düzelmişti aynı değeri giryordum ama yapı olarak byte değil word idi  senin olayınla bir ilgisi olmayabilir ama belki işe yarar

mdemir

Bir şeyleri eksik yaptığın için istediğin gibi çalışmıyor işte. İlk mesajında yazdığın kodu da ekleseydin şimdiye RGB olayını halletmiştin ama sen hala basit bir frekans oluşturmakla uğraşıyorsun. Forumlarda yardım almak için soru sorarken yeterince açıklayıcı olmak gerekir, yoksa çok beklersiniz.




mdemir

#7
Bir önceki mesajım moderasyona takıldı galiba.

Yazınızdaki resimlere göre frekans oluşturmada sorununuz var. Frekansta küçük farklar yok, tamamen tutarsız. Kodunuzu koymanızı istedim çünkü resimlerde interrupt içinde yapılan porta bir değer atama işlemi gözükmüyor. Görmeden tahminde bulunacak olursam kodunuzda gerekli interrupt bölümü yok, main() içinde döngüyle bir şeyler yapmaya çalışıyorsunuz. RGB için doluluk kısmına geçmeden sadece frekansı görmeniz için bir örnek veriyorum, denemelerinizi bir de bu kodla yapın.
#include <12F675.h>
#byte PORTA = 0x05
#byte TRISA = 0x85

#FUSES INTRC_IO, NOWDT, NOPUT, NOMCLR, NOBROWNOUT, NOPROTECT, NOCPD
#use delay(clock=4000000)
#use fast_io(A)

#int_RTCC
void  RTCC_isr(void) {
   PORTA ^= 0b111;
}

void main() {
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);
   setup_timer_1(T1_DISABLED);
   setup_comparator(NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);

   TRISA = 0b00000000;
   PORTA = 0b00000000;
   
   for(;;)
      ;
}



mcn

İlginiz için teşekkürler mdemir.

Kodlarımı ekliyorum.Yapmak istediğim renklerin kendi arasında soft bir geçiş olması.Sorun yaşadığım kısım ise geçiş esnasında ışıkta titreme oluyor.Frekanstan kaynaklandığını düşündüm,bahsettiğiniz doluluk nedir tam bilmiyorum?Sizin gönderdiğiniz kodları denedim,bir sorun gözükmüyor,ben de neden böyle birşey oluyor anlayamadım?tekrar teşekkürler.

#include <12F675.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOMCLR                     //Master Clear pin enabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPD                    //No EE protection

#use delay(clock=4000000)

#define BLUE PIN_A0 
#define GREEN PIN_A1 
#define RED PIN_A2 
#define GP3 PIN_A3 
#define GP4 PIN_A4 
#define GP5 PIN_A5 

#use fast_io(A)


int i=0,p=100,r=0,rd,bl,gr,mod=0,n=0;
int f=50,m=200,b=2,a=0,h=150;

#int_timer0  
void  timer0_kesme ()   
{
    set_timer0(255);
    i++;
    if(i==rd)
    {output_low(RED);}

    if(i==gr)
    {output_low(GREEN);}

    if(i==bl)
    {output_low(BLUE);}

    if(i==51)
    {i=0;
    output_a(0b111111);
    
    }

}

void fast()
{

for(r=0;r<f;r++)
{
for(n=0;n<f;n++)
{
for(a=0;a<3;a++)
{

}

}}
}

void soft()
{
for(r=0;r<m;r++)
{for(n=0;n<b;n++)
{


}}
}

void softa()
{

for(r=0;r<h;r++)
{
for(n=0;n<h;n++)
{
}}
}

void main()
{

set_tris_a(0b000000);

OUTPUT_a(0b111000);

setup_timer_0(RTCC_INTERNAL | RTCC_DIV_64); 
   set_timer0(255);   

enable_interrupts(int_timer1);
   enable_interrupts(INT_timer0); 
   enable_interrupts(GLOBAL);



output_a(0b111111);

while(1)
{


for(rd=30;rd<49;rd++)//kirmizi
{
bl=2;gr=2;
if(rd==48)
{
for(n=0;n<p;n++)
{softa();
}}

soft();
}
for(gr=2,rd=49;gr<49;gr++,rd--)//kirmizidan yeşile
{
bl=2;
if(gr==25)
{
for(n=0;n<p;n++)
{softa();
}}

if(gr==48)
{
for(n=0;n<p;n++)
{softa();
}}

soft();
}



for(bl=2,gr=49;bl<49;bl++,gr--)//yeşilden maviye
{
rd=2;
if(bl==25)
{
for(n=0;n<p;n++)
{softa();
}}

if(bl==48)
{
for(n=0;n<p;n++)
{softa();
}}


soft();
}
for(gr=2;gr<49;gr++)//maviden turkuaza
{
rd=2;bl=49;

if(gr==25)
{
for(n=0;n<p;n++)
{softa();
}}

if(gr==48)
{
for(n=0;n<p;n++)
{softa();
}}

soft();
}
for(bl=49,rd=2;rd<49;bl--,rd++)//turkuazdan sarıya
{
gr=49;

if(rd==25)
{
for(n=0;n<p;n++)
{softa();
}}

if(rd==48)
{
for(n=0;n<p;n++)
{softa();
}}

soft();
}
for(bl=2,gr=49;bl<49;bl++,gr--)//sarıdan mora
{
rd=49;
if(gr==25)
{
for(n=0;n<p;n++)
{softa();
}}

if(gr==48)
{
for(n=0;n<p;n++)
{softa();
}}

soft();
}
for(gr=2;gr<49;gr++)//sarıdan beyaza
{
rd=49;bl=49;
if(gr==25)
{
for(n=0;n<p;n++)
{softa();
}}

if(gr==48)
{
for(n=0;n<p;n++)
{softa();
}}

soft();
}
for(bl=49,gr=49;bl>3;bl--,gr--)//yeşilden maviye
{
rd=30;
if(bl==25)
{
for(n=0;n<p;n++)
{softa();
}}

if(bl==48)
{
for(n=0;n<p;n++)
{softa();
}}
soft();
}




}}

www.teknikyazi.com --üşenme,erteleme,vazgeçme...

mdemir

Merhaba,

Doluluk derken duty cycle demek istemiştim.

Kesme içinde "set_timer0(255);" yazmışsınız. Burası çok hatalı.
Timer 0'dan sayıp 255 olunca yeni bir kesme gelecek. Siz kesme yeni başlamış, timer 4-5 civarında iken doğrudan 255'e set ediyorsunuz. Bu durumda başka işlem yapacak zaman kalmaz, arka arkaya kesmeler gelir. Bütün zamanlamalar karışır.
İstediğiniz frekansa yakın bir değeri setup_timer_0() komutunda prescaler ile elde edin, set_timer0()'yu ise ince ayar için kullanın. Burada 200'den büyük bir değer kullanmamaya çalışın. Kodda başka bir sorun göremedim. Kolay gelsin.

My75

#10
2 ay önce Attiny2313 ile rgb kontrol yaptım,4 kanal hpwm var.Benim yaptığım 3 kanal rgb kontrol fakat Dmx512 kontrollu.Avr bu konuda mükemmel çalışıyor kısaca profesyonel bir şey yapmak istersen birde Avr ile dene derim..Üstelik Bascom avr Basic ile bir kaç komutta iş bitiyor...Herşey kütüphanesinde var..Ama tabiki Pic ile de olur,geçişlerde zamanları yükseltmen gerek,mesela pwm 255'den atıyorum 1us ile düşerken 100'den sonra 5us ile düşmelisin,benimki örnek sadece.Bu durum ledlerin tepkime süresi ile alakalı gibimi desem kısaca parlama oranı birebir doğru orantıda düşmüyor..
Tomurcuk için çaba göstermeyen dal,odun kalmaya mahkumdur...