avatar_Mucit23

Timer1 ile Devir ölçümü

Başlatan Mucit23, 04 Kasım 2012, 00:10:16

Mucit23

Merhabalar Arkadaşlar ve değerli Ete hocam..

Bi motor kontrol sistemi üzerinde çalışacağım. Tekerlekli araç motorunu kontrol etmem gerekiyor. Kontrol olayında bir sıkıntım yok fakat farklı bir çalışma yapmayı planlıyorum. Bu iş için motorun devrini ölçmem gerekiyor. Bir yerden başlayayım dedim az önce motor devrini ölçmek için işlemcinin timer1 sayacını kullanarak frekans ölçmeye çalıştım.


image

Resimdeki gibi timer1'in clock input bacağına dışarıdan clock sinyali uyguladım. Bu şekilde gelen clock sinyallerini saydırdım. Daha sonra Timer0 kesmesini kurup her 1 sn de bir timer1 sayacını okudum.
Şimdilik devir hesaplamıyorum. Frekans hesaplamaya çalışıyorum ama bir türlü timer0 kesme süresini doğru düzgün ayarlayamadım.

bende şöyle bir yöntem uyguladım. clock sinyalinin frekansını 50Hz olarak ayarladım. Daha sonra timer0 sayaıcısının değerleriyle ve kesme içerisindeki sayacın değerleriyle oynarayak ekranda 50 değerini görünceye kadar ayarlama yaptım. Her neyse Ekranda istediğim değeri görünce frekansı 100Hz çıkarıp denediğimde bu sefer ekranda 200hz in üzerinde bir rakam gördüm. Bu durum iyice kafamı karıştırdı.

Yazdığım kodlar şöyle hocam
'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2012 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 24.10.2012                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
DEFINE OSC 4
@  __config _XT_OSC & _WDT_ON & _PWRTE_ON & _LVP_OFF & _CP_OFF
TRISA=0:PORTA=0
TRISB=0:PORTB=0
TRISC=0:PORTC=0

ADCON1=7
OPTION_REG=%00000101
INTCON=%10100000
TMR0=100
T1CON=%00000111
ON INTERRUPT GOTO KESME
TMR1H=0:TMR1L=0

DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 3
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 2
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2

SAYAC VAR WORD
SNS   VAR BYTE

PAUSE 200
LCDOUT $FE,1
BASLA:

LCDOUT $FE,$80,"SAYAC=",DEC4 SAYAC

GOTO BASLA

DISABLE
KESME:

SNS=SNS+1
IF SNS=61 THEN
  SNS=0
  SAYAC.HIGHBYTE=TMR1H
  SAYAC.LOWBYTE=TMR1L
  TMR1H=0:TMR1L=0
ENDIF

TMR0=100
INTCON.2=0
RESUME
ENABLE


Şuanda okuma aralığı 1sn nin dışında olabilir. Değerleri çok değiştirdim çünkü. Nerede hata yapıyor olabilirim sizce. gerçekte 5-10 ms aralığında ölçüm yapacam. Bu hataları şimdiden çözmem gerekir.
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

Erata

#1
asagıdaki gibi bir denermisin  basic kullanmıyorum o yuzden deneyemedim

sendeki timer 0  ayarları yanlış gibi geldi bana

asagıdaki haliyle  (1000 ms)  1 saniyedeki pals sayılacak  yani counter resulation 1 Hz.  olması gerek  ve lcd de  50 Hz görmen gerek


birde isisde pic i 4 mhz ayarladığından emin ol ilk eklendiğinde pic 1 mhz oluyordu yanlış hatırlamıyorsam






DEFINE OSC 4
@  __config _XT_OSC & _WDT_ON & _PWRTE_ON & _LVP_OFF & _CP_OFF
TRISA=0:PORTA=0
TRISB=0:PORTB=0
TRISC=0:PORTC=0

ADCON1=7
  OPTION_REG = 0x85    ' Prescaler 1:64;  TMR0 Preload = 97;  Actual Interrupt Time : 9,986 ms yaklasık 10 ms

  TMR0       = 97
  INTCON = 0xA0

T1CON=%00000111
ON INTERRUPT GOTO KESME
TMR1H=0:TMR1L=0

DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 3
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 2
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2

SAYAC VAR WORD
SNS   VAR BYTE

PAUSE 200
LCDOUT $FE,1
BASLA:

LCDOUT $FE,$80,"SAYAC=",DEC4 SAYAC

