pıc ile frekansmetre

Başlatan asof544, 07 Nisan 2015, 13:51:02

ete

TMR1 kesmesi bence hala çalışmıyor. Sebebini de bilemiyorum. Derleyici olsa gerek.
Maalesef konu proton olunca elim kolum bağlanıyor.
Ete


Hattuşa

hocam basicte yapamazmısınız? yapmaya çalıştığım T1CKI de çalışan TMR1 sayıcısının taşması durumunda kesmeye götürüp, sayıcının taşmamasını sağlatmak. bu arada PBP da oluyormu bilmiyorum ama protonda zaman zaman derleyici saçma kodlar üretiyor. bunun sebebini bulamadım ama bazen yaşıyoruz bu sorunu yoksa yazdığım kodda hatanın olmadığını düşünüyorum.

ete

Programını PBP ya çevirdim. Senin program kesinlikle kesmeye girmiyor. Benimki aynı kod olmasına rağmen giriyor.

İşin mantığını çok iyi anlamadım. Kodda bazı değişiklikler yaptım olması gereken değişiklikler ama sıhhatli çalışmıyor bu mantık.
@ __config _BODEN_ON & _BOREN_ON & _CP_ON & _PWRTE_ON & _WDT_ON & _LVP_OFF & _MCLRE_OFF & _INTRC_OSC_NOCLKOUT 
DEFINE OSC 4       
CMCON=7
PORTA=0:portb=0
TRISB =%01000000 
TRISA=0

' Define LCD registers and bits
Define LCD_DREG  PORTB
Define LCD_DBIT  0
Define LCD_RSREG PORTB
Define LCD_RSBIT 5
Define LCD_EREG  PORTB
Define LCD_EBIT  4
DEFINE LCD_BITS 4 'LCD bus size 4 or 8
DEFINE LCD_LINES 2 'Number lines on LCD

OPTION_REG =%10010101
Symbol T0IF = INTCON.2 ' TMR0 Overflow Interrupt Flag
Symbol T0IE = INTCON.5 ' TMR0 Overflow Interrupt Enable
Symbol GIE = INTCON.7  ' Global Interrupt Enable
Symbol PEIE = INTCON.6 ' Peripheral Interrupt Enable
Symbol TMR1IE =PIE1.0
Symbol TMR1IF =PIR1.0
GIE =0
T0IF =0
T0IE =1
TMR1IE =1
TMR1IF =0
PEIE =1
T1CON =%00000011

ON INTERRUPt GOTO KESME
Fr VAR Word
FrQ VAR word
FrSeC VAR Word
SaY VAR Byte
SaYaC VAR Byte

TMR0 =99  '10 ms
LCDOUT $fe,1:pause 200

Fr =0
FrQ =0
TMR1L =0
TMR1H =0
SaY =0
SaYaC =100
LCDOUT $fe,$80,"OKUNAN FREKANS"

GIE =1

MaIn:
If SaYaC =1 Then  FrQ =Fr /10
If SaYaC =10 Then FrQ =Fr /100
If SaYaC =100 Then FrQ =Fr /1000

lcdout $fe,$c0,Dec FrQ,"Khz   ",Dec SaYaC," "

GoTo MaIn


disable
KeSMe:
    If TMR1IF =1 Then
       sayac=sayac/10
       If SaYaC =0 Then SaYaC =100
       PORTA.2 =1
       TMR1IF =0:TMR1L =0:TMR1H =0
       SAY=0
       goto CIK
    EndIf

     TMR0 =99
     SaY=SaY+1
     If SaY =SaYaC Then
        Fr.LowByte =TMR1L
        Fr.HighByte =TMR1H
        TMR1L =0
        TMR1H =0
        porta.2=0
        If Fr >=1001 Then
          SaYaC =10
        Else
          SaYaC =100
        EndIf
        SaY =0
     EndIf
     T0IF =0

CIK:
resume
enable
End


Hattuşa


