Rb0 kullanarak frekans okumak.

Başlatan Tolga86, 25 Mayıs 2015, 11:16:53

Tolga86

Merhabalar.
Şimdi üye oldum ve ilk mesajımı yazıyorum. :)
Rb0 pinine gelen frekansı okuyarak, aldığım frekansa göre c portunda ki step motoru hareket ettirmek istiyorum.
Uzun zamandır üzerinde uğraşmama ramen başarabilmiş değilim. CCS C kullanıyorum.
Rb0 dan frekansı okuyabilmek için ne yapmam gerekiyor. Nerede hatam var. timer0 değil de farklı bir timer mı kullanmalıyım. gerçi denemedi değilim. yardımcı olursanız çok sevinirim. şimdiden teşekkür ederim.

unsigned long long int t;
float f;
const int adim[]={0x00,0x04,0x06,0x0B,0x03,0x07,0x0C};
const int geri[]={0x00,0x0C,0x07,0x03,0x0B,0x06,0x04};
int eski=0,yeni=0;
int i=0; 

void main()
{  

   set_tris_c(0x00);
   set_tris_b(0x03);
   set_tris_d(0x02);
   output_c(0);
   output_d(0);
   output_b(0);

  setup_timer_0(RTCC_EXT_L_TO_H | RTCC_DIV_8);
  enable_interrupts(INT_timer0);
  enable_interrupts(INT_ext);
  enable_interrupts(GLOBAL);
  set_timer0(0);

if(yeni>eski)
   {
   while(eski<yeni)
      {

      for(i=1;i<7;i++)
      {
         output_c(adim[i]);
         delay_ms(150);
      }
      eski++;
      }
   }

if(eski>yeni)
   {
   while(eski>yeni)

      {

      for(i=1;i<7;i++)
      {
         output_c(geri[i]);
         delay_ms(150);
      }
      eski--;
   }    

}
  delay_ms(150);

  while(1);

}


#int_timer0
void timer0_kesme()
{
set_timer0(0);
t=get_timer0(); 
f=t*0.0000004;
f=1/f;
yeni=f;
yeni=yeni/4;
}

Gökhan BEKEN

Özel mesaj okumuyorum, lütfen göndermeyin.

ferdem

Frekans okumak için ya periyot süresini ölçersiniz ya da belirli bir süre(1s mesela) içinde gelen "pulse"ları sayarsınız. Hangi yöntemi kullanacaksınız? İki yöntem de kullanılabilir. Frekansa göre doğruluk, yapılabilirlik değişiyor. Örneğin 4MHz lik frekansı periyot(250ns) ölçerek bulamazsınız ancak 1 s de gelen pulse ları sayarak bulabilirsiniz.

RB0 kesmesi için bir kesme rutini yazmamışsınız, sadece timer0 için bir rutin var, bu şekilde frekansz zaten ölçülmez.

RB0 pini ile periyot süresi ölçebilirsiniz. RB0 kesmesi geldiğinde timer başlatılır, tekrar geldiğinde durdurulur süreye bakılır. Kronometre başlat durdur hesabı.

CCP pinleri bu işlem için daha uygun olabilir, CCP modülün capture özelliğini kullanarak timer değerini daha doğru okumuş olursunuz.

İnternette aradınız mı: PIC frequencymeter, frekansmetre. PIC pulse width measurement, PIC period measurment...

Kolay gelsin.

Tolga86

Cevaplarınız için teşekkür ederim. Evet internetten aradım. ccp kullanarak yapılmış. Zaten bende ccp kullanarak yaptım. ama benim bu frekansı rb0 pininden okumam gerekiyor. o yüzden bi işime yaramadı.

external interrupts kullanarak yapmaya çalıştım ancak başarılı olamadım.

Gönderdiğim kod üzerine ekleyerek gösterebilirmisiniz ?

justice_for_all

dusen ve yukselen kenarlarda kesme olussa yapabilirdiniz ama değilse yapamazsınız.
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay


Tolga86

Dediklerinizin hepsini denedim ancak olmuyor. İnternette araştırma yaptım elbette. ama ccp modülü kullanılarak yapılmış genelde.
rb0 a gelen frekansı başka porta aktaran kısa bir örnek yapma imkanınız var mı. timer ve ext kesmesini nasıl kullandığınızı görebilmem için.
kaç aydır uğraşıyorum üzerinde. elimden gelen herşeyi yaptım ve artık tıkandım. devam edebilmem için bu aşamayı atlatmam gerekiyor.
yardımlarınızı bekliyorum. teşekkür ederim.

Tolga86

#7
int araştırması ile yapabildiğim bu ama yine hata var biyerlerde. Çalışmıyor.

int i=0; // Tamsayı tipinde değişken tanımlanıyor
int j=0; // Tamsayı tipinde değişken tanımlanıyor
float f; 
unsigned long long int t; 
int eski=0,yeni=0;

const int adim[]={0x00,0x06,0x02,0x0B,0x09,0x0D,0x04};
const int geri[]={0x00,0x0D,0x09,0x0B,0x02,0x06,0x04};

//****** Dış Kesme Fonksiyonu *****************

#int_timer1  
void  timer1_kesme ()  
{

set_timer1(0);
t=get_timer1(); 
f=t*0.0000004;
f=1/f;
yeni=f;
yeni=yeni/4;

}        
#int_ext                
void  ext_kesmesi ()    
{
set_timer1(0);

if(yeni>eski)
   {
   while(eski<yeni)
      {

      for(i=1;i<7;i++)
      {
         output_c(adim[i]);
         delay_ms(150);
      }
      eski++;
      }
   }

if(eski>yeni)
   {
   while(eski>yeni)

      {

      for(i=1;i<7;i++)
      {
         output_c(geri[i]);
         delay_ms(150);
      }
      eski--;
   }    

 }

}

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

void main ()
{

   setup_spi(SPI_SS_DISABLED);     // SPI 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_b(0x01);   
   output_b(0x00);     

   set_tris_c(0x00);  
   output_c(0x00);

   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1);
   set_timer1(0);   

   enable_interrupts(INT_timer1); 

   ext_int_edge(H_TO_L);   

   enable_interrupts(INT_EXT);  
   enable_interrupts(GLOBAL);  

   while(1); // Sonsuz döngü

}

Gökhan BEKEN

#8
Hız ne bimiyorum ama, kesme içinde işlem yapılmaz, bir değişken tanımlayın, bayrak olarak kullanın, yani sadece 1 veya 0 değerini alsın.
Main fonksiyonundaki, while'in içine bir if ekleyerek o değişkenin 1 olup olmadığını kontrol edin, eğer 1 ise, 0'layın ve kesmede yapılması gereken işlemleri orda yapın.
Ayrıca kesmenin içinde set_timer1(0); yazmışsınız, bir kesmeden çıkmadan başka kesme üretebilecek birşey yapıyorsunuz.  Bu da yanlış.
Özel mesaj okumuyorum, lütfen göndermeyin.

ferdem

https://www.picproje.org/index.php/topic,59469.msg460350.html#msg460350 başlığında B0 pinine gelen pulse genişliği ölçülüyor, o örneği inceleyebilirsiniz.

selimkoc

PIC'lerde kesme ile frekans okumak sıkıntılı bir durum. kesmeye girme-çıkma prosedurlerinden dolayı yüksek frekansları okumak zor. Ancak STM32F407 ile yaptığım ölçümlerde 4 MHz hatasız ölçebilmiştim. (Core 168 Mhz de çalışırken)