Haberler:

Eposta uyarılarını yanıtlamayınız ( ! ) https://bit.ly/2J7yi0d

Ana Menü

encoder okuma

Başlatan gogtugh, 17 Şubat 2015, 17:07:19

gogtugh

ben devir sayısını ölçmek istiyorum encoder tur başına 200 puls veriyo, proteusta devre mükemmel çalışıyo her pulsu yakalıyo fakat devreyi kuruyorum borda lcd bi gösteriyo bir sıfır gösteriyo bi gidiyo yani gerçekte olmuyo eğer kodlarda bir sorun yoksa devreyle ilgilenecem  kodlarda eksiği veya hatayı söyleyebilirseniz çok sevinirim...
                     

bu arada proteusta 200 e bölmeyi kaldırıp simüle ettim pulslar görülsün diye.








#include<16f877A.h>


#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD

#use delay(clock=4000000)


#use fast_io(d)
#use fast_io(b)

#define use_portd_lcd TRUE
#include<lcd.c>

int32 i=0,a=0;


#int_ext
void ext()
{
a++;




clear_interrupt(int_ext);
}







#int_timer1
void timer1_kesmesi()
{
  set_timer1(63036);
i++;

if(i==3000)
{
i=0;
lcd_init();
printf(lcd_putc,"RPM=%ld",a/200);
a=0;

  
}
}



void main()
 {
     
    setup_psp(PSP_DISABLED);
 
    setup_timer_2(T2_DISABLED,0,1);
    setup_adc_ports(NO_ANALOGS);
    setup_adc(ADC_OFF);
    setup_CCP1(CCP_off);
    setup_CCP2(CCP_off);
    setup_comparator(NC_NC_NC_NC);

lcd_init();

set_tris_b(0x01);
ext_int_eDGe(H_to_L);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
    
    
    
    
    
    setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); 
 
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
    

    while(1);

 }


Salih

lcd_init();


Bu işlemi main içerisinde bir kere yapsan yeterli olur.

LCD yazdırma işlemini timer kesmesi dışına çıkar.
timer kesmesinde sadece bir biti set et,
ve while döngüsü içinde bu bit 1 olunca
lcd ye yazdırma işlemi yap. yazdırma işlemi sonunda biti reset yap.

baran123

Böyle yap, lcd bir kere hazırlanır
#include<16f877A.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=4000000)

#use fast_io(d)
#use fast_io(b)

#define use_portd_lcd TRUE
#include<lcd.c>

int32 i=0, a=0;

#int_ext
void ext()
{
    a++;
    clear_interrupt(int_ext);
}

#int_timer1
void timer1_kesmesi()
{
    set_timer1(63036);
    i++;

    if(i==3000)
    {
        i=0;
        a=0;
    }
}
void main(void)
 {
    setup_psp(PSP_DISABLED);
    setup_timer_2(T2_DISABLED,0,1);
    setup_adc_ports(NO_ANALOGS);
    setup_adc(ADC_OFF);
    setup_CCP1(CCP_off);
    setup_CCP2(CCP_off);
    setup_comparator(NC_NC_NC_NC);

    set_tris_b(0x01);
    ext_int_eDGe(H_to_L);
    enable_interrupts(INT_EXT);
    enable_interrupts(GLOBAL);
    setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); 
 
    enable_interrupts(INT_TIMER1);
    enable_interrupts(GLOBAL);
    
    lcd_init();
    while(1)
    {
       printf(lcd_putc,"RPM=%ld", a/200);
    }
}

Salih

@Baran'ın kodlarına, Şöyle ilave edeyim.

if (i==0) printf(lcd_putc,"RPM=%ld", a/200);


Önlem alınmazsa lcd'de aşırı yazma dan dolayı ekran silik gözükür.

gogtugh

#4

şu şekilde son hali fakat encoderi çok yavaş elimle çevirdiğimde okuyabiliyo hızlanınca sıfır gösteriyo






#include<16f877A.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=4000000)

#use fast_io(d)
#use fast_io(b)

