Pic İle Frekans Okuma

Başlatan toprak, 23 Kasım 2012, 22:00:50

toprak

  Merhaba
  Pic 'i kullanarak frekans okutmak istiyorum. Okuduğu frekansa göre işlem yaptıracağım.
  PBP dili kullanıyorum. Frekans okuma işlemini nasıl yapabilirim. Picin hangi özelliğini kullanmak gerekiyor.
  Daha önceden ADC kullanarak yapmaya çalıştım. Fakat çok istediğim gibi olmadı. çok istikrarlı değildi.
  Frekansı pice okutmak mümkün mü.?
  Okutmak istediğim frekans 0 ile 2000 hertz arasında.
  Hangi komutları ve ayarları kullanmak gerektiği konusunda fikirlerinizi almak isterim.
 
 
Kişi kesinliklerle başlarsa gideceği yer kuşkulardır, ama kuşkularla başlayacak kadar doygun ise kesinliklere ulaşır.

nurim

Alıntı yapılan: toprak - 23 Kasım 2012, 22:00:50
  Merhaba
  Pic 'i kullanarak frekans okutmak istiyorum. Okuduğu frekansa göre işlem yaptıracağım.
  PBP dili kullanıyorum. Frekans okuma işlemini nasıl yapabilirim. Picin hangi özelliğini kullanmak gerekiyor.
  Daha önceden ADC kullanarak yapmaya çalıştım. Fakat çok istediğim gibi olmadı. çok istikrarlı değildi.
  Frekansı pice okutmak mümkün mü.?
  Okutmak istediğim frekans 0 ile 2000 hertz arasında.
  Hangi komutları ve ayarları kullanmak gerektiği konusunda fikirlerinizi almak isterim.
 
Forumda zaten vardı.
http://etepic.com/index.php/topic,60.0.html
Kolay Gelsin
nurim

ete

Frekans ölçmenin belli başlı iki yolu var. Birincisi sinyalin peryodunu ölçmek ikincisi ise belirli bir zaman dilimi içinde gelen puls sayısını hesaplamak şeklinde uygulanır.
Puls ölçmek nispeten kolay bir yöntemdir. Bunun için portb.0 kesmesini kullanabilirsiniz.
Önce kesmeyi yükselen kenar için kurup sinyal geldiğinde kesme bölümünde timer çalıştırıp sinyalin düşen kenarı için geçen süreyi hesaplarsınız. Veya kesme başında timer ı çalıştırıp kesmeyi bu seferde düşen kenar için kurup kesmeden çıkarsınız. Kesme oluştuğu anda timer değeri size yukselen kenarla düşen kenar arasındaki zamanı veerir. Benzer şekilde birde düşen kenarla yükselen arasındaki zamanı da bulup ilk bulduğunuza eklerseniz bir peryodu hesaplamış olursunuz. Bu hesabın hassas bir şekilde yapabilirseniz geriye frekansı F=1/T.  Formülü ile hasaplamak kalır. Burada 1 yerine 1000 yazarsanız frekans KHz cinsinden çıkar. 1 yerine 1.000.000'kullanırsanız frekans Hz olarak bulunur.

Diğer metod da ise yaklaşık 1 sn lik bir sabit zaman tutularak bu sürede gelen pulsleri sayabilirsiniz böylece frekans gelen pulsmadedi kadar hz dir.
Diyelimki 1snn(1000 ms) zaman tuttunuz tutarken tmr1 sayacını dışarıdan gelen pulsleri sayacak şekilde kurdunuz ve sıfırladınız. 1000 ms sonunda timer değeri size direk hz değerini verecektir.
İşlemcilerde gerek Tmr0 ve gerekse Tmr1 sayaçları dışarıdan gelecek pulsleri sayabilirler. Her birinin birer ayrılmış sabit giriş pini bulunur. Bu pinleri kullanarak saydırma işini yapabilirsiniz.
Ete

toprak