hocam mantık şu (yanlış düşünüyor olabilirim)

şimdi elimdeki frekans kaynağım 1 hz ile 540 khz arası ve ben bunu okuyup ekrana yazdırmak istiyorum.
T1CKI ile harici kaynaktan puls saydırarak frekansı ölçümlemeye çalışıyorum. malum t1CKI puls saayarken TMR1 sayacını kullanıyor ve 16 bit çözünürlülükte yani 0-65535 değerini alıyor TMR1L ve TMR1H sayacımız. elimdeki mevcut frekansın aralığı çok geniş malum 1-2hz oldukça düşük, 1-2 hz i sayabilmek için  enaz 1000mS T1CKI yi dinlememiz gerekiyor. ki sizinde bahsettiğiniz gibi 1 hz demek 1000 mS de bir puls,
şimdi ben TMR0 ile 10mS lik bir zaman oluşturdum. bunuda 100 ile çarpınca 1000mS lik süreyi elde ettim.
TMR0 =99
     SaY=SaY+1
     If SaY =SaYaC Then

TMR0 =99 bu 10 ms lik oluşturulan zaman, say =say +1 ile de ben zamanı 1000mS yeye çıkaarmak için kullandım.  buraya kaadar sorun yok yani çok hassas olmaasa da tuttuğum zaman denk geliyor. 1000mS de 1hz-50 khz arası okuma yapmak TMR1 için sorun teşkil etmiyor. ancak 50khz üzerine çıktığım zaman 1000mS de misal 70 khz de 1 sn deki puls miktaarı 70,000 oluyor bu seferde TMR1 değeri taşma yaapıyor ve saçmalıyor.

ben burada TMR1 değeri taşma yaptığında tuttuğum zamanı kısaltaarak taşmayı önlemek, bunun içinde TMR1 kesmesini aktif edip taşma oluştuğunda 1000mS yeyi 10mS veya 1Ms yeye çekmeye çalışıyorum.

belki dışardan bir switch veya butonla manuel bir seçim yapmak işleri kolaylaştırır ama bunu yazılımla yapmak istiyorum. elimizdeki ölçü aletlerinde 10 mhz e kadar ölçüm yapıyor bunu yapanlar nasıl yaapıyor acaba?

hocam çokmu imkansıza zorluyoruz?

not: klavyem bozulunca ucuz kablolu bir klavye aldım oda kafasına göre harfleri fazla fazla basıyor. bu durum için özür dilerim.



ete

Öncelikle frekansların ölçüm sınırları nasıl hesaplanır ona bakalım istersen.
TMR1 sayacını dışarıdan tetiklemeli olarak kullanıyoruz.
1000 ms (1sn) zaman tutuyorum. TMR1 sayacını 1/1 bölme oranı ile saydırıyorum.
Bu durumda en fazla 65.535 saydırabilirim. Bu ise yaklaşık 65Khz'e eşdeğerdir.
Şayet TMR1 sayacını 1/2 bölme oranı ile saydırırsam 65x2=130 Khz 'e kadar ölçüm yapabilirim demektir.
1/4 bölme oranı ile saydırırsam 65x4=260 Khz ölçebilirim.
1/8 bölme oranı ile saydırırsam 65 x 8=520 Khz saydırabilirim demektir.
Gördüğün gibi sadece bölme oranı ile oynayarak sabit zaman tutarak 65Khz - 520 Khz aralığını saydırabilirim.
Şimdi zaman ile oynayarak bu sayıları biraz daha katlamak mümkün.
1000 ms yerine 500 ms zaman tutarsam ve sonucu 2 ile çarparsam sayma aralığım 1040 khz'e kadar çıkar.
Biraz daha düşürür ve 250 ms zaman tutar ve sonucu 4 ile çarparsam 2 Mhz saydırabilirim. Saydırabilirim derken bunların hesapları artık kritik noktalara dayanır ve biraz karmaşık 32 bit hesaplar gerektirir.

