877A ile encoderdan pals okumada sorun

Başlatan i_iMiT, 28 Haziran 2013, 00:06:05

i_iMiT

Merhaba arkadaşlar
aşağıdaki programla iki pals arasındaki zamanı ölçmeye çalıştım daha sonrada bunu devir sayısına oranlayacaktım fakat önceden doğru aldığım zaman bilgisinin programa yeni kodlar ekleyince (ref bilgisi almak için adc çevirici kullandım) yanlış olduğunu gördüm

unsigned sinyal=100,gb,digital;
int16 pals, time, f;

#define pals pin_C0

void main()
{
   setup_adc_ports(ALL_ANALOG);
   setup_adc(adc_clock_div_2);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
   setup_timer_2(T2_DIV_BY_16,250,1);
   setup_CCP1(CCP_PWM);
   setup_CCP2(CCP_PWM);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   set_timer1(0);   // TMR1 değeri belirleniyor
   
   set_tris_b(0x00);
   set_tris_c(0x01);
   set_tris_e(0xFF);
   
   lcd_init();
   printf(lcd_putc, "\f pals olcum");
   delay_ms(10);
   
   set_pwm1_duty(0);
   set_pwm2_duty(0);
   
   enable_interrupts(INT_timer1); // int_timer1 kesmesini aktif yapar
   enable_interrupts(GLOBAL);     // Aktif edilen kesmelere izin ver
   
   while(true)
   {
   while(!input(pals))
   {}
   
   set_timer1(0);
   
   while(input(pals))
   {}
   
   while(!input(pals))
   {}
   
   time=get_timer1();// iki pals arası zaman bulunuyor

   f=50000/time;// frekans bulunuyor
   f=f*20;
   gb=f/6;// 0-255 arasındaki değerlere oranlama
   
   output_high(pin_c3);
   output_low(pin_c4);
   
   set_adc_channel(5); //an5 
   delay_us(20);
   digital=read_adc();
   delay_us(20);
   
   if(gb<digital)
   sinyal=sinyal+1;
   
   if(gb>digital)
   sinyal=sinyal-1;
   
   if(sinyal>250)
   sinyal=250;
   
   if(sinyal<1)
   sinyal=1;

   set_pwm1_duty(sinyal);
   set_pwm2_duty(sinyal);
   
   printf(LCD_PUTC, "\fD %u S %u\nG %u F %ld",digital,sinyal,gb,f);
   delay_ms(100);
   }
}


yazdığım program bu şekilde adc çevirici eklediğimde timer1 yanlış zaman bilgisi alıyor bu hatayı nasıl çözebilirim ?

yavuzak

Timer1 kaç saniyede overflow oluyor. pulslar saniyede kaç kere geliyor. Bu süreleri uygun ayarladınmı. Timer1 bana çok yüksek frekansta çalışıyor gibi geldi. Ayrıca interrupt kullanmıyorsun niye enable interrupt yapıyorsun. Ayrıca çoğu zaman 50000/time gibi ifadeler yanlış sonuç veriyor çünkü noktalı sayılar çıkıyor sonuçta. Bu sonuçları ektana yazdır ve doğru hesaplandığına emin ol. Diğer görünen sorunlar setup_adc(adc_clock_div_2); çok yüksek bir frekans. Bunu div_32 yap ya da T1_INTERNAL yap çünkü pic 1Mhz de çalışıyorsa eğer senin seçimin mantıklı. 20Mhz filansa bu hızda ADC çevrim yapamaz. read_adc() 10 bit geri döndürecek sen bunu 0-255 ile kıyaslıyorsun. burada da hata çıkabilir

i_iMiT

pic 4 MHz de çalışıyor. motora 1 Volt verdiğimde encoder çıkışı 68 Hz (iki pals arası 41msn) veriyor devride 200 d/d oluyor. max 19 V verdiğimde encoder çıkışı 1525 Hz (iki pals arası 660usn) veriyor devride 4550 oluyor. timer1 16bit olduğu için 65535 sayar sonra taşma olur benim programda ise en fazla 41000 sayar bu yüzden overflow olacağını sanmıyorum buradaki amacım encoderdan gelen iki pals arasındaki zamanı bulup onu devir sayısına oranlamak. adc çeviriyi programa eklemeden istediğim sonuca ulaştım iki pals arasını sorunsuz olçüyorum
fakat adc girdimi işin içine sonuç hatalı oluyor. bunu çözemedim