timer0 ve ext_int birlikte kullanımı

Başlatan makine_terbiyecisi, 27 Şubat 2016, 11:30:47

makine_terbiyecisi

Merhaba Arkadaşlar,
Ben kare dalganın frekansını hesaplamak istiyorum.
İnternette tatmin edici bir cevap bulamadım. Son çare olarak siz deneyimli arkadaşlara abilere sormak istedim.

Kare dalga pulse saymak için ext_int kullanacağım. Timer0 ise zaman sayacak.
Şöyle bir kod yazdım fakat ext_int içindeki pulse hep sıfır değer döndürüyor.

#include <16f877.h>

#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=20000000)

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

#define use_portd_lcd TRUE // LCD d portuna bagli
#include <lcd.c>



int16 pulse=0,tur=0;
unsigned int8 tt=100;
int1 flag=0;

#int_ext
void pulse_counter(){
   if((input(PIN_B0)==1)&(input(PIN_B1)==0)){
      pulse++;
      if(input(PIN_B2)==1){
         tur++;
      }
   }
   if((input(PIN_B0)==1)&(input(PIN_B1)==1)){
      pulse--;
      if(input(PIN_B2)==1){
         tur--;
      }
   }
}

#int_timer0
void timer(){
   set_timer0(60);
   flag=0;
   
   if(tt>0){
      tt--;
   }
   else{
      //delay_us(100);
      flag=1;
      disable_interrupts (global);
      disable_interrupts(int_timer0);
      disable_interrupts(int_ext);
      tt=100;
   }
}

//************ ANA FONKSIYON *********************
void main(){
   setup_psp(PSP_DISABLED);
   setup_timer_1(T1_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);
 
   set_tris_d(0x00); // D portu cikis
   set_tris_b(0x01);
   
   setup_timer_0 (RTCC_INTERNAL|RTCC_DIV_256);
   enable_interrupts(INT_EXT);
   enable_interrupts(INT_timer0);
   enable_interrupts(GLOBAL);
   ext_int_edge(H_TO_L);
   set_timer0(60);
   
   lcd_init(); // lcd hazirlaniyor
   //printf(lcd_putc,"\f  Welcome !!\nSalih Aslan .."); 
  int t;
   while(TRUE){
      if(flag){
         t++;
         printf(lcd_putc,"\fF=%Lu puls/sn\nTur=%d tur/sn",pulse,t);
         
         enable_interrupts(INT_EXT);
         enable_interrupts(INT_timer0);
         enable_interrupts(GLOBAL);
         ext_int_edge(H_TO_L);
         set_timer0(60);
         pulse=0,tur=0;
         tt=100;
         flag=0;
      }
   }
}
# ÖĞRENELİM, ÖĞRETELİM #


dursuncemal

interupta iki adet  sarti kontrol ediyorsun > ( if((input(PIN_B0)==1)&(input(PIN_B1)==0))) burada b1 i enble gibi mi kulanmak istedin. birde zatan interruptun yonnunu h to l diye ayarlamissin bu durumda b0 a bakman anlamsiz sadece bi e bakman yeterli bu arada tris ayarlarinda sadece b0 giris secilmis ( if((input(PIN_B0)) diye sordugunda ccs giris yapiyor mu yapmiyor mu bilmiyorum.

bu isin en kolayi   timer1 in clock kaynagini external secip tmr0 i da 1 saniyeye kurup her timer0 interruptunda tmr1 in icerigini okuyup sifirlamak.
:=

Salih

Örnek program.
Tmr1 sayıcı, Tmr0 kesme olarak kullanıldı.

// Tmr1 Modülünü Frekansmetre olarak kullanma Örnek Programı
#Include  <16F877.h>
#Fuses XT,NOWDT
#Use Delay(clock=4M)
#include <Lcd.c>

int16 say=0,frk=0;

#int_Timer0// 65 ms
void Kesme()
{      
      say = get_timer1();
      set_timer1(0);
//Kesme değeri 1 saniyeye çevirmek için (1000/65) 15,2 
      frk = (say*152)/10;
      set_timer0(2);     
}

void main()
{
   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)   
   {           
      printf(Lcd_putc,"\fFrk=%Lu Hz",frk);
      delay_ms(200);
   }
} 

makine_terbiyecisi

Öncelikle yardımcı olduğunuz için çok teşekkür ediyorum..

Projemde enkoderli dc motor hız ve yönünü kontrol etmeye çalışıyorum.
Enkoderin 3 tane çıkışı var. bir tanesi tur başına pulse üretiyor, diğer ikisinin faz farklarına göre hız ve yön kontrolü yapılıyor.
Hangi yöne döndüğünü anlamak için interrupt içinde ( if((input(PIN_B0)==1)&(input(PIN_B1)==0))) mantıksal işlemini sorguladım.

#int_ext
void pulse_counter(){

pulse++;// Bu şekilde hatasız çalışıyor.

}


böyle yapınca çalışıyor.
Ama benim yapmak istediğim, saat yönüne dönerse '+pulse', tersi yönde olursa '-pulse' deger versin istiyorum. :-\ :-\
# ÖĞRENELİM, ÖĞRETELİM #

makine_terbiyecisi

Yardımcı olan tüm arkadaşlara teşekkür ediyorum..
Sorunu farklı bir yöntem ile çözdüm.
Aynı sorunu yaşayacak arkadaşlar için yazmak istedim...

Enkoderin aralarında faz farkı bulunan pinlerini Bir D-Flip Flop devresine verdim.
bu flip flop çıkışından 0-1 çıkış veriyor. bu çıkışlar ile yön tayini yaptım..

Detaylı bir anlatım olmadı ama hepsini yazamadım. İhtiyacı olan arkadaşlar ulaşırsa detaylı bilgi veririm...

Bir Mum Diğer Bir Mumu Tutuşturmakla Işığından Birşey Kaybetmez ...
# ÖĞRENELİM, ÖĞRETELİM #