Hocam devreyi 12f675 kullanarak yapacağım. GP2 kesmesini kullanmam gerekecek.
Sinyali bu uçtan pice vermemiz gerekecek.
Bu durumda saydırma için TMR0 kesmesini kullanırsak iki kesme birden kullanma sorun yaratmaz mı hocam?
Bu konuda hiç örnek var mı?
Daha önce hiç GP2 kesmesini kullanmadım.
Kişi kesinliklerle başlarsa gideceği yer kuşkulardır, ama kuşkularla başlayacak kadar doygun ise kesinliklere ulaşır.

ete

Yazdıklarımı pek anlamadın sanırım. Aynı anda iki kesme kullanmıyoruz ki zaten!!.
Sen şimdi aşağıdaki metodlardan hangisini kullanacaksın önce onu söyle.
- Peryot ölçme
- Puls sayma

Ete

toprak

Yukarıda anlattığınız ilk yöntemi kullanacağim.
Yani yükselen kenar ile düşen kenar arasındaki zamanı hesaplayarak frekansı bulma yöntemi.
Kişi kesinliklerle başlarsa gideceği yer kuşkulardır, ama kuşkularla başlayacak kadar doygun ise kesinliklere ulaşır.

ete

Çok büyük bir hassasiyet aramıyor isen;
PULSIN PIN,1,YUKSEK
PULSIN PIN,0,ALCAK
şeklinde bir komut gurubu kullanıp gelen sinyalin HIGH ve LOW peryodunu ölçebilir (10 a bölünmüş halini)
sonra PERYOT=ALCAK+YUKSEK
FREQ=100/peryot formülü ile direk khz cinsinden frekansı hesaplayabilirsin.
yada hz cisninden hesaplamak istersen
peryot=(alcak+yuksek)
peryot=(100/peryot)*1000 şeklinde bulabilirsin.
kesme ile daha hassas hesaplayayım diyorsan,
O zaman GP2 pinini Yükselen kenar için kesme oluşturacak şekilde (PORTB.0 kesmesi gibi) kuracaksın. Yani OPTION_REG=%11000000 şeklinde verecek ve INTCON=%10010000 şeklinde kesme oluşturacaksın.
Ancak önceden yapılması gerekenler var.
z var bit
poz var bit
sure var word
freq var word
peryot var word
şeklinde değişkenleri tanımla
basla satırından evvel
poz=0:z=1 :freq=0:peryot=0 değerlerini ver.

Uzun anlatmaktansa direk kesme içinde ne yapılacağını göstereyim. Biraz karmaşık bir işlem gibi gözüküyor ama bütün yapılan işlem şu,
ilk kesme oluştuğunda z ye konum değiştir. süre=tm1 yap ve tmr1=0 yap
z=0 ise ilk kesme oluştu demektir. (z=1 ile başlamıştık) Bu durumda yapılması gereken kesmeyi düşen kenara ayarlamak
ancak son safhada yeniden yükselen kenar kesmesi yakalayacağımız için buraya bir poz değişkeni ile durum kontrolü eklemek gerekir. O halde POZ=1 ise işlem bitti peryodu hesaplayabiliriz demektir.

z=1 ise ikinci kesme oluştu demektir o halde sure=tmr1:tmr1=0:freq=freq+sure yapıp kesmeyi yükselen kenara çevirmek gerekir. Ayrıca burada Poz=1 vererek son safhada olduğumuzu belirteceğiz.

son safhada z yeniden sıfır olacak ve  poz=1 olduğundan sistem hesap kısmına geçecektir. Orada Sure=tmr1:freq=freq+sure
ve sonunda peryot=freq şeklinde elimize geçmiş olacaktır.

KESME:
SURE.BYTE0=TMRL:SURE.BYTE1=TMR1H
TMR1L=0:TMR1H=0
TOGGLE Z
IF Z=1 THEN BIR 'yani ikinci kesme oluşmuş ise