GOTO BASLA

DISABLE
KESME:

SNS=SNS+1
IF SNS=101 THEN
  SNS=0
  SAYAC.HIGHBYTE=TMR1H
  SAYAC.LOWBYTE=TMR1L
  TMR1H=0:TMR1L=0
ENDIF

TMR0=97
INTCON.2=0
RESUME
ENABLE


ete

Biraz kestirmeden gidiş yapmışsın gibime geliyor.
Frekans saydırmanın en temel yollarından birisi zaman tutup gelen pulsleri saydırmakır.
Kullandığımız sayaclar limitli olduğundan dolayı saydırılacak frekansta sayacların alabilecekleri dwğerleri önceden irdelemek gerekiyor. Örnek verecek olursak;
Kaynak frekansı 50 hz olan bir sinyali 1000 ms içinde sayarsak 50 saymamız gerekir. Bu dwğer tmr1 sayacı sınırları içindedir. Hatta bölme oranı 1/1 bile alınsa yeterlidir.
Bu durumda sayac bizim 65535 hzlik frekansları bile saymamıza yeterli gelecektir.
İşin bu kısmında sorun olmadığını düşünüyorum.
Sorun bence tuttuğun tmr0 zamanında.
Sana 1.000.000 us lik bir süre gerekiyor.
1/64 bölücü kullnmışsın. Tmr0 ra hiç bir ön değer yüklemez isek ,
Her 256 çevrimde bir kesme oluşturacaktır. 64 e bölerek kullanınca 256 x64=16384 us de bir kesme oluşturur. 1.000.000/16384=61 adet net kesme gereklidir. Bu değer ideal hesap olup komut gecikmelerinden dolayı rakam düşebilir. Kesme etiketind gelen kesmeleri sayıyorsun net 61 kesme için kesme değeri 62 olduğunda tmr1 değerini okumalısın.
Peki bu anlattıklarıma karşılık sen ne yapmışsın. ?
Tabiiki Tmr0 için ön yükleme kullanmışsın. Bu durumda tuttuğun zaman hesabı şöyle olacaktır.
Tmr0 256-100=156 saymada bir kesme oluşturacak.
156 x 64 =9.984 us her kesmede geçen süre olacak.
Sen 60 kesme de bir değer almışsın ohalde 60 x9984= 599.040us lik bir zaman tutmuş oluyorsun. Neredeyse tutman gerekenin yarısı.
Programda tmr0=100 ifadelerini kaldır ve kesme kısmında kesme sayacı 61 değilde 62 olunca tmr1 değerini al bakalım sonuç ne oluyor.
Ete

Mucit23

Ben picmulticalc programına göre yapmıştım ama hata yapmışım anlaşılan. Neden böyle yaptığımıda bilmiyorum. Anlamadım gitti. Her neyse dediğiniz gibi yapınca düzeldi.

Tmr1 sayacında ise  boyut problemi olacağını pek sanmıyorum hocam zaten şimdilik 10ms aralıklarla sayac değerini okuyacam. Bu sürede sayacın içeriğinin dolması için nerden baksanız 6mhz clock frekansı uygulamam gerekirki bu mümkün değil.

Devir okuma yöntemi pek aklınıza yatmadığını düşünüyorum. Bildiğiniz daha iyi bir yöntem varmı?
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

ete

Bu güne kadar pek çok devir ve frkekans ölçen alet yaptım. Devir birimi dev/dak cinsindenbelirlendiği için hassas ölçümlerin mutlaka dakika bazında zaman tutularak yapılması gerekir.  alternatif yol ise puls genişliğinin ölçülerek  frekans bilgisine ulaşılması şeklinde oluyor. Bildiğiniz üzere FREKANS=1/T dir. T burada perodu belirliyor. Peryod ise high ve Low pulslerinin toplamıdır. O halde gelen sinyalin bu peryotlarını toplarsanız belkide daha hassas bir frekans bilgisine sahip olabilirsiniz.
Bu yöntemide kullandım ve düşük devirlerde daha hassas sonuçlar aldım diyebilirim.

Ete

Mucit23

Teşekkür ederim hocam. Sanırsam iki pals arasındaki süreyi ölçerek ölçüm yapsam dediğiniz gibi düşük devirlerde daha iyi bir sonuç alırım. Bakayım ikisinide test edeceğim
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

Mucit23

Hocam selamlar. Yine buna benzer bir problemim var.

