Soft delay_us yazmaya çalıştım. Uzman görüşleriniz ve önerileriniz.

Başlatan rree, 25 Temmuz 2013, 00:07:31

rree

   Daha önceki konularda kesme içinde delay fonksiyonu kullanmanın problemlere sebeb olacağını belirten arkadaşlar olmuştu. Ben de yazılımsal delay_us  programı yazmaya çalıştım.
   - Frekans olarak osilatör değil iç clock  mhz cinsinden bir değer düşündüm.
   - 5 Mhz clock frekansı olan bir işlemci  boş bir fonksiyonu bile çağırsan 1 us  yi  aşan zaman harcıyor.
   - Başlangıç değeri olarak 3 us den sonra  girilen değere yakın bir gecikme değeri elde edebildim.
   - Bir de çeşitli işlemciler için program yazmaya çalıştım bunlar 5Mhz 10Mhz  20Mhz  40Mhz
   - Bunları elde etmek için Asmbler dilinde nop ile gecikme komutları kullandım.
   - Daha pratik esnek bir program olabilirmi hayırlı Ramazan dileğiyle.
#define ClockF 40  //Mhz denetleyici iç clock frekansı yada Mips

int8 DelayRE_us(unsigned int Gecikme_us){
#if ClockF==5  
    if(Gecikme_us>4){
         Gecikme_us=Gecikme_us-3;
         
      while(Gecikme_us>0)
        {
          --Gecikme_us;
         
        }
          
    }
        #asm
         nop
         nop
         nop
        #endasm
  #endif
  #if ClockF==10  
    if(Gecikme_us>2){
         Gecikme_us=Gecikme_us-2;
         
      while(Gecikme_us>0)
        {
          --Gecikme_us;
         #asm
         nop
         nop
         nop
         nop
         nop
        #endasm
        }
          
    }
        #asm
         nop
         nop
         nop
         nop
         nop
        #endasm
  #endif
 #if ClockF==20  
    if(Gecikme_us>2){
         Gecikme_us=Gecikme_us-2;
         
      while(Gecikme_us>0)
        {
          --Gecikme_us;
         #asm
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
        #endasm
        }
          
    }
        #asm
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
         nop
        #endasm
  #endif
  #if ClockF==40  
    if(Gecikme_us>2){
          Gecikme_us=Gecikme_us-2;
      while(Gecikme_us>0)
        {
          --Gecikme_us;
          #asm nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop
           nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop
           nop nop 
          #endasm
         
        }
          
    }
       #asm nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop
            nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop 
            nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop
            nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop
       #endasm
         
  #endif
 
}

void main()
{   DelayRE_us(100);}

kantirici

Uzman değlim ama, madem delay için bir fonksiyn yazılacak ben olsam bir timer kurup her timer taşmasında değişken arttırıp istenilen gecikmeyi elde etmeye çalışırdım.

rree

Amaç yazılımsal donanım kullanmadan yaklaşık gecikmeler elde etmek.

RaMu

Bu fonksiyon hangi derleyicide hangi md.lere yönelik yazıldı?

Misal ccs c nin kendi delay_us vs. fonksiyonuda benzer birşey yapıyor,
burada yapılan yeni birşey diye düşünmüyorsun herhalde.
Yani ccs c donanım (timer veya kesme) kullanmadan delay üretiyor.

Aslında timer kesmesiyle delay üretmenin faydaları var,
çünkü delay esnesında md. başka işlemlerde yapabilir.
Ama senin yazdığın şekilde olan standart delay fonksiyonu
kullanıldığında md. delay bitene kadar delay fonksiyonunu boş boş işlemektedir,
hatta boşa enerji bile harcamaktadır,
misal delay esnasında md. başka işlem yapmayacaksa
md. uykudayken sayabilen bir timer kullanıp,
uykudan çıkarak işlem yapmak enerji tasarrufuda sağlar,
bu biraz ince ayrıntı oluyor, pille çalışan uygulamalarda aranan-istenen birşey olur.