'Z=0 hali ilk kesme oluştu
IF POZ=1 THEN HESAP 'YANİ SON KESME OLUŞTU GİT HESAPLA ARTIK
GOTO CIK

BIR:
freq=freq+sure
POZ=1
GOTO CIK

HESAP:
      FREQ=FREQ+SURE
      PERYOT=FREQ
      FREQ=0:POZ=0
     
CIK:
    OPTION_REG=Z
    INTCON.0=0
    RESUME
    ENABLE       

şeklinde sistem çalışabilir herhalde.  Denemdim ama böyle olması gerek diye düşünüyorum.
Programın ana kısmında ise Frekans=1000/Peryot formülü ile frekansı hesaplayabilirsin.

Ete

toprak

#7
Hocam daha önce pulsin komutunu kullanmamıştım. Sormadan önce biraz araştırdım.
Ve programı şu şekilde yaptım.
@	device  pic12F675, wdt_off, pwrt_on, mclr_off, protect_off,bod_off,intrc_osc_noclkout
 
define OSC 4           
define osccal_1k 1
define PULSIN_MAX 1000
TRISIO = %00000100         
GPIO=0
OPTION_REG=%10000000    'Pull up dirençleri IPTAL
CMCON = %00000111       ' Giriþlerdeki Comparatorlar kapalý
ANSEL=0             

SYMBOL LED1=GPIO.0
SYMBOL LED2=GPIO.1

SAYAC   VAR BYTE
ALCAK   VAR WORD
YUKSEK  VAR WORD
PERYOT  VAR WORD
FREKANS VAR WORD
clear         

BASLA:

PULSIN GPIO.2,1,YUKSEK
PULSIN GPIO.2,0,ALCAK
      PERYOT=YUKSEK+ALCAK
      FREKANS=(100/peryot)*1000
   IF PERYOT<>0 AND FREKANS>300 THEN             
      SAYAC=SAYAC+1
      FREKANS=0
      LED1=1:PAUSE 300:LED1=0
      iF SAYAC=5 THEN
      LED2=1:PAUSE 300:LED2=0:SAYAC=0
      endif
   endif
GOTO BASLA
end

program çalışıyor.
Yalnız okuyacağı frekans 100 hz bile olsa işlem yapıyor. 300 hz den aşağısı için işlem yapmaması gerekirken
işlem yapıyor.
Dahili osilator kullanıyorum. Bunun bir etkisi olabilir mi.
Yani program çalışıyor ama istediğim gibi çalışmıyor.
Bir yerde yanlışlık var. Ama anlayamadım.
Kişi kesinliklerle başlarsa gideceği yer kuşkulardır, ama kuşkularla başlayacak kadar doygun ise kesinliklere ulaşır.

ete

300 den aşağısı için işlem yapma diye bir komut göremiyorum.
Komutlar her frekans için işlem yap şeklinde. O halde program doğru çalışıyor ama sen yanlış düşünüyorsun.
Ete

toprak

Hocam If kısmındaki şartı hep sağlamasının nedeni nedir anlayamadım.
Pice gelen sinyal 100 hz olduğu halde IF kısmı yine de çalışıyor.
Normalde çalışmaması lazım. Yanlış düşündüğüm nokta neresidir.
Kişi kesinliklerle başlarsa gideceği yer kuşkulardır, ama kuşkularla başlayacak kadar doygun ise kesinliklere ulaşır.

ete

Ben deniyorum bir terslik göremedim. Ancak hesaplamada kusur var sanırım.
Aşağıdaki kodu denermisin.
CLEAR dan itibaren aşağıdakileri programa kopyala lütfen.

Ete
clear         
pause 300
BASLA:

PULSIN GPIO.2,1,YUKSEK
PULSIN GPIO.2,0,ALCAK
      PERYOT=(YUKSEK+ALCAK)
      FREKANS=10000/(peryot/10)
   IF PERYOT<>0 AND FREKANS>300 THEN             
      SAYAC=SAYAC+1

      LED1=1:PAUSE 300:LED1=0
      iF SAYAC=5 THEN
      LED2=1:PAUSE 300:LED2=0:SAYAC=0
      endif
   endif
