hitec c de DELAY( ) doğruluğu

Başlatan ferhat, 20 Ekim 2003, 20:34:45

ferhat

arkadaşlar sizce hitec teki delayus() veya delayms() tam doğru zamanı veriyor mu

şöyleki basit led yakıp söndürme de 200ms*5=1sn bekle komutlarında ledler yaklaşık 1,4 ~ 1,6 sn yanıp veya sönüyor. bu değerleri kronometre ile aldım
yoksa bende mi yanlışlık var.

bu değerler yanlışken tutup çok kısa sürelere nasıl güveneceğiz. örneğin servo motor için 1ms 1,5ms ve 2ms gecikmeli lojik 1ler gerekmektedir.

bu sorunun şöyle üstesinden gelmeyi denedim
delay.c ve delay.h dosyalarını delay.h altında birleştirdim ve us( ) aynen bırakıp
ms( ) yi assembly ile yazdım aynı şekilde sn( )  oluştırup onu da assembly ile yazdım
ancak hitec bu assembly döngülerinde sonsuz döngüye giriyor ve çıkamıyor sonuçta program fonksiyonun çağrıldığı yerde tıkanıyor ilerlemiyor.

bir tavsiyesi olan var mı?

yada sizin hitec altında tam doğru olarak çalıştığınıza inandığınız .h dosyaları var mı

microchipc.com dan delay rutinlerini aldım . kod çok büyük adam birkaçtane dosyayı birbirne zincirlemiş derleyince kodu büyütüyor.

benim istediğim 877 için 4mhz altında tam doğru ve ya yakın doğru zamanlamayı verecek az yer kaplayacak bir rutin bulmak , çok küçük bir istek :)

kolay gelsin

Erol YILMAZ

Selam;
Hi-Tech in delay fonksiyonlari buyuk olcude yanlis cevap veriyor.
En guzeli en cok kullandigin frekanslarda hazir 250 uS lik delay rutinleri kurmak.
Yani 4 Mhz, 20 Mhz vs....
Kolay Gelsin.

Analyzer

Dostum merhaba,

Ben CCS kullanıyorum ama senin karşılaştığın sorunla ben de karşılaştım.O problem compilerdan kaynaklanmıyor.Programın içinde kullandığın komutların da işletme zamanları var bildiğin gibi.Örneğin x komutu 2 cycle'da tamamlanıyor, y komutu 1 cycle'da tamamlanıyor.O nedenle bir döngü kurduğunda; örneğin pseudo kodunu vermek gerekirse :

while (.....) {
.
.
.
x(...);
y(...);
delay_ms(250);
not (led); // yanık ise söndür, sönük ise yak...
}

Bu gibi bir döngüden 4 sn'de bir yanıp sönmesini beklememelisin   :D Çünkü döngü içinde kullandığın prosedürlerin ve fonksiyonların içindeki komutların da işletme süreleri var. Bu nedenle kesin sonuç istiyorsan taşma kesmesini (overflow  interrupt) kullanman gerekir.Bu kesme belirlediğin zaman aralığında işletilir.Borland C++ Builder veya Delphi kullandı isen oradaki Timer bileşeni gibi.
Senin için pseudo kodu vermek isterdim ama Hitech kullanmıyorum o nedenle anlamsız olur.
Aklına takılanları çekinmeden sorabilirsin.

Analyzer.
Üşeniyorum, öyleyse yarın!

ferhat

evet bu süre olayını biliyorum hitec in yanında gelen samples lerdeki delay.h
içerisinde zaten bu süre 3 e bölünüyor. aşağıda us verildi Crystal=4mhz
    void DelayUs(unsigned char x){
            unsigned char i;
            i=x/3;
            while(--i =! 0) continue;
     }
     tamam bu ok! adam milisaniye çağırırken de 4*250us işletiyor.belki 1ms de bu süre uzaması farkedilmiyor ama sn ler de işler karışıyor.
*****************
      bende sn de tam işlesin diye assembly ile yazdım
     . .. . . .delay.h
      void DelaySn(unsigned char x)
          while(x-- =! 0){
                 //1sn    
             #asm
                 ....................
             #endasm
       }
 }
     

       kesinlikle eminim ki bu pic c nin assembly ile de arası yok
      yukarıdaki kodu header dosyası içerisinden
           DelaySn(1)
           DelaySn(10)
olarak da çağırırsan  1sn muamelesi yapıyor. Ayrıca DelaySn(10) gibi bir çağırmada sonsuz döngüye giriyor. Ve bu kodun ms uyarlaması çalışmıyor.
       bende şöyle yaptım delayMs(1) sorunsuz çalıştığından,,diyelimki 10sn gecikme yapacağız
          for(x=0;x<10;x++) DelaySn(1);
    ama bu kod da itici geliyor .hemen şöyle bir akıl gelebilir for döngülerini ayrı bir program sayfasında  içerisinde tanımla 2 dosyayı birbirine zincirle ve dosyaları .c yazdığımız dosyadan çağır.ama ne yazık ki bunu da yemedi.
       ama bu kodları hassas olarak yaptığım zama n size burada vereceğim

ferhat

kritik zamanlamalar için  assembly gecikme rutinleri şart olduğu için aşağıdaki gibi rutinleri hi-tec pic c ye ekledim ve mp-lab 6,30 da simülasyonunu yaptığım zaman tam doğru zamanlama verdi aşağıdaki kod geliştirilebilir ve header dosyası olarak pic c ye entegre edilebir. bunu yaptığım zaman yine onu vereceğim.

girilen parametre switch() yapısında gerekli katsayılar verilerek gerekli gecikme sağlanıyor ben 3-4 tane yapı koydum istenildiği kadar çoğaltılabir.

asm eklentisi için etiket ve en sonda ; şart !!!!


void Delay(unsigned char m){
   delayC1 = 0;
   delayC2 = 0;
   switch(m){
       case 1 : coef1 = 10 ; coef2 = 22 ; break;   //700us
       case 5 : coef1 = 7  ; coef2 = 238; break;   //5 ms
       case 20: coef1 = 100; coef2 = 63 ; break;   //20ms
   }  
DELAYus:               //delay = 3*coef1*coef2 + 4* coef1
#asm
Delayus
   MOVF   _coef1,w      
   MOVWF   _delayC1
Dongu1
   MOVF   _coef2,w      ;1*coef1
   MOVWF   _delayC2      ;1*coef1
Dongu2
   DECFSZ   _delayC2,F      ;1*coef2*coef1
   GOTO   Dongu2      ;2*coef2*coef1
   DECFSZ   _delayC1,F      ;1*coef1
   GOTO   Dongu1      ;1*coef1
#endasm
;  
}

Erol YILMAZ

Selam;
H.H. bir gecikme fonksiyonu yazmadim ama CCS isi soyle yapiyor.
Ilk once kullanicidan Clock frekansini aliyor.
Daha sonra yapacagin gecikmeleri miktarina gore Delay_us(xxx) veya Delay_ms(xxx)
fonksiyonlariyla aliyor. Gecikme katsayilarini derleme asamasinda Clock 'a gore belirliyor. Daha sonra da zaten program icerisinde gelen delay() komutlarini isliyor.

Genel bir fonksiyon yapilmak isteniyorsa;
Tasarlanan delay() fonksiyonunda parametre olarak bir adet Clock bilgisi ve gecikme miktari bilgisi olmasi gerekir, diye dusunuyorum.
Kolay Gelsin...