#define use_portd_lcd TRUE
#include<lcd.c>

int32 i=0, a=0;

#int_ext
void ext()
{
    a++;
    clear_interrupt(int_ext);
}

#int_timer1
void timer1_kesmesi()
{
    set_timer1(63036);
    i++;

   
}
void main(void)
 {
    setup_psp(PSP_DISABLED);
    setup_timer_2(T2_DISABLED,0,1);
    setup_adc_ports(NO_ANALOGS);
    setup_adc(ADC_OFF);
    setup_CCP1(CCP_off);
    setup_CCP2(CCP_off);
    setup_comparator(NC_NC_NC_NC);

    set_tris_b(0x01);
    ext_int_eDGe(H_to_L);
    enable_interrupts(INT_EXT);
    enable_interrupts(GLOBAL);
    setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); 
 
    enable_interrupts(INT_TIMER1);
    enable_interrupts(GLOBAL);
    
    lcd_init();
    while(1)
    {
    if (i==3000) 
       
       {
       printf(lcd_putc,"RPM=%ld", a/200);}
    
    }
}

Salih

#5
Frekansı 20Mhz yap.

Kodları şöyle yapalım.

#include<16f877A.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=4000000)

#use fast_io(d)
#use fast_io(b)

#define use_portd_lcd TRUE
#include<lcd.c>

int32 i=0, a=0,d;
int1 oldu;

#int_ext
void ext()
{
    a++;
    clear_interrupt(int_ext);
}

#int_timer1
void timer1_kesmesi()
{
    set_timer1(63036);
    i++;
     if (i==3000) 
   {
      i=0;
      d = a/200;
     oldu=1;
}
   
}
void main(void)
 {
    setup_psp(PSP_DISABLED);
    setup_timer_2(T2_DISABLED,0,1);
    setup_adc_ports(NO_ANALOGS);
    setup_adc(ADC_OFF);
    setup_CCP1(CCP_off);
    setup_CCP2(CCP_off);
    setup_comparator(NC_NC_NC_NC);

    set_tris_b(0x01);
    ext_int_eDGe(H_to_L);
    enable_interrupts(INT_EXT);
    enable_interrupts(GLOBAL);
    setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); 
 
    enable_interrupts(INT_TIMER1);
    enable_interrupts(GLOBAL);
    
    lcd_init();
    while(1)
    {
    if (oldu) 
       
       {
       printf(lcd_putc,"RPM=%ld", d);}
       oldu=false;
    }
}

gogtugh


kodu şöyle çevirdim fakat iyice gitti proteus bile düzgün saymıyo bu sefer benim kara veremediğim şey b0 kesmesi hızlı yakalar mı yakalamaz mı bunun kesin olduğunu bi anlasan programa iyice kafa yoracam  neyse teşekkür ederim bu arada cevaplarınız için.








#include<16f877A.h>
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=20000000)

#use fast_io(d)
#use fast_io(b)

#define use_portd_lcd TRUE
#include<lcd.c>

int32 i=0, a=0,d;
int1 oldu;

#int_ext
void ext()
{
    a++;
    clear_interrupt(int_ext);
}

#int_timer1
void timer1_kesmesi()
{
    set_timer1(63036);
    i++;
     if (i==7500) 
   {
      i=0;
      d = a/200;
     oldu=1;
}
   
}
void main(void)
 {
    setup_psp(PSP_DISABLED);
    setup_timer_2(T2_DISABLED,0,1);
    setup_adc_ports(NO_ANALOGS);
    setup_adc(ADC_OFF);
    setup_CCP1(CCP_off);
    setup_CCP2(CCP_off);
    setup_comparator(NC_NC_NC_NC);

    set_tris_b(0x01);
    ext_int_eDGe(H_to_L);
    enable_interrupts(INT_EXT);
    enable_interrupts(GLOBAL);
    setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); 
 
    enable_interrupts(INT_TIMER1);
    enable_interrupts(GLOBAL);
    
    lcd_init();
    while(1)
    {
    if (oldu) 
       
       {
       printf(lcd_putc,"RPM=%ld", d);}
       oldu=false;
    }
}

