karedalga (pulse) hesaplama pic16f877

Başlatan ismailhtc, 06 Aralık 2013, 10:01:59

ismailhtc

     Arkadaşlar saniyede sayısı belli olmayan ama maksimum 150 darbe gelebilecek bi debimetrem var. ben bu debimetrenin kaç tane darbe ürettiğini hesaplıyacağım. aynı zamanda son bir saniye kaç darbe geçtiğinide hesaplıyacağım.

   Kodlarım aşağıdadır fakat anlamadım nokta 1 sn  süreyi belirlemede sıkıntım var. toplam darbe miktarını saymak için timer0 kesmesi kullandım. 1 sn yi hesaplamak içinde timer1 diye düşündüm. Ama hakim olamadım isiste kesmenin birinde duruyor orada kalıyor. sayma işlemine devam etmiyor. Umarım sıkıntımı anlatabilmişimdir.

[IMG]http://imageshack.us/a/img542/6711/duni.png[/img]

Kodlar. acaba sıkıntı ne olabilir. timer1 zamanlamasını 1 sn olacak şekilde ayarlamaya çalıştım fakat o yanlış olabilir. yinede herhangi bi işlem yapmıyor. kesmelerde öncelik gibi bi sıkıntı da olabilir aslında. Teşekkürler
/******************************************************
*******************************************************/
#include <16f877.h>     // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.

// Denetleyici konfigürasyon ayarları
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD

#use delay (clock=20000000) // Gecikme fonksiyonu için kullanılacak osilatör frekansı belirtiliyor.

#use fast_io(a) //Port yönlendirme komutları A portu için geçerli

#define use_portb_lcd TRUE   
#include <lcd.c>   

float sayi=0; // Tamsayı tipinde değişken tanımlanıyor
float adeger=0 ;
float a=0 ;

//****************** Timer0 Kesmesi *****************************
#int_timer0  // Timer0 kesmesi
#int_timer1

void timer1_kesme ()
{
set_timer1(3036) ;
a=adeger ;
adeger=0;
}

void  timer0_kesme ()   // Kesme fonksiyonu ismi
{
      set_timer0(255);   // TMR0 değeri belirleniyor

       sayi=sayi+1;
       adeger=adeger+1 ;
      
}



/********* ANA PROGRAM FONKSİYONU********/

void main ( )
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı
   setup_CCP1(CCP_OFF);            // CCP1 birimi devre dışı
   setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı

   set_tris_a(0x10); // RA4 pini giriş
   while(1)   // Sonsuz döngü
   {

         
        lcd_init(); 
        printf(lcd_putc,"\fpulse=%.1f",sayi); 
        printf(lcd_putc,"\nnlik=%.1f",a); 
        delay_ms(150);
           


   setup_timer_0(RTCC_EXT_H_TO_L | RTCC_DIV_1); // Timer0 ayarları yapılıyor
   set_timer0(255);   // TMR0 değeri belirleniyor
   enable_interrupts(INT_timer0); // int_timer0 kesmesini aktif yapar
   enable_interrupts(GLOBAL);     // Aktif edilen kesmelere izin ver  
   
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
   set_timer1(3036) ;
   enable_interrupts(INT_timer1);
   enable_interrupts(GLOBAL);     // Aktif edilen kesmelere izin ver
   

 }
 }

Kabil ATICI

C olayını iyi bilmem, ama sen işleri baya karıştırmışsın gibi geldi...
anladığım kadar
Timer0 harici girişi kullanıyorsun ve dışarıdan gelen sinyalleri sayıyor
Timer1  1sn üretmek için kullanılıyor.

Buna göre senin timer0 (RA4 bacağı) için bir kesme yapmana gerek yok. Çünkü bu sayıcı olarak çalışıyor ve dışarıdan gelen sinyalle kendi otomatik sayar ve değerini günceller.

Timer1 zaten o bir zamanlayıcı

sen bir frekansmetre yapman gerekiyor bunun için hazır yapılmış örnekleri kullanabilir veya kendinde oluşturabilirsin.
timer0 girişi aktif et
timer1 başlat ve 1 sn bekle.
timer1 kesmesinde
timer0 girişini kapat.
timer0 sayac değerini oku
timer0 sayacını sıfırla
timer1 zamanlayıcısını kur
ve ilk baştaki işlemlere git.

sende aldığın timer0 değerini 1sn'lik zaman diliminde değerlendir.
Burada timer0 aslında bir sayıcıdır ve timer0 kesmesi diye birşeyi işe karıştırma çünkü o durum oluşmaz.. Ve oluşmaması gerekirde. O ancak timer0 zamanlayıcı olarak kullanıldığı zaman işe karışır.

Bu arada isis her zaman gerçek zaman (real time) çalışması vermeyebilir. Özellikle elemanlara analog olarak işaretli ise.
ambar7

erpay

B0 ve B1 de ki input değişimini ölçen kesmeleri kullanarak da sayabilirsin aslında.

ismailhtc

arakdaşlar sorunu hallettim

inter_timer0 kodunu yanlış yere yazmışım void_timer0_kesme bölümünün hemen üstüne yazınca çalıştı
#int_timer1

void timer1_kesme ()
{
set_timer1(3036) ;
a=adeger ;
adeger=0;
}

#int_timer0  // Timer0 kesmesi
void  timer0_kesme ()   // Kesme fonksiyonu ismi
{
      set_timer0(255);   // TMR0 değeri belirleniyor

       sayi=sayi+1;
       adeger=adeger+1 ;
      
}