628 ile devir ölçmeye çalışıyorum. Yaptığım iş 1 sn içerinde timer1 ile gelen puls'ları sayıp elde ettiğim bu sayıyı 60 ile çarpıp ekrana yazıyorum. Fakat çözünürlüğüm çok düşük oluyor.

Örneğin Timer girişine 1hz uygulasam 60rpm olarak ekranda görüyorum. Frekansı 2Hz'e çıkartıyorum devir sayısı 120 oluyor normal olarak. Fakat frekansı 1.5Hz yapsam bu sefer devir sayısı 60-120 arasında değişiyor.

Timer yöntemi hassasiyeti düşürüyor.  Benim iki puls arası süreyi ölçmem gerekiyor. Bunuda CCP donanımı ile yapmak istiyorum. Daha önce bu donanımı pwm özelliği dışında kullanmadım. Ete hocam sizin bu konuda bir çalışmanız oldumu? Ne yapmam gerekiyor?

Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

ete

#7
Mucit,
Bu konuda bir iki denemem olmuştu ama şimdi hem nasıl olduğun pek hatırlamadım hemde yaptığım çalışmaları bulamadım.
Malum büroda başka bilgisayar evde başka bilgisayarım var. Evdekinde olmadığına göre büroda olmalı. Ancak şu anda Ankara dışında bir yerde işim var her gün oraya gidip geliyorum. Hafta içinde büroya uğrayabilirsem bakarım. Değilse bir ara data sheet incelemesi ile yeniden bakarım nasıl olduğuna.

Bu mesajı yazdım ama sonradanbir çalışma buldum, Aşağıda veriyorum. İnceleyecek vaktim yok senbak istersen işine yararsa en azından mantığı öğrenirsin.
@ DEVICE pic16F628A                      'işlemci 16F628                                
@ DEVICE pic16F628A, WDT_Off              'Watch Dog timer açık
@ DEVICE pic16F628A, PWRT_ON             'Power on timer açık
@ DEVICE pic16F628A, PROTECT_OFF         'Kod Protek kapalı
@ DEVICE pic16F628A, MCLR_off            'MCLR pini kullanılMIYOR.
@ DEVICE pic16F628A, HS_OSC 'INTRC_OSC_NOCLKOUT  'Dahili osilatör kullanılacak 
CMCON=7
define OSC 10
PORTA=0:TRISA=%00000000
PORTB=0:TRISB=%00001000

T1CON=%00000001
CCP1CON=0

SURE VAR WORD 56
DEVIR VAR WORD 58
ILK   VAR WORD 60
IKINCI VAR WORD 62
TEMP  VAR WORD 64
FREQ  VAR WORD 66
SYMBOL FLAG=PIR1.2
SYMBOL KESME=PIE1.2

PAuse 500


BASLA:
        TMR1L = 0                               
        TMR1H = 0               
        CCP1CON = %00000101                   
        KESME = 0                             
        Flag = 0                               
        KESME=1
        While Flag=0:Wend               
        ILK.LowByte=CCPR1L
        ILK.HighByte=CCPR1H 
        CCP1CON = %00000100                   
        Flag=0                             

        While Flag=0:Wend               
        IKINCI.BYTE0=CCPR1L
        IKINCI.BYTE1=CCPR1H
        SURE=IKINCI - ILK   
        CCP1CON = %00000101
        Flag=0   
         TEMP=IKINCI+ILK


'      FLAG=0  'kesme bayrağı sıfırlanıyor
'      KESME=1
''      T1CON=%00000001       '5-4 bitler 00=1/1 , 01=1/2  , 10=1/4  , 11=1/8 bölme oranı T1 için
'      CCP1CON=%00000101  'yükselen kenarda kesme     
'      WHILE FLAG=0:WEND
'      T1CON=%00000001
'      TMR1L=0
'      TMR1H=0       
'      CCP1CON=%00000100  'düşen kenarda kesme
''      KESME=0
'      FLAG=0
''      KESME=1
''      PIR1.0=0     

'      WHILE FLAG=0:WEND
'      T1con=%00000000
'      SURE.Byte0=TMR1L
'      SURE.Byte1=TMR1H
       IKINCI=(IKINCI*/1024)/10000
      sure=(sure*/1024)/10000
      devir=(1000/sure)*60
      freq=1000/(IKINCI)
     