sadogan

Amacın yanlızca devir ölçmek ise tmr0 encoderden gelen plasleri saysın tmr1 ilede örenğin 100 ms de bir tmr0 içerigini okuyup
sonrada tmr0 içerigini sıfıra eşitledikten sonra okuduğun tmr0 değerinden devri hesaplaya bilirsin.
Programında 32 bitlik i ve a değişkenleri var ama onları 16 bit sınırları içinde kullanıyorsun 8 bit işlemci ve 4mhz çalışırken bunlara dikkat etmen gerekiyor.


gogtugh

bitler de iyice karıştı zaten de benim anlamadığım proteusta bu kadar iyiken neden gerçekte olmyo tama sümilasyon programı ama neyi kabul ediyoda böyle oluyo

Salih

senin devrende encoder pals sayısı nedir tur başına,
ve dönmesini düşündüğün max. dev/dak ne kadar.

gogtugh

#10
Tur başına 200 puls max dk 200 300 okusa yeterli

Salih

#11
Şunu denermisin. Mantığı değiştirelim.
Tmr1 direk sayıcı kullanalım bu sefer.
Dikkat et, frekans 4 Mhz göre hesaplı.
Encoder giriş ucunuda RC0'a bağla

#Include  <16F877A.h>
#Fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#Use Delay(clock=4000000)
#include <Lcd.c>

int16 devir=0;
int8 i=0;
int1 oldu;

#int_Timer0// 60 ms
void Kesme()
{      
      i++;
      if (i==10)
         {
            devir = get_timer1()/2;// devir dakika olması için
            set_timer1(0);
            i=0;
            oldu=1;
         }  
      set_timer0(21);     
}

void main()
{
   setup_psp(PSP_DISABLED);
   Setup_spi(SPI_SS_DISABLED);
   Setup_timer_0(T0_INTERNAL | T0_DIV_256);
   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1);
   setup_timer_2(T2_DISABLED,0,1);   
   Setup_adc_ports(NO_ANALOGS);
   Setup_adc(ADC_OFF);
   Setup_CCP1(CCP_OFF);
   Setup_CCP2(CCP_OFF);
   port_b_pullups(true);
   Enable_interrupts(INT_Timer0);
   Enable_interrupts(GLOBAL);
   Lcd_init();
   delay_ms(10);
   set_timer1(0);
   While(True)   
   { 
     if (oldu)
      {
         printf(Lcd_putc,"\fDevir=%Lu",devir);
         oldu=0;
      }      
   }
} 


mesaj birleştirme:: 18 Şubat 2015, 12:21:11

Program da devir hesabını yanlış yapmışım, düzelttim.
Yenisini kullan.

gogtugh

ben bu işi çözemedim ya enkoder bozuk desem puls veriyo yani denedim led yakmada falan





Salih

#13
En son verdiğim programı denedin mi?
Proteus da gayet güzel çalışıyor.
Donanımla ilgili problem olmasın.
Encoder çıkışları kaç volt ve çıkış veriyormu, test ettinmi?
Sinyal jeneratörün varsa 1 Khz bir kare dalga uygularmısın.
Buda LCD'de 300 D/Dk olarak görülmesi gerekir.

gogtugh

Evet bu son attığım sizin programınız  proteusta çalışıyor doğrudur evet, sinyal jenaratörüm yok maalesef donanımsal sorun da olabilir diye bende düşünüyorum fakat geliştirme kartı kullanıyorum ne kadar hata olabilir onda emin degilim
Şöyle bi uygulama yapmıştım 7 segment displayde 00 dan 99 a kadar her HIGH geldiğinde bi arttir seklinde orda artmıştı tabi elimle çok yavaş çevirdiğinden yani puls geliyo eminim ama ben cok cesit yaptım sizde bunu yaptınız timer 1 ve timer2 yi yapmistım daha önce artik encoder de sorun var diyip yenisini alacam aldıktan sonra deneyecem hepsini tekrardan