Frekans Ölçme ( Kare Dalga )

Başlatan saucompeng, 14 Aralık 2011, 20:15:01

saucompeng

Merhaba arkadaşlar;

18F2585 + 10MHZ kristal kullanarak yaptığım devrede RB0 pinine karedalga vermekteyim. Bu karedalga ise 220V gibi 50Hz'lik bir dalga. Ve ben bu dalgayı RB0 pininin interrupt'ını kullanarak yükselen kenarları dikkate alarak ölçmek istiyorum. Tabi ölçüyorum fakat değer 50 çıkması gerekirken 54-49 arasında değerler oluyor.  Ve garip olan bazen 16 , 23 gibi garip değerlerde olabiliyor. 

1. deneme > #int_timer2 kullanarak ( 200 us * 5000 = 1sn ) boyunca RB0 pinindeki yükselen kenarları saydırmak. Sonuç > 54-49 arası değerler

2. deneme > #int_timer2 kullanarak ( 200 us * 5000 = 1sn ) boyunca while(1) içerisinde input(pin_b0) değerinin değişimini saydırmak. Sonuç > Olması gereken 100 , karşılaşılan 20-30 arası bir değer

3. deneme > #int_timer2 kullanarak ( 200 us  ) iki rb0 interrupt'ı arasındaki süreyi ölçmek. Çıkan sonuçlara göre 20ms olması gereken değer 11.6 ms çıkıyor.


Sizce rb0 pini yerine ccp1 olan bir pin mi kullanmak gerektiği için böyle bir problem oluyor ? Yoksa rb0 pinine gelen sinyalde bozukluk mu var ?

500 Mhz osiloskopla sinyali ölçtüm ve tam tamına 50Hz lik bir sinyal var. Osiloskopun kaçırdığı ara saçma değerler olabilir mi?
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

saucompeng

Alıntı yapılan: gerbay - 14 Aralık 2011, 20:19:26
hocam periyodu ölçtüğün timer ın hassasiyeti nasıl..  Bir de bu tür durumlarda atıyorum 10 sn buyunca ölçüp sonra 10 a bölmek falan daha sağlıklı sonuç verir.

Timer 200uS'de bir interrupt üretiyor , Ayrıca 10 sn boyunca örnekleme almak mümkün değil çünkü sistemin amacı sinyal 50 Hz altına düşünce elektriğin sağlıklı veya olmadığını anlayarak bir mesaj üretmek.
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

justice_for_all

peki timer dan eminmisiniz yani 200 us oldugundan
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

CaFFeiNe

hocam timer kesmesi yerine RB0 kesmesini kullanıp her kesme geldiğinde timer registeri değerini okuyup frekansı hesaplayabilirsiniz sanıyorum
yada capture modülünü kullanın

saucompeng

Alıntı yapılan: justice_for_all - 14 Aralık 2011, 20:27:40
peki timer dan eminmisiniz yani 200 us oldugundan

200us olduğuna kesinlikle emin oldum. Bir led çıkışı verdim , osiloskopta sinyalin frekansını kontrol ettim.  CaFFeiNe  timer register'ı değerini nasıl okuyabilirim ?   gerbay kodlar işyerinde yarın paylaşırım muhtemelen...
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

justice_for_all

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

drmp

caffeine katılmamak elde değil zaten başka yoluda yok  bir profesyone üründede yöntem budur diye biliyorum

2 pals arasındaki zaman zarfında içeride bir tane sayaç sayacak  1.plus start 2.puls stop
buradan sayac değerini hesaplayarak hassas ölçüm yapabilirsin

justice_for_all

#7
kodunu gormek lazim 3. yontem icin.. CCS yi kullaniyosun sanirim timer degerini elde etmek icin degisken = get_timerx; // burda x kullandiginiz timer
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

saucompeng

Alıntı yapılan: justice_for_all - 14 Aralık 2011, 21:06:59
hangi derleyiciyi kullaniyosun?

Derleyici olarak MPlab kullanıyorum , Programlayıcı MPLAB ICD3...

Alıntı yapılan: gerbay - 14 Aralık 2011, 21:16:47
hocam bir de rb0 pinine osiloskop bağlayıp oradaki sinyali osiloskop ile ölçebilirmisin?

Osiloskopla zaten dediğim karedalgayı ölçüyorum gerbay
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

justice_for_all

Alıntı yapılan: saucompeng - 14 Aralık 2011, 21:40:55
Derleyici olarak MPlab kullanıyorum , Programlayıcı MPLAB ICD3...