Kullandığın mantığı anlıyorum. O kadarını bende çözmüştüm zaten. Ancak diyelimki 540 Khz ölçüyorsunve birden sinyal 10Khz'e düştü sen SAYAC değerini 100 yapman gerekir bunu program nasıl anlayıp da yapacak?

Diğer taraftan T1CON da bölme oranını 1/2 verdiğin için hesaplama şeklinde yanlış bence.
If SaYaC =1 Then  FrQ =Fr /10
If SaYaC =10 Then FrQ =Fr /100
If SaYaC =100 Then FrQ =Fr /1000
şeklindeki satırların ;
If SaYaC =1 Then  FrQ =Fr /20
If SaYaC =10 Then FrQ =Fr /200
If SaYaC =100 Then FrQ =Fr /2000
şeklinde olmalı bence.

Ayrıca TMR1 kesmesi oluştuğunda;
       TMR1IF =0:TMR1L =0:TMR1H =0 :SAY=0
değerlerinide sıfırlaman gerekir. Aksi halde anlamsız sayılar bulursun.

Bu mantığı pek sevmedim. Her şeyden önemlisi sonucu geç alabiliyorsun.  Üstelik net 10ms yada 100 ms süre tutamadığın için sonuç komut gecikmelerinden dolayı biraz beklenenden fazla çıkıyor.
Maalesef daha iyi bir mantık da aklıma gelmiyor. Oruç tutunca beyin faaliyetlerim çok yavaşlıyor. Ramazandan sonra belki bir şeyler düşünürüm.

Ete

Hattuşa

cevap için tşk ederim hocam TMR1 sayacının bölme oranları ile oynamayı akıl edemedim açıkcası, şimdi birazda kafayı ona yorayım.

Hattuşa

ETE hocam şöyle bir uygulama yaptım gerçekte denemeyi düşünüyorum zira artık gitmiyor
KeSMe:
Context Save
   TMR0 =3
Fr.LowByte =TMR1L
Fr.HighByte =TMR1H
TMR1L =0
TMR1H =0 
FrS =FrS +Fr
Inc SaY
If SaY =100 Then
SaY =0
FrD =FrS
FrS =0


EndIf
T0IF =0

Context Restore



TMR0 kesmesini 10 ms yeye ayarladım. her kesme oluştuğunda float bir değişkene T1CKI den gelen puls sayısını toplayarak attım. 1000mS ye ye denk gelen 100. kesmede de float değişkendeki değeri başka bir değişkene atıp değerleri sıfırladım. ana programda da bu değişkeni frekans değeri olarak işlem yaparak gösterdim. Artık 1 sn lik aaraalıktaa da olsa frekansı 1 hz ile 600 khz arasını okuyabilirim diye düşünüyorum. işi basite kaçırınca bu kadar oluyor sanırım. umarım yeterli gelir

ete

Simulasyonda çalışıyorsa işini görür.
Ete

er-da

100 ms  de   100kHz frekanstaki 1Hz lik değişimi sağlıklı olarak ölçebilirmiyim..hangi yolla a) duty on / off süresini ölmekle    b)bir zaman süresinde(100mS) pals saydırmak ...?

ete

100 ms de 100Khz lik sinyali puls sayarak ölçebilmek daha akıllıca olur. Zira 10.000 sayarsın ve böylece bunn 10 katı sana doğru puls miktarını verir. Peryot ölçersen 10us lik bir peryot ölçmen gerekecek. Duty %50 ise 5ms LOW 5ms HIGH süresi ölçemn gerekecek ki buda ölçülebilecek küçük bir değer olarak gözüküyor. Ancak yüksek frekanslarda çalışan bir pic ile bu iş sağlıklı yapılabilir. Bütün bu dediklerim frekans stabil ise geçerli tabiiki değilse 100 ms yerine 1000 ms zaman tutmak daha uygun olacaktır.

Ete

er-da


Powered by EzPortal