Kesme içerisinde delay kullanmanın zararlı olma nedenine ne?
Bence kesme içerisinde yazılan kodu uzatması olabilir,
daha önemlisi kesme ivedi birşeydir,
olağandışıdır,
bu özel durum için yapılacak işlemler kısa olmalıdır,
asıl program kesmede olmamalıdır,
kesmede elde edilen bilgi asıl program döngüsünde işlenmelidir,
biz sadece bir kaynaktan kesme beklemiyoruz,
kesme içerisindeyken başka bir kaynaktanda kesme gelebilir,
bunu kaçırırsak ne olacak?
Kesme fonksiyonunda bence hiçbirşekilde bekleme yapılmamalı,
hatta mümkünse hiçbirşey yapılmamalı,
mümkün olan en az işlemle kesmeden çıkılmalı.

Bu arada kesme içerisinde bekleme ihtiyacı neden oldu,
bu gerçek bir durumsa merak ettim,
veya aklında bir kurgu varsa oda olur.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

rree

Ben bir program yazmıştım kesme kullanmıştım içinde delay fonksiyonu gerekmişti.  proteus debug   da c kodları gözükmez oldu  reset atargibi bir satırdan sonra ilk baştan tekrar tekrar başlıyordu. Picprojeden arkadaşlar delay fonksiyonunu kesme içinde kullanmamı söylediler. Delayı kaldırdım program düzeldi.
Bekleme sebebim  bir belleke datanın yazılmasını bekliyordum.Soft dealy fonksiyonu yazma fikri bundan sonra oldu. Ccs nin delay fonksiyonu yazılımsal ise niye proteus debug sapıtıyor.??
Kesme içinde niçin çabuk çıkılsın , kesme içindeyken  ccs kendisi otamatik kesme disable yapıyor biliyorum.

Tagli

RaMu durumu açıklamış zaten, ama özetlersek, kesmeler genelde hızla halledilmesi gereken şeylerdir. Halledilme hızının yanısıra, kuyrukta beklemeye de pek tahammülleri yoktur. Evet, bir kesme işlenirken kesmeler otomatik olarak kapatılır, ama bu durum sıradaki bir kesmenin kabul edilemez bir süre beklemesine sebep olabilir. Sıra ona geldiğinde de iş işten geçmiş ve yapması gereken işi zamanında yapamamış olur.

Bu arada, yazılımsal gecikme ifadesi isabetsiz olmuş. Kod ile yapılan tüm gecikmeler yazılımsaldır zaten. Donanımsal gecikmeler, mesela kesme sebebinin oluşması ile programın kesme koduna dallanması arasında geçen süre gibi sürelerdir ve yazılımcının kontrolünde değildir.

Normalde derleyicilerin kesme kodu içinde gecikmeye izin vermesi gerekir, sonuçta kulanımı pek doğru olmasa da bu durum programcının sorumluluğunda. CCS C hesapta hata engellemeye çalışıyor ama işleri daha da karmaşıklaştırmış. Ama bunun çözümü kendi gecikme kodunu yazmak olmamalı.

Proteus simülasyonları hakkında pek bilgi sahibi değilim, ama bildiğim kadarıyla çok güvenilir değiller.
Gökçe Tağlıoğlu

rree

-Kendi gecikme programını yazmakla kontrol bizde +++
-Bu program daha sade ve esnek yazılması için neler olabilir.

z

Kesme programlarında neden beklenmez masalla anlatayım.

Anne TV izlemektedir. Bu esnada ara ara mutfağa giderek ocaktaki yemeği kontrol etmektedir.

Bu olayda izlenen TV ana program, ara ara mutfağa gidip yemeği kontrol etmek de timer interrupt rutinidir.

Telefon çaldığında anne telefonu açar ve uzun uzun sohbete başlar. Bu da kötü yazılmış seri port interrupt rutinidir.