'      IF PIR1.0=1 then
'         T1CON=%00000001
'         KESME=0
'         PIR1.0=0
'         GOTO BASLA
'      ELSE
'         T1CON=%00000001         
'       ENDIF 
'      sure=sure+1
      kesme=0   
      pause 100
      goto basla


Ete

gergy

Ete hocam daha iyi bilir ancak, CCP metodu ile de timer metodu ile aldığınıza benzer sonuç alırsınız düşük frekanslarda. Bu arada darbe periyodunu ölçmeye yönelik uygun bir örnek vermiş ETE hocam. Yine de açıklamak gerekirse darbe periyodunu ölçmek için Timer1 taşma olmayacak şekilde prescalerı ayarlanır, CCP1CON yazmacında önce yükselen kenar için kontrol bitleri ayalanır (CCP1CON = %00000101), Capture kesmesi aktive edilir (CCP1IE--> PIE1.2 biti). Kesme oluşunca Timer1 değeri darbe başlangıç zamanı olarak kaydedilir, akabinde CCP1CON yazmacı düşen kenar için ayarlanır (CCP1CON = %00000100). Kesme oluşunca Timer1 değeri darbe bitiş zamanı olarak kaydedilir ve bu değerden başlangıç değeri çıkarılarak darbe periyodu hesaplanır. Ancak eğer Ete hocanın verdiği örnekteki gibi ana döngüde bu işlemleri yapacaksanız ki özellikle CCP1CON yazmaç değerlerinin değişiminde kesmelerin kapatılıp açılması ve bayrakların sıfırlanması önem arz ediyor, keza yazmaç değerlerinin değişmesi kesme oluşturabiliyor. Öbür türlü bu işlemler kesme rutini içinde yapılırsa zaten kesme başlangıcında kesme kapatıldığından örnekteki gibi ana döngü deki kesmeyi kapatma işlemlerine gerek kalmıyor. Ayrıca verilen örnekteki programda kesme bayrağı beklendiğinden; örneğin 500 ms'lik bir darbe için ana döngüde en az 500 ms beklenmesi gerekiyor ki bu pek de istenen bir durum olmayabilir, o süre zarfında yapılacak başkaca işlemler açısından kesme rutini içinde ilgili işlemler yapılırsa daha verimli olur düşüncesindeyim. İlgili işlemlerden kastım yazmaç ayarlama, değişkenlere timer değerlerinin yüklenmesi, bayrak sıfırlama CCP1IF (PIR1<2>) ve ilk ve son değer saptanması işlemleridir, süre ve devir hesabı vb. ana döngüde yapılır zaten.

Mucit23

Aslında puls genişliği ölçmek benim işime yaramıyor. Zira bu yöntemi hatalı çalışacağını düşünüyorum. Çünkü devir sinyalini herhangi bir motor miline yapıştırılmış beyaz bant üzerinden alacağım. Motorun her bir turunda beyaz bandı gördüğüm zaman pic mikroişlemciye lojik1, beyaz band dışında lojik0 göndereceğim.

Şimdi puls genişliğini ölçmek mutlaka işe yarar ama puls genişliği motor miline yapıştırılan bandın genişliği ile doğrudan ilgili olduğu için işimi zorlaştırır diye düşünüyorum. Bu yüzden puls genişliğinden ziyade motor milinden aldığım sinyalin peryodunu ölçmem gerekiyor.

Bunuda şöyle yaparım diye düşündüm. CCP kesmesini yükselen kenarda oluşacak şekilde kuracağım. Ayrıca timer1'i de her 1 ms aralıklarla kesme oluşturacak şekilde ayarlayacağım. Sonra ccp kesmesi oluştuğunda bir bayrağı aktif edeceğim. Tekrar CCP kesmesi oluştuğunda bayrağı 0 yapacağım. Timer1 interrupt rutini içerisinde ise bu bayrak 1 ise her kesme oluştuğunda bir sayacın değerini arttıracağım. Bayrak 0 olduğunda ise sayacın değerini alacağım. Bu sayacın değeri benim doğrudan peryodum dur.

sayacın değeri ms cinsinden olduğu için devir=(1000/sayac)*60 şeklinde bir formül ile devri hesaplarım diye düşünüyorum. Akşam hemen deneyeceğim.
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

gergy

