18f452 ile devir sayma sorunu

Katılım
29 Nis 2010
Mesajlar
33
Puanları
1
Yaş
35
Arkadaşlar merhabalar.
18f452 ile bir döner mekanizmanın dakikadaki devir hızını ölçmeye çalışıyorum.
Ancak ölçümler sağlıklı gelmiyor.

20Mhz. Kristal kullanıyorum.
Ext kesmesi ve Timer1 kullanıyorum.
Ext kesmesi ile B0 portunda her değişimde x değişkenini bir artırıyorum.
Timer1 ile 104ms zaman oluşturup timer1 her kesmeye gittiğinde t1 değişkenini 1 artırıyorum ve t1 değişkeni 10 değerine ulaştığında (ki bu da yaklaşık 1 sn lik zaman çıkıyor) aktif x değişkeninin değerini alıp 60 ile çarparak dakikadaki devir hızını almaya çalışıyorum.

Ancak ölçümler esnasında sağlıklı sonuç çıkmıyor. Sanırım zamanlamada sorun oluyor.

Döner mekanizmanın devri her an değişebilir olduğu için sorun çıkıyor sanırım. Yani timer1 1 saniyelik turu tamamlarken B0 pinine gelen palsler arasında 1-2 pals kaçabiliyor. Bunu nasıl önlerim.

Kodlar aşağıda...

Kod:
#include "D:\deneme\ext_ve_timer.h"




#define LCD_ENABLE_PIN PIN_B5
#define LCD_RS_PIN PIN_B4
#define LCD_RW_PIN PIN_B6
#define LCD_TYPE 2
#include <lcd.c>

#device high_ints=true

#int_timer1 HIGH

int x,t1, devir;

#int_ext
void ext_kesmesi()
{
   x++; 
   set_timer0(1);
}

#int_timer1
void timer1_kesmesi()
{
   set_timer1(1);
   if (t1==10)
   {
      disable_interrupts(int_ext);
      devir=x*59;
      x=1;
      enable_interrupts(int_ext);
      t1=1;
   }
   else
   {
      t1++;
   }
}

void main()
{
   lcd_init();

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   setup_timer_2(T2_DISABLED,0,1);
   setup_ccp1(CCP_OFF);
   set_timer0(1);
   set_timer1(1);
   enable_interrupts(int_ext);
   enable_interrupts(int_timer1);
   enable_interrupts(GLOBAL);
   //TODO: User Code
   
   for(;;)
   {
      printf(lcd_putc,"\fSAYI:%u--%u--%u",devir, t1, x);
      delay_ms(50);
   }

}
 
gelen iki pulse arası zamanı ölçüp timer1 ile burdan yola devam etseniz nasıl olur...
 
Arkadaşlar merhabalar.
18f452 ile bir döner mekanizmanın dakikadaki devir hızını ölçmeye çalışıyorum.
Ancak ölçümler sağlıklı gelmiyor.

20Mhz. Kristal kullanıyorum.
Ext kesmesi ve Timer1 kullanıyorum.
Ext kesmesi ile B0 portunda her değişimde x değişkenini bir artırıyorum.
Timer1 ile 104ms zaman oluşturup timer1 her kesmeye gittiğinde t1 değişkenini 1 artırıyorum ve t1 değişkeni 10 değerine ulaştığında (ki bu da yaklaşık 1 sn lik zaman çıkıyor) aktif x değişkeninin değerini alıp 60 ile çarparak dakikadaki devir hızını almaya çalışıyorum.

Ancak ölçümler esnasında sağlıklı sonuç çıkmıyor. Sanırım zamanlamada sorun oluyor.

Döner mekanizmanın devri her an değişebilir olduğu için sorun çıkıyor sanırım. Yani timer1 1 saniyelik turu tamamlarken B0 pinine gelen palsler arasında 1-2 pals kaçabiliyor. Bunu nasıl önlerim.

Kodlar aşağıda...

Bana göre bu işin en güzel yöntemi gelen her pulse ile bir sayıcının değerini arttırıp her sn o değeri alıp sayıcıyı resetleyip ve bir kaç değer alarak sonrada ortalamasını 60 ile çarpmak daha stabil bir değer okumanızı sağlayabilir.
 
Kod:
#include "D:\deneme\devir.h"

#define LCD_ENABLE_PIN PIN_B5
#define LCD_RS_PIN PIN_B4
#define LCD_RW_PIN PIN_B6
#define LCD_TYPE 2
#include "lcd.c"

#priority ext,timer1

int t1;
unsigned int16 devir=0;
unsigned int16 x=0;
unsigned int1 tazele=0;
#int_ext
void ext_kesmesi()
{
   x++;
}

#int_timer1
void timer1_kesmesi()
{
   set_timer1(65536-62500);
   if (t1==9)
   {
      disable_interrupts(int_ext);
      devir=x*60;
      x=0;
      enable_interrupts(int_ext);
      t1=0;
      tazele=1;

   }
   else
   {
      t1++;
   }
}

void main()
{
   lcd_init();

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   setup_timer_2(T2_DISABLED,0,1);
   setup_ccp1(CCP_OFF);

   enable_interrupts(int_ext);
   enable_interrupts(int_timer1);
   enable_interrupts(GLOBAL);
   set_timer1(65536-62500);// Her 1/(20000000) *4*8=1.6 us'de timer1, bir artar. (65536-62500) * 1.6= 100 ms tasma süresi. 10 * 100 ms=1 s  
   //TODO: User Code

   for(;;)
   {
      if(tazele)
      {
         delay_ms(1000);
         printf(lcd_putc,"\fSAYI:%Lu %Lu",devir, x);
         //delay_ms(50);
         tazele=0;
      }
   }

}

Arkadaşlar sorunumu çözdüm, çözüm yukarıdaki kodlardaki gibi. Şuan sağlıklı olarak ölçebiliyorum..
 

Forum istatistikleri

Konular
128,349
Mesajlar
916,881
Kullanıcılar
450,189
Son üye
abdullah 2000

Yeni konular

Geri
Üst