GOTO BASLA
end

toprak

Hocam yine aynı şey oldu. Frekans 300 den yüksek de olsa düşük de olsa IF kısmı çalıştı.

Bu arada programı count komutuyla denedim. Bu sefer istediğim oldu. Acaba kullanmam gereken komut count mu?
Program şöyle.
SYMBOL LED1=GPIO.0
SYMBOL LED2=GPIO.1

SAYAC   VAR BYTE
ALCAK   VAR WORD
YUKSEK  VAR WORD
PERYOT  VAR WORD
FREKANS VAR WORD
clear         

BASLA:

COUNT GPIO.2,1000,FREKANS

 
   IF FREKANS>300 THEN             
      SAYAC=SAYAC+1
      FREKANS=0
      LED1=1:PAUSE 300:LED1=0
      iF SAYAC=5 THEN
      LED2=1:PAUSE 300:LED2=0:SAYAC=0
      endif
   endiF
GOTO BASLA
end

Bu şekilde yapınca program doğru çalıştı.
Biraz daha denemem gerekecek.
Kişi kesinliklerle başlarsa gideceği yer kuşkulardır, ama kuşkularla başlayacak kadar doygun ise kesinliklere ulaşır.

toprak

Hocam TMR0 kullanarak da bir program yapmaya çalıştım. Frekans değeri kadar ledi yakıp söndürdüm.
Fakar TMR0 için ön bölücü değeri en düşük 1/2 dir. Bunu nasıl halledeceğiz.
SYMBOL LED1=GPIO.0
SYMBOL LED2=GPIO.1

I       VAR WORD
FREKANS VAR WORD  32
clear         
PAUSE 300
BASLA:
  OPTION_REG=%10000000
  TMR0=0
  OPTION_REG=%10100000
  pause 100
  OPTION_REG=%10000000

  FREKANS=TMR0
  IF FREKANS>10 THEN
  for I=0 TO FREKANS
      TOGGLE LED1
      PAUSE 250
      NEXT I
    ENDIF
   
GOTO BASLA

       END
Kişi kesinliklerle başlarsa gideceği yer kuşkulardır, ama kuşkularla başlayacak kadar doygun ise kesinliklere ulaşır.

ete

Sen en düşük ne olmasını istiyordun? 1/1 midir?.
Option registere bakarsan, TMR0 sayacı için bölme oranlarının 1/2 den başladığını ancak aynı sayaç ile çalışan WDT bölem oranlarının ise 1/1 den başladığını görebilirsin.
Şayet sana 1/1 gerekiyor ise Option Registeri 3 nolu biti (PSA)nin 1 ile işlemciyi kandırmak mümkün oluyor. Böylece sen TMR0 sayacını 1/1 bölme oranı ile kullanabiliyorsun. Tabiiki bölme işlemi WDT için yapılmış gibi gözüküyor ama aslında sen onu TMR0 için kullanmış oluyorsun.

Denemesi bedava.

Ete

toprak

Evet 1/1 olmasını istiyordum. Optıon registerin 3.Bitini 1 yapınca oldu.
Programda 100 milisaniye boyunca TMR0 ı saydırdım. Gerçek frekans programda gözükenin 10 katı oluyor yani.
Hocam sormak istediğim birşey var.
Dahili osilator 4 mhz seçili. Ölçtüğüm frekans 0 ile 1000 Hz arası.
TMR0 8 bitlik bir sayıcı. Yani 256 ya kadar sayabiliyor.
bu sayma işlemini tam olarak TMR0 nasıl yapıyor.
Osilatore bağli olarak nasıl bir hesap yapıyor.
Kişi kesinliklerle başlarsa gideceği yer kuşkulardır, ama kuşkularla başlayacak kadar doygun ise kesinliklere ulaşır.

Powered by EzPortal