avatar_Mayhoş

Timer ile uS Belirleme

Başlatan Mayhoş, 07 Ocak 2020, 14:02:05

Mayhoş

#include <16F877A.h>
#fuses HS, NOWDT, NOPROTECT, NOLVP
#use fast_io(D)
#use delay(crystal=20000000)
#define IR_Sensor PIN_A4

short kontrol_ir(){
unsigned int16 count = 0;
  
  SET_TIMER1(0);
  
  while(!input(IR_Sensor) && (count < 80))
  count = GET_TIMER1();

  if( (count > 80) || (count < 30))
  return FALSE;
 
  SET_TIMER1(0);
  count = 0;
  
  while((input(IR_Sensor)) && (count < 40))
  count = GET_TIMER1();

  if( (count > 40) || (count < 10))
  return FALSE;
    
return TRUE;
}

void main() 
{
  output_d(0);
  set_tris_a(11111111);
  set_tris_d(00000010);
  SETUP_TIMER_1(T1_INTERNAL | T1_DIV_BY_8);
  while(TRUE)
  {
  while(input(IR_Sensor));                          
  if(kontrol_ir())
  {
    output_high (PIN_D0);
  }
  if(input(IR_Sensor) == 0)
  output_low (PIN_D0);
  }
}

Merhaba arkadaşlar,

IR Alıcı ile bir devre yapmaya çalışıyorum ve gelen sinyalin bana ait olduğunu anlamam için belli ölçülerim var. Bunu da timer ile yapmaya çalıştım fakat timer çalışmıyor sanırım ya da ben ayarlamalarını yapamadım.

Yaklaşık 70us boyunca 1 , 30us boyunca 0 bilgisi geliyor alıcıma.

Bende programda 1us'ye ayarlı timer çalıştırayım dedim.

1 bilgisi için :
Timer 80us'den küçük ve 1 bilgisi geliyorsa sinyal benimdir ama 80us'den büyük veya 30us'den küçükse benim değildir.

Yine aynı şekilde 0 bilgisi için :
Timer 40us'den küçükse ve 0 bilgisi geliyorsa sinyal benimdir ama 40us'den büyük veya 10us'den küçükse benim değildir.

Şeklinde bir mantık oluşturdum. Şartları sağlıyorsa main kısmında ki D0 pinini high yapacak, eğer hiç bilgi yoksa ya da kesilmişse 0 yapacaktı.

Bu haliyle çalışıyor fakat timerlar garip bir şekilde önemsiz kaldı. Başka bir bilgide de D0 pini anlık olarak aktif olabiliyor.

Yalnızca timerlar ile deneyeyim dedim.
Mesela;

set_timer1(0); count=0;
count=get_timer1();
if(count>100)
output_high(pin_d0);

gibi bir komut oluşturdum. Fakat pin çıkış vermedi. Sanki timer komutum çalışmıyor.


Kısacası benim belli mikrosaniyelerle bir if komutu oluşturmam lazım. Örneğin: 50.mikrosaniyede bilgi 1 ve 80.mikrosaniyede bilgi 0 ise bu benim sinyalimdir çıkışı high yap.

Büyüktür küçüktür yerine eşittir koyduğumda ise hiç çıkış alamadım. Yardımcı olabilir misiniz acaba?

Teşekkürler.

MB_77

#1
bu mesaj tarafımdan silinmiştir.

ete

Bana kalırsa çok küçük zaman birimleri ile çalışıyorsun. 8 bit lik bir mikroişlemcide 1us lik süre çok küçük bir zaman dilimidir. Her ne kadar OSC frekansın 20Mhz olsa bile yakalamaya çalıştığın peryotlar bence küçük geliyor. Komutlarında işlenirken gecikmeye sebep olduklarını unutma. Sen 100 birimlik bir sayımı yakalamaya çalışıyorsun. Timer'ın sayma puls süresi 1/5=0,2 us dir ve 100 birim süresi ise 20us tutar. Ama o işi test edecek komutların belkide 50us tutuyordur.
Ayrıca HIGH ve LOW peryotların yakalanmasında dikkat edilmesi gereken hususlar vardır.
Direk olarak giriş 1 ise timer saymaya başlasın diyemezsin. Önce o girişin LOW olduğu konumu yakalayıp orada beklemen ve 1 olmadan önce timer'ı sıfırlaman ve 1 olur olmaz sayıcıyı çalıştırman gerekir. Ancak bu şekilde doğru sayım alabilirsin. Yakalamaya çalıştığın sinyalin önce tersini yakala ve orada bekleyerek istediğin şekil geldiğinde saymayı başlat. Bu hem LOW hemde HIGH peryotları için geçerlidir.
Ancak bu şekilde doğru zamanları yakalayabilirsin. Bu durumda karşılaştırmalarında doğru olabilir. Yinede gelen puls=1 ise ve süre 80 den küçük ise benim sinyalimdir demende yanlış bence. Bakalım o sinyal 70us süre ile mi geldi. En az 70us ile sürmesi durumunda o sinyal senindir demek daha doğru değilmidir.
Sonuçta bazı mantıksal düşünce hataların var diye düşünüyorum. Ama her şeyden önemlisi çalıştığın süreler çok küçük. Ben olsam küçük denemeler yapardım. Mesela , timer1 i sıfırlayıp hazırda bekletir ve giriş 1 olduğunda saydırmaya başlar ve sıfır olduğunda durdurup sayılan değeri ya eproma yazdırıp oradan okur yad abir şekilde o bilgiye bir bakardım. Ne sayıyorsun yada neyi sayamıyorsun anlamak lazım.
ete








Hattuşa

20Mhz ile timer e baktığımızda işlmecinin 1 ticksi 0.2uS sizin yazdığınız kod komutlar 1uS için yeterli gelmeyebilir. yani işlemcinize if dediğinizde bu komutu işleme süresi 0.2 sürer min. ve devamında komuta devam ettiğinizde komut işleme süreniz yetersiz kalır. bence daha hızlı bir işlemci ile yol devam etmelisiniz. misal 64Mhz lik bir işlemci belki yetiştirir.



MB_77

#4
bu mesaj tarafımdan silinmiştir.

Powered by EzPortal