#10
Hocam o zaman da oluşan kare dalganın periyodunu ölçeceksiniz ki kurduğunuz mantık doğru, hatta 4. veya 16. edge özelliği sayesinde ortalama bile alma şansınız olacaktır. Pratik bir çözüm göstermek adına, ortalama almadan yapacak olursanız;  Timer1 olası en yüksek periyotta taşma olmayacak şekilde prescalerı ayarlanır, CCP1CON yazmacında yükselen kenar için kontrol bitleri ayarlanır (CCP1CON = %00000101), Capture kesmesi aktive edilir (CCP1IE--> PIE1.2 biti). Bu arada sizin dediğiniz şekilde istenen periyotta timer1 taşma kesmesi oluşunca bir değişkenin değeri (örn. Timer1_32) bir attırılır (32 bit sayıcı, malum Timer1 sadece 16 bittir). Bu her timer1 taşma kesmesinde bir arttırılan değer, timer1 için 32 bitlik sayma amacına hizmet edecektir. Capture için kesme oluşunca önceki okuma değeri bir başka değişkene aktarılır, sonra Timer1_32 değeri bir dword değişkenin 3. ve 2. byte değerlerini oluşturacak şekilde atanır ve timer1'in mevcut değeri de ilgili dword değişkenin 0. ve 1. byte'ı olarak atanır. Özetle 32 bitlik timer1 değeri ilgili 32 bitlik değişkene atanmış oluyor. Bu değerden bir önceki kaydedilen değer çıkarılarak kare dalganın periyodu hesaplanır. Fikir vermesi açısından kesme kısmı için bir örnek ekledim:


KESME:
If TMR1IF == 1 Then                    ' Timer1 taşma kesmesi
    Inc Timer1_32                         ' 32 bit sayıcının high word kısmını arttır
    Clear TMR1IF
EndIf

'CAPTURE kesmesi, devir sensörünün algılanması için 
If CCP1IF == 1 Then                    ' Capture kesmesi
    TimerSon = Capt                      ' Son okunan (bir önceki capture'da okunan) değeri TimerSon değişkenine yükle

    Capt.Byte3 = Timer1_32.HighByte    ' Yakalanan kare dalganın periyodunu
    Capt.Byte2 = Timer1_32.LowByte     ' 32 bit olarak Capt değişkenine yükle
    Capt.Byte1 = CCPR1H
    Capt.Byte0 = CCPR1L
   
    Clear CCP1IF
    Clear TMR1IF

End If



Capt-TimerSon farkı size kare dalganın periyodunu verecektir, frekans veya devir için formülü zaten siz çıkartırsınız :)

gergy

Yalnız bir şey eklemeden geçemeyeceğim, çok düşük devir değerlerinde daha düzgün sonuç alabilmek için frekans çarpanı gerekir, örneğin basit bir çözüm nand kapısı (örn. 4011) ile frekans çiftleyici olabilir. 1 hz'lik bir sinyali 2 veya 4 yaparak daha hassas veya sizin tabirinizle yüksek çözünürlüklü sonuçlar elde etmeniz mümkün olur.

Mucit23

Evet bahsettiğim yöntemle yaptım. Proteusta denedim oldu gibi. Güzel çalışıyor. İlk başta Pic16F628'in 4Mhz Dahili osilatörü ile denedim. Düşük frekanslarda 0.5hz ile 20hz arası çok güzel çalıştı. Fakat frekansı yükselttikçe işlemci yetişemedi. Bende harici 20Mhz osilatör bağladım.

Ayrıca timer kesmesini 1ms aralıklarla oluşturuyordum. Düşük frekanslarda bu değer iyi çalışıyordu fakat frekans yükseldikçe baktımki 1ms yetmiyor. Bende 100us aralıklarla kesme oluşması sağladım.Sonra 4Mhz de 100us lik kesmeler işlemciyi çok yoruyordu ama 20Mhz de iyi oldu. Hatta çözünürlük yine yetmezse kesme oluşma süresini 50us yada 10us yapacağım. Timerin oluşma sıklığı doğrudan alınan ölçümün çözünürlüğünü etkiliyor.

Yazdığım kodlar bunlar.

#include <16F628A.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //Internal RC Osc, no CLKOUT
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(clock=20000000)

#use fast_io(a)
#use fast_io(b)

#include <lcd_driver.c>

static float frequency=0,rpm=0;
static int16 period=0,period_counter=0;
static int1 ccp_flag1=0,ccp_flag2=0;