mplab bir derleyici degildir hocam derleyicinin calismasini saglar sadece microchipin derleyicisinimi kullaniyosun CCS yi mi
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

saucompeng

Alıntı yapılan: justice_for_all - 14 Aralık 2011, 21:15:38
kodunu gormek lazim 3. yontem icin.. CCS yi kullaniyosun sanirim timer degerini elde etmek icin degisken = get_timerx; // burda x kullandiginiz timer


CCS'TE KABACA YAZMAK GEREKİRSE


int16 fTimer=0;
int16 tTimer=0;

#int_timer2
void isr_timer2()   (200 us )
{
      tTimer++;
      fTimer++;
}


int16 oldFtimer=0;
int16 newtime=0;


#int_ext
void ext_isr()
{
     newtime=fTimer-oldFtimer;
     oldFtimer=fTimer;
}


int main()
{
     ...
     while(1)
      {
            if(tTimer>5000)  //200us*5000=1sn
            {
                write_eeprom(fCount++,newtime);
            }
      }
}
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

CaFFeiNe

Alıntı yapılan: saucompeng - 14 Aralık 2011, 21:05:44
200us olduğuna kesinlikle emin oldum. Bir led çıkışı verdim , osiloskopta sinyalin frekansını kontrol ettim.  CaFFeiNe  timer register'ı değerini nasıl okuyabilirim ?   gerbay kodlar işyerinde yarın paylaşırım muhtemelen...

mesela timer-1 i dahili clock ile çalışacak şekilde ayarlarsın sonra TMR1H ve TMR1L registerlerini okuyup 0..65535 arası bir değer elde edersin
mesela ilk RB0 kesmesinde 1546 okuduk diyelim bir sonraki RB0 kesmesinde 34564 okuduk diyelim aradaki fark 34564-1546=33018 clock yapar bir clock 1us ise 33.018mS yapar yani 30.28Hz

tabi basic,C gibi bir dil kullanıyorsan timer değerini okumak gayet kolay misal CCS için timer1 okuma

deger=get_timer1();

saucompeng

Alıntı yapılan: CaFFeiNe - 14 Aralık 2011, 21:55:27
mesela timer-1 i dahili clock ile çalışacak şekilde ayarlarsın sonra TMR1H ve TMR1L registerlerini okuyup 0..65535 arası bir değer elde edersin
mesela ilk RB0 kesmesinde 1546 okuduk diyelim bir sonraki RB0 kesmesinde 34564 okuduk diyelim aradaki fark 34564-1546=33018 clock yapar bir clock 1us ise 33.018mS yapar yani 30.28Hz

tabi basic,C gibi bir dil kullanıyorsan timer değerini okumak gayet kolay misal CCS için timer1 okuma

deger=get_timer1();

Anladım. Ama zaten benim yaptığım işlemlerde aynı sayılır. Fakat sonuçta bir problem var :/
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

haydarpasamikro

ilk pals interruptı ile timerın değerini saklayın. Her timer interrupt olunca ilave edin. Tekrar pals interrupt olunca timer değerini tekrar ilave edin. Böylece 2 pals arasında geçen timer toplam değerini bir artış süresine ile çarpın ve bunu f=1/t formülünden frekansı çıkartın. Örneğin timer toplam değerini tuttuğumuz değişken 20000 saymış olsun. Ftimer = 1us olsun. Yani 20000us=20ms eder. f= 1/20ms = 50hz çıkar. ANCAK! interrupt oluşması ile kesme alt programın çalışması ve timer değerini çekene kadar geçen süreyi de düşünmek gerekir. Yani çıkarmak gerekir. Fibonacci hesaplamısı bu hatayı gidermek için kullanılabilir.
Mikro Dünyası.Haydarpaşa Teknik ve Endüstri Meslek Lisesi Mikrodenetleyici Atl. Şefi

CaFFeiNe

yalnız sadece RB0 kesmesi kullan timer kesmesini kapat ve tüm ölçme işini RB0 kesmesinde halledebilmen lazım, yalnız timer registerlerinin taşma olayıda var mesela ilk değeri okudun diyelimki 60000, sonraki okumada ise mesela 10000 bu sefer ölçtüğün pals 10000+5536 olacak, şöyle yapabilirsin ilk okumada timeri registerlerini sıfırla sonraki okumada direk değeri okumuş olacaksın, 50Hz işaret için sanırım 100 adet RB0 kesmesi olacak yani 10ms de 1, 1uS clock zamanı için timer registerlerinde haliyle 10000 okuman lazım