T

PULSIN Sorunu

Başlatan tass_co, 27 Şubat 2014, 12:02:13

tass_co

Merhaba arkadaşlar. 16f877 ile gelen puls leri saymak istiyorum. kullandığım kod;


DEFINE OSC 4
DEFINE PULSIN_MAX 1000
TRISB=0
OPTION_REG= %10000000

ALCAK VAR WORD
YUKSEK VAR WORD
PERIYOD VAR WORD
SONUC VAR WORD
CLEAR

BASLA:
PULSIN PORTB.1,0,YUKSEK
PULSIN PORTB.1,1,ALCAK
PERIYOD=(ALCAK+YUKSEK)
SONUC=(10000/(PERIYOD/10))*30


Bu şekilde yaptığımda aldığım değer 65506, almam gereken değer ise 120. Tam olarak neyi yanlış yaptığımı çözemedim. Yardımcı olursanız sevinirim

İyi çalışmalar

ete

Sorunun ne olabileceğini maalesef bizde bilemeyiz.
Çünki detay vermemişsin.
PULSIN PORTB.1,0,YUKSEK   bu komut satırı ile gelen puls'in LOW süresini ölçersin. Bunuda 10'a bölünmüş olarak alırsın.
Sonuç us cinsindendir. Örnek verecek olursak süresi 1000 us olan bir LOW sinyalini sen YUKSEK=100 olarak okursun.
Sanki buradaki değişkene ALCAK desen daha uygun olacak gibi. Bir sonrakinede YUKSEK desen daha uygun gözüküyor.
PULSIN PORTB.1,1,ALCAK, bu komut satırıda gelen sinyalin HIGH süresini ölçecek. mantık aynı.
Bu hesaba göre verdiğin formül ile 65506 sonucunu alıyor isen peryot=4 olarak hesaplanıyor demektir. Alcak=2 , Yüksek=2 gibi sanki. BUnların 10'a bölünmüş değerler olduğu düşünülürse gelen sinyalin yaklaşık 20 us LOW ve 20 us HIGH süresi var demektir.
Tabiiki neye dayanarak sonucun 120 çıkması gerektiğini bilemiyorum ama benim açıklamama göre yanlışını sen bul istersen.

Ete

tass_co

Haklısınız hocam. Yüksek-alçak değişkenleri yanlış atamışım.

Hocam, Proteus-Puls ve Clock Generator ünden çıkış veriyorum. 4hz sinyal gönderip Pulsin ve formül yardımıyla 120 sonucunu elde etmek istedim. Lakin hangi değeri verirsem vereyim 65535 (uç değer) almaktayım. Ölçümde bir yanlışım var ama bulamadım.

ete

#3
Asıl sorunun puls girilen PORTB.1 pinini çıkış olarak belirlemiş olman. Puls giriş pinini giriş yaparsan sorun düzelir. Çünki kod da bir hata gözükmüyor. Ama neden hala 4 Hz lik sinyalde 120 elde ediyorsun onu anlamadım. Sanırım özel bir sisteminvar hesaplama ona denk geliyor.

Ben bir deneme yaptım ve aşağıdaki kod ile doğru sonuç alıyorum,
PULSIN PORTB.0,1,yuksek
PULSIN PORTB.0,0,ALCAK
PERIYOD=(ALCAK+YUKSEK)
SONUC=(10000/(PERIYOD/10))*30 '    9464

LCDOUT $fe,$02,"sonuc=",dec sonuc


Üstelik sırf denemek amacı ile puls giriş pininide çıkış bıraktım. Yine doğru sonuç veriyor (120 çıkıyor) . Sebebide PULSIN komutunun otomatikman ilgili pini Giriş olarak ataması olsa gerek. Bazı komutlar ilgili pin giriş değilse ve o pinden komut giriş alacak ise pini otomatik giriş yapar bazılarıda tersini yapar.
Ete



tass_co

#4
Hocam çok teşekkür ederim, zaman ayırdığınız için.

Hata şu kod satırından kaynaklanıyormuş. "'DEFINE PULSIN_MAX 1000", kaldırınca ölçüm düzeldi.

Daha önce sizi yine rahatsız etmiştim fan kontrol projesi için. 30 ile çarpmamın sebebi fanın RPM değerini elde edebilmek içindir. Şimdi portb ye 10 giriş alıp fanların rpm değerini okuması için ayarlayacağım ve hayata geçireceğim. Ama daha önce bahsettiğiniz gibi çalışmayadabilir :)

Tekrar teşekkür ederim sayın hocam.
İyi günler dilerim

tass_co

Hocam tekrar rahatsız edeceğim ama örnek vererek sorayım; frekans 52,34hz olduğunda çıkan sonucumuzun 1570 olması gerekiyor lakin çıkan sonuç 1560 olmakta. Başka değerlerde bu fark değişmekte. Bunu nasıl düzeltebilirim

ete