Telefonda konuşmaya başlayan anne artık ne TV ile ne de ocaktaki yemekle ilgilenir.

Nihayetinde yemek yanar, dizideki can alıcı sahne kaçar, annenize telefonla acil ulaşması gereken kişi annenize ulaşamaz, babanız eve geldiğinde bağırır çağırır ev yanık kokar vs vs.

Bu yüzden int rutininde bekleme yapılmamalıdır.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

RaMu

Z hocamın söylediklerinin üstüne kesme ile ilgili birşey söylemeye gerek yok.

Kendi delay fonksiyonunu yazınca kontrol sende olmuyor,
if while vs. kullanmışsın, yine derleyici nasıl işliyorsa ona bağımlısın,
bunun yerine ccs c nin delay fonksiyonunun asm çıktısını debug edip,
nasıl çalıştığını anlamak kontrolü sağlamakta daha faydalı olur.

Bu programı daha sade yazmak için asm de delay fonksiyonu nasıl yazılır ona bakmalısın.


Alıntı Yap
Ccs nin delay fonksiyonu yazılımsal ise niye proteus debug sapıtıyor.??

Hiç çakma telefon gerçeğinin yerini tutar mı?
Hiç simulasyon gerçeğin yerini tutar mı?

Devre isiste çalışıyor ama gerçekte çalışmıyor,
yada tam tersi durumlarıyla çok karşılaştım,
isisi baz alarak iş yapılmaz.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

yldzelektronik

Isise çamur atmak hiç de akıllıca ve haklı bir iş değildir.O program pc  üzerinde çalıştığına göre belirlenmiş parametlere göre hareket eder ve gerçek dünyada olduğu gibi bu parametrelerin anlık değişme imkanları söz konusu değildir.Ancak bu parametreleri münülerden değiştirebilirsiniz.Delay işi sadece kullanıcının/programcının isteğine kalmış.Eğer derleyicinizin delay fonksiyonlarına güvenmiyorsanız yazın kendi kodlarınızı.Ancak sağlam çalıştığı ortadaysa hiç de gerek yok.Ha işi öğreneyim, sistemden haberdar olayım vs gibi fantastik amaçlarla yapacaksanız da buna zaman ayırmanız gerektiğini ve gerekliliğini düşünmüşsünüzdür.Timer ile delay nasıl sağlıyorsunuz?Rtos benzeri bir yapı mı oluyor?Mesela ana programda bir fonksiyon çağırdım.Adc ölçümü yapıyor.Ölçüm bittikten sonra diğer kanaldan ölçüm yapacağım.Bunun için 20us bekleme öneriliyor.Bu süreyi delay_us(20); fonksiyonunu çağırıp mcuyu kitlemektense timer kullanarak yapalım.Nasıl olacak?Çünkü birden fazla delay gerektiren yerler olabiliyor.Örneğin,adc işine bir de led yak söndür ekleyelim.Pini 1 yaptım 2 sn bekleyecek.Pini 0 a çektim 500 ms bekleyecek.Bunu timer ile nasıl yaparız?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

XX_CİHAN_XX

Algoritmalarımızı oluştururken kesme içersin de uzun beklemeler yapmayacak şekilde oluşturmamız gerekir.
Hatta zaruri durumlar ve ufak gecikmeler hariç delay fonksiyonunu değil kesme içinde mümkünse ana program içinde bile kullanmamak gerekir. Saniyede milyonlarca komut koşturabilen bir aleti eblek eblek bekletmek bu yeteneğin hakkını verememek demektir. System timer kesmeleri vasıtasıyla gerekli gecikmeleri elde etmek daha güzel bir yaklaşım olacaktır.
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

RaMu