//****************** Timer1 Kesmesi *****************************
#int_timer1 // Timer1 kesmesi
void Timer1_isr()
{
set_timer1(65067);

  if(ccp_flag1)
  {
    period_counter++;
  }
  if(ccp_flag2)
  {
    period=period_counter;
    period_counter=0;
    ccp_flag1=0;ccp_flag2=0;
  }

clear_interrupt(int_timer1);       
}

#int_ccp1
void ccp1_isr()
{
  if(ccp_flag1)ccp_flag2=1;
  ccp_flag1=1;
  clear_interrupt(int_ccp1); 
}

void main()
{
  set_tris_a(0x00);
  set_tris_b(0x08);
  output_a(0x00);
  output_b(0x00);
 
  setup_ccp1(CCP_CAPTURE_RE);
  setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  set_timer1(65043);
  enable_interrupts(INT_timer1);
  clear_interrupt(INT_CCP1);
  enable_interrupts(INT_CCP1);
  enable_interrupts(GLOBAL);

  lcd_init();
 
  lcd_gotoxy(1,1);

   while(TRUE)
   {
      frequency=(float)10000/period;
      rpm=frequency*60;
      lcd_gotoxy(1,1);
      printf(lcd_putc,"Freq=%.1fHz ",frequency);
      lcd_gotoxy(1,2);   
      printf(lcd_putc,"Hiz = %.1fd/dk ",rpm);     
     
   }

}

@gergy
Yaptığım ölçümü daha nasıl iyileştirebilirim?

Başka bir sorum daha olacak. Devir ölçmeyi unutalım frekans ölçmeye çalışıyoru. 0.5Hz ile 1000Hz arasını olabilecek en hassas şekilde ölçmek istersem hangi yöntemi uygulamam gerekir? Yine periyot ölçmeye çalıştığımızı düşünelim.



Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

gergy

#13
Hangi yöntemi derken tam olarak anlayamadım??? Ete hocamızın dediği gibi zaten iki yöntem var, ya belli bir zaman aralığındaki darbeleri saymak ya da darbe genliğini ölçmek. Siz zaten yine periyot ölçmeyi seçince darbe genliği ölçümünü zaten yöntem olarak seçmiş oldunuz. Kastettiğiniz başkaca bir husus varsa açmanızı rica edeceğim.

Bunların dışında, eğer ccp ile nasıl bir yöntem izleyeceğimizi soruyorsanız, üzerinde son olarak konuştuğum yöntem bence uygundur, ancak düşük frekanslarda direk periyodu ölçmek en hassas sonucu verecek iken yüksek frekanslarda hem gürültüyü azaltmak hem de program akışını fazla kesintiye uğratmamak (sizin tabirinizle işlemciyi çok yormamak) adına 4th edge ya da 16th edge kullanılabilir. Yalnız minimum 0.5 Hz ölçecekseniz çözünürlüğünüz otomatik olarak zaten 0.5 Hz olmuş oluyor ki periyodunu ölçmek 2 sn alacaktır. Bu kadar beklememek için yapılabilecek olan önceki mesajımda bahsettiğim gibi frekans çarpanı kullanmak olabilir. Ancak bu sefer de yüksek devirlerde sıkıntı olmaması için belli bir frekans değerinin üzerinde 4th edge ya da 16th edge geçiş yapılarak yavaşlama sorunu çözülebilir. Benim yukarıda bahsettiğim şekilde örneğin 20 MHZ kristal için timer1 1:8 prescaler için 1.6 us periyotla çalışacaktır, 16th edge için bu periyot 25,6 us olacaktır. Bu da yüksek frekansları ölçmek için bence yeterli hassasiyeti verecektir. Bunun dışında benim aklıma başkaca bir şey gelmiyor, Ete hocamızın daha iyi fikirleri ve açıklamaları olacağına eminim.


ete

Bu günlerde bir makina söküm işi ile uğraşıyorum ve 1 hafta daha işim var. Bu aralıkta yalnızca mesaj okuyup kısa cevaplı olanlara telefonla cevap vermeye çalışıyorum. Bu konuda uzun boylu düşünecek vaktim yok.Zaten önceden de belirttiğim gibi ya darbe saymak yada peryod ölçmek eldeki imkanlar. Bunlardan hangisi uyuyor ise onu kullanmak gerekir. Bu iki alternatifin varyasyonları var onlarıda deniyorsun öyle gözüküyor. Sonuç olarak bulunanlara ekleyeceğim başka bir şey yok maalesef.

Ete

Powered by EzPortal