Pulsin komutu ile olmaz bu iş. Zİra zaten 10'a bölünmüş değer verdiği için otomatikman küsüratlar temizleniyor demektir.
Küsüratlı işlemlerde bana kalırsa TMR1 sayacını kullanarak süre ölçmen gerekir. BU şekilde daha hassas ölçüm yapabilirsin.
Ölçmek yapmak için
T1CON=0:TMR1L=0:TMR1H=0
WHILE PORTB.1=1:WEND  'pin LOW oluncaya kadar bekle
T1CON=%00000001 'tmr1 aktif
WHILE PORTB.1=0:wend
T1CON=0:ALCAK.Byte0=TMR1L:ALCAK.Byte1=TMR1H
TMR1L=0:TMR1H=0
WHILE PORTB.1=0:WEND
T1CON=1
WHILE PORTB.1=1:WEND
T1CON=0:YUKSEK.Byte0=TMR1L:YUKSEK.Byte1=TMR1H
Peryod=ALCAK+YUKSEK
SONUC=10000/PERYOD*30
SOnuç hesabında tekrar 10'a bölmüyoruz çünki hesaplanan değer 1/1 ölçüm değerindedir.

Ete

tass_co

Hocam peki 10 girişi timer ile ölçebilecek miyim? Yani demek istediğim Timer tek giriş ve tek ölçüm için 1 sn beklemek durumunda. Yanlışsam düzeltin lütfen

ete

#8
Başka çaren var ise onu yap istersen değilse küsüratlı freklanslarda Pulsin sistemi çalışmaz diyorum.
Ayrıca nedne 1 sn beklesin onuda anlamadım. Sen puls genişliği ölçüyorsun puls saymıyorsunki!!!

Ete

tass_co

#9
Yanlışsam düzeltin hocam; 1 sn içindeki puls sayısı bize frekansı veriyor. Frekansı alıp 30 ile çarpmam lazım ki rpm değerini öğrebileyim. 10 giriş olduğunu ele alırsak, timer her giriş için 1 sn meşgul edilecek. Sonuç olarak 10 sn de bu değerleri elde etmiş olacağım. Umarım yanlış düşünüyorumdur

Hocam değerde 5~10 oynama olsa sıkıntı değildi ama bazı değerlerde fark 28 e çıkmakta. Tek timer ile aynı zamanda 10 giriş frekansını ölçebilecek bir metod varsa işimi görecek. Diğer türlü 2 timer lı pic için 10 sinyali ölçmek 5 saniye sürecek. bu da benim işeme yaramayacak

ete

Başından beri yanlış yapıyorsun galiba. Kullandığın komut PULSIN puls genişliğini ölçer puls saymaz. Komut kullanımı ;
PULSIN Pin,State,Var  şeklinde olup State parametresi HIGH ölçülecek ise 1 , LOW ölçülecek ise 0 olarak kullanılıyor.
Puls sayacak komut ise ;
COUNT Pin,Period,Var şeklinde kullanılır.

Frekans ölçmek için illa pulsları saymak gerekmez. Puls genişlikleride frekans konusunda bize bilgi verir.
Zaten kullandığın yöntem puls genişliği yöntemi ama kafandaki bilgi puls sayma yöntemi nasıl olmuş anlamadım.
Frekans=1/T yani 1/Peryot dur.  Bu durumda PULSIN komutu yada söylediğim yöntemle ölçeceğin puls genişlikleri yöntemi ile frekans hesaplayabilirsin. Bunuda üstelik 1 sn beklemeden yaaprsınki başka çarende yok gözüküyor.

Ete

tass_co

#11
Hocam çok özür diliyorum. Frekans hesabına takıldım, ezbere gittim.

Yukarıda verdiğiniz timer kodunu denedim, 0 değerini almaktayım. Acaba Timer için define vs gibi birşey mi eklemem gerekiyor?

ete

#12
Başka bir şey gerekmez. Kod da bir hata vardır.
Ufak bir deneme yaptım. Aşağıdaki kod 16F628A da mükemmel çalışıyor.
       TMR1L=0:TMR1H=0:T1CON=0
       WHILE GIR=1:WEND
       WHILE GIR=0:WEND
       T1CON=1
       WHILE GIR=1:WEND
       T1CON=0
       YUKSEK.BYTE0=TMR1L:YUKSEK.BYTE1=TMR1H
       TMR1L=0:TMR1H=0:T1CON=0
       WHILE GIR=0:WEND
       WHILE GIR=1:WEND
       T1CON=1
       WHILE GIR=0:WEND
       T1CON=0
       alcak.BYTE0=TMR1L:alcak.BYTE1=TMR1H     
       
       LCDOUT $FE,$02,"YUKSEK=",DEC YUKSEK,"  "
       LCDOUT $FE,$C0,"ALCAK =",DEC ALCAK,"  " 
       PAUSE 50
       GOTO BASLA


Ete

Powered by EzPortal