Alıntı yapılan: yldzelektronik - 25 Temmuz 2013, 13:40:26
Isise çamur atmak hiç de akıllıca ve haklı bir iş değildir.O program pc  üzerinde çalıştığına göre belirlenmiş parametlere göre hareket eder ve gerçek dünyada olduğu gibi bu parametrelerin anlık değişme imkanları söz konusu değildir.Ancak bu parametreleri münülerden değiştirebilirsiniz.Delay işi sadece kullanıcının/programcının isteğine kalmış.Eğer derleyicinizin delay fonksiyonlarına güvenmiyorsanız yazın kendi kodlarınızı.Ancak sağlam çalıştığı ortadaysa hiç de gerek yok.Ha işi öğreneyim, sistemden haberdar olayım vs gibi fantastik amaçlarla yapacaksanız da buna zaman ayırmanız gerektiğini ve gerekliliğini düşünmüşsünüzdür.Timer ile delay nasıl sağlıyorsunuz?Rtos benzeri bir yapı mı oluyor?Mesela ana programda bir fonksiyon çağırdım.Adc ölçümü yapıyor.Ölçüm bittikten sonra diğer kanaldan ölçüm yapacağım.Bunun için 20us bekleme öneriliyor.Bu süreyi delay_us(20); fonksiyonunu çağırıp mcuyu kitlemektense timer kullanarak yapalım.Nasıl olacak?Çünkü birden fazla delay gerektiren yerler olabiliyor.Örneğin,adc işine bir de led yak söndür ekleyelim.Pini 1 yaptım 2 sn bekleyecek.Pini 0 a çektim 500 ms bekleyecek.Bunu timer ile nasıl yaparız?

Abicim hem hem adc hem led için timer ile nasıl bekleme oluşturayım diye sorup,
hemde isise çamur atmak akıllıca değil demek,
bu pek profesyonel bir yorum değil,
isis tecrübelerime dayanarak çapraz çalışmama (gerçek-isis) durumlarının olduğunu gösterebilirim,
isis elinizdeki donanım ile aynı özellikleri sağlamayabilir,
bunun için bazen isise takla attırmak gerekiyor,
en basit örneğini 2*16 lcd de yaşadım,
2 kod yazmak zorunda kaldım,
biri sadece isiste biri sadece gerçek devrede 2*16 lcd yi çalıştırabiliyordu.

İstediğin kadar farklı gecikmeyi bayrak kullanarak,
sayaç tanımlayarak sağlayabilirsin,
her timer kesmesinde ilgili sayacın bayrağına bakıp sayaç aktifse değerini arttırır azaltırsın (algoritmana göre)
programındada bu sayacı kontrol ederek gerekli sürenin geçip geçmediğine karar verirsin.

https://www.picproje.org/index.php/topic,47916.0/topicseen.html
burada ambar7 biraz daha ayrıntılı bahsetmiş.

Özellikle tarama mantığıyla latch kullanmadan display uygulaması yapıyorsan
zaten delay fonksiyonlarını kullanamazsın,
yukarıda anlattığımıza benzer işlemler yapman gerekir.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

rree

 Arkadaşlar konu timer ile gecikme yapmak değil.  Yeri ve zamanı geldiğinde timer kesmesini kullanarak hatta real timer programı yazabilirim.
-İsis e benim ihtiyacım oluyor ccs nin delayını kesme içinde  olduğu zaman debug yapmıyor. Onun için delay fonksiyonu yazdım.
  İsteğim daha kısa ve daha kararlı bir yol varmı?

yldzelektronik

Alıntı yapılan: RaMu - 25 Temmuz 2013, 15:03:10
Abicim hem hem adc hem led için timer ile nasıl bekleme oluşturayım diye sorup,
hemde isise çamur atmak akıllıca değil demek,
bu pek profesyonel bir yorum değil,
isis tecrübelerime dayanarak çapraz çalışmama (gerçek-isis) durumlarının olduğunu gösterebilirim,
...


Bilmiyorum profesyonel olmakla alakası var mı ama öyle diyorsanız öyledir.Doğrudur yaşanmışlığınız vardır isis ile.Benim o soruyu sormamın sebebi o mantığı kavramamış olmam.Merak da ediyorum.Sayaç bayrağı derken?Sayaç olarak bir değişken tanımlanmayacak mı?Timer int bayraığını mı kastediyorsunuz?

Alıntı yapılan: rree - 25 Temmuz 2013, 15:56:43
Arkadaşlar konu timer ile gecikme yapmak değil.  Yeri ve zamanı geldiğinde timer kesmesini kullanarak hatta real timer programı yazabilirim.
-İsis e benim ihtiyacım oluyor ccs nin delayını kesme içinde  olduğu zaman debug yapmıyor. Onun için delay fonksiyonu yazdım.
  İsteğim daha kısa ve daha kararlı bir yol varmı?

Debug yapmıyor dediğiniz olayı resim ekleyerek gösterir misiniz?Isis debug delay sırasında  varsa main.h dosyasında delay süresince çakılıyor.Delay bitince de normal kodlara devam ediyor.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

RaMu

@yldzelektronik öncelikle yorumu anlayışla karşıladığın için teşekkür ederim.

Evet sayaç için bir veya daha fazla değişken tanımlanacak,
tanımlanan herbir sayaç için birde bayrak tanımlanacak,
linkte örnek var hemen hemen aynısını yazmış olacağım şimdi,
misal
sayac1 ve bayrak1
sayac2 ve bayrak2 tanımladık,
timer kesmesini kurduk misal 1 ms de bir timer kesme veriyor,
biz led1 i yakıp 500 ms bekleyip sonra söndürmek istiyoruz,
aynı zamanda led1 i yaktığımız anda led2 yi yakıp, 1 saniye bekleyip led2 yi söndürmek istiyoruz,

çok değişik şekillerde yapabiliriz bir örnek deneyelim,
led1 i yaktık ve hemen bayrak1 i kurduk sayac1 e 500 yazdık,
led2 yi yaktık ve hemen bayrak2 yi kurduk sayac2 ye 1000 yazdık,

timer interrupt fonksiyonu şunu yapıyor,
bayrak1 aktifse sayac1 i 1 azalt, sayac1 sıfır olduysa bayrak 1 i pasif yap,
bayrak2 aktifse sayac2 yi 1 azalt, sayac2 sıfır olduysa bayrak2 yi pasif yap,

ana döngüde artık biz ledleri yaktıktan sonra söndürme işlemi için bayrak1-bayrak2 pasif oldumu diye bakacağız,
bayrak1 bayrak2 pasif mi kontrolü yaparken aynı zamanda başka kontroller veya başka işlemlerde yapabiliriz.

Şimdi hani mikrosaniye döngüsü diye sorarsan onuda yapabiliriz,
ama genel mantığımız yine bu şekilde olacaktır.
Aslında rtos a da benziyor herhalde, ben rtosdan pek anlamam, en azından hiç rtos uygulaması yapmadım,
bu yüzden kesin birşey söyleyemiyorum.

mesaj birleştirme:: 25 Temmuz 2013, 17:04:07

Alıntı yapılan: rree - 25 Temmuz 2013, 15:56:43
Arkadaşlar konu timer ile gecikme yapmak değil.  Yeri ve zamanı geldiğinde timer kesmesini kullanarak hatta real timer programı yazabilirim.
-İsis e benim ihtiyacım oluyor ccs nin delayını kesme içinde  olduğu zaman debug yapmıyor. Onun için delay fonksiyonu yazdım.
  İsteğim daha kısa ve daha kararlı bir yol varmı?

Sen bu yazdığın fonksiyonu kullanınca isis debug yapabiliyor mu artık,
yani problemi çözüyormu bu yazdığın delay fonksiyonu?
Öyleyse tamamen asm olarak yazman veya daha kısa verimli hale getirmene yardımcı olayım.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html