CCS INTERRUPT HATASI

Başlatan kalman, 15 Haziran 2005, 20:05:35

Erkan Gench

Alıntı yapılan: "SpeedyX"Tartışmayı alevlendirmek için int içerisindeki kod kısa olmalı kesinlikle delay olmamalıya karşı çıkayım.

Merhaba benim söylediğim şey tabiki birden fazla int'in kullanıldığı programlarda geçerli veya tek int kullanılıyorsa int'in her gelişini takip etmenin önemli olduğu programlarda.

İyi ama böyle devrelerde de bu bekleme işini int içinden yapmak zorunda değilsiniz ki. int içerisinde bir flag set olur ana program bunun üzerine gereken yere dallanarak işini yapar. sizin dediğiniz şekilde de iş halledilebilir olsada bu mantığa alışmak bence en iyisi çünkü büyük işlerin altına girdiğinizde bu tür alışkanlıklar sizi baş ağrılarından kurtarıyor.

Alıntı yapılan: "SpeedyX"
CCS çok iyi değildir demişsiniz, peki hangisi gerçekten iyidir (asm hariç)?

bildiğim şey ccs profesyonel bir program değil sık sık hata yapmasını bekleyebilirsiniz, c18 ise çok güzel ama 16 serisi için kullanamazsınız. peki 16 serisi için hangisi iyi derseniz bilmiyorum. hi-tech iyi gibi duruyor ama hiç kullanmadım bilmiyorum.

gie biti int içine girildiğinde otomatik olarak reset olur retfie komutu ilede otomatik olarak set olur(16f84a datasheet s.29). int içerisinde gie'yi kapatmanızın bir anlamı yok fakat açmanız tehlikeli olabilir çünkü int içinden çıkılmadan yeni int gelme ihtimali var.

petek dediğim gibi bende uzun zaman ccs kullandım ve çok memnundum taki büyük bir işte beni rezil edene kadar. ama şunuda söyleyim ben hala küçük işlerde ccs kullanıyorum. ccs gerçekten çok kolay çok kullanışlı ama profesyonel değil sorun burada.

ben daha önce stack problemi ile hiç karşılaşmadım sorun sizin program yazma stilinizden kaynaklanıyor olabilirmi acaba?

karşılaştığım sorunlara gelince birincisi yukarıda anlattıklarım. ikincisi ccs ile pic'e ve yazdığınız programa tam anlamıyla hakim olmanızın zorluğu (örneğin ccs her interrupta girdiğinizde bütün registerleri kaydeder ve sizin int rutininiz 2 bayt bile olsa toplamda bu 30-40 baytı geçer buna müdahele edemiyorsunuz) tabi işler kolaylaştıkça hakimiyetin zorlaşması doğal bir şey. üçüncüsü pointer kullanımındaki sıkıntılar (picin flash'ında bir string yaparsanız buna pointer ile ulaşamıyorsunuz x = TABLE [5]; bu oluyor ama bu olmuyor ptr = &TABLE ;), sonra mevcut rtos'lardan (işletim sistemi) ccs için olanını ben hiç görmedim ama c18 için çok var. ve daha bir çok şey tabi bunlar kötü tarafları iyi taraflarının listesi daha uzun.

şunuda belirteyim ki c18 biraz zordur özellikle ccs'nin rahatlığına alıştıktan sonra fakat buna karşılık alacağınız verim çok daha fazla.

18 serisinin maliyetinin yüksek olması talebin azlığından kaynaklanıyor yoksa gerçekte aradaki fiyat farkı çok az. aslında herkes 16 serisini bırakıp 18'e geçse fiyatta ucuzlar bulmakta kolaylaşır. zaten 18'i biraz kullanınca insanın bir daha 16larla uğraşası gelmiyor çünkü çok fark var.

bu arada kalman o resimdeki elf'mi ork'mu ben çözemedim ikisinede benziyor yoksa karıştırmışlarmı :)
Zorluklar, zamanında yapmamız gerekip de yapmadığımız kolay şeylerin birikmesiyle oluşur. Henry Ford ----------- Ya Rabbi Filistin'deki ve dünyanın her tarafındaki Müslüman kardeşlerime yardım et.

Petek

Alıntı yapılan: "SpeedyX"

#int_rtcc
void RTCC_ISR() {
   x++;
   delay_ms(5000); // 5 Saniye bekle
   if(x==200) x=0;
   }
}

yine bana göre şu şekliyle düzgün çalışmaz, iç içe interrupt alır.
Eğer ISR içerisinde gie otomatik olarak kapatılıp, çıkışta aktif yapılıyorsa yeni birşey daha öğrenmiş olurum.

Bu şekilde çalışmaz. Nedeni ise 2000 ms beklediğinde timer interrupt flagi set edilmiş olur. İnterruptan çıktığın anda ise o flag set edildiği için tekrar interrupta döner. Ama interrupt rutininin sonunda timerflagini resetlersen çıkışta set edilmiş flag olmadığı için normal programa dönersin.
“Önyargıları yıkmak atomu parçalamaktan zordur” A.Einstein

SpeedyX

Teşekkürler arkadaşlar, birşey daha öğrenmiş olduk(GIE).
CCS içinde iyi düşüncelerim vardı, bunlar biraz sarsıldı. CCS ile şimdiye kadar basit sayılabilecek projeler yaptım, assembly ile 6000 satırlık programlar yazdım hiç sorunsuz çalıştılar, kolaylık ve C merakımdan dolayı CCS ile devam etmeye karar verdim ama görüyorumki onun hakkında kötü düşünceler var. Bakalım, daha rezil olmadım hiç ama rezil olma ihtimalinede hazırlıklıyım artık. :)

Şöyle diyebilirmiyiz; ASM>C18>CCS>PBP

Saygılar.

Petek

Alıntı yapılan: "Erkan Gench"
ben daha önce stack problemi ile hiç karşılaşmadım sorun sizin program yazma stilinizden kaynaklanıyor olabilirmi acaba?

Program yazma stilimden kaynaklanamaz, çünkü alt programdan döndüğünde, başka bir alt programın ortasından başlaması ya page yada stack probleminden kaynaklanır. Çözümü alt programların yerlerini değiştirerek bulmuştum.

Alıntı Yap
karşılaştığım sorunlara gelince birincisi yukarıda anlattıklarım. ikincisi ccs ile pic'e ve yazdığınız programa tam anlamıyla hakim olmanızın zorluğu (örneğin ccs her interrupta girdiğinizde bütün registerleri kaydeder ve sizin int rutininiz 2 bayt bile olsa toplamda bu 30-40 baytı geçer buna müdahele edemiyorsunuz) tabi işler kolaylaştıkça hakimiyetin zorlaşması doğal bir şey.

Evet. Şu an yaptığım programda context saving 30-40 adım götürüyor. Bu adımlar kadar timer setinginden eksilterek istediğim zamanı elde ediyorum. abi bu sorun 16 serisi işlemcilerin mimarisinden kaynaklanıyor. En düşük kapasiteli 8051 serisinde bile 11 vektörel interrupt var. Timer için ayrı,  port değişimi için ayrı, kılı için, tüyü için ayrı interruptlar var. 16 serisi piclerde tek interrupt olduğu için, kullanıcı kolay ayırt edebilsin diye CCS de interrupt ta her flagi tek tek kontrol ederek ilgili interrupt rutinine dallanıyor. Bu da tabi interruptta gereksiz zaman kayıplarına neden oluyor. Ben birden fazla interrupta gerek duymadığım için (uart haberleşmesini ana programda rcif, txif polling yaparak izliyorum) CCSnin stantart yöntemini kullandım. Çok hassas iş yapacak olsam #INT_GLOBAL seçeneğini seçerim. Context savingler için ayrı alt programlar yapar, interruptta çağırırım. Bir defa çağırılacağı için CCS bunu alt program olarak değil, normal kod içerisine yerleştiriyor. Amacım interrupt içerisinde bir bit set edip çıkmak ise zaten ona da gerek kalmaz (bitset bit clear status registerinin içeriğini, wregi, fsr yi, pclathi değiştirmediği için).

Alıntı Yap
üçüncüsü pointer kullanımındaki sıkıntılar (picin flash'ında bir string yaparsanız buna pointer ile ulaşamıyorsunuz x = TABLE [5]; bu oluyor ama bu olmuyor ptr = &TABLE ;),

Bunda haklısınız. Bir sorun da string içerisinde 0 rakamını yerleştiremiyorsunuz. 0 ı görünce string sonu olarak görüyor. Oysa LCD deki ilk 8 baytta kendim karakter tanımlıyorum ve 0. bayttaki karakteri bastırtamıyorum.

Jal de flash_get, flash_put komutları vardı. Benzeri CCS de de var. Bunlarla ROM alanında istenilen şeyler yapılabilir ama tabi standart C den ayrılıyorsunuz. Bu yöntemle bir adrese 2 karakter sığdırılabiliyor. 14 bit üzerinde 2 karakter sığdırılabiliyor. Ama bu da zahmetli bir iş. Bir ara (sanıyorum) CCS'nin bunu otomatik yaptığını okumuştum.

Alıntı Yap
sonra mevcut rtos'lardan (işletim sistemi) ccs için olanını ben hiç görmedim ama c18 için çok var. ve daha bir çok şey tabi bunlar kötü tarafları iyi taraflarının listesi daha uzun.

RTOS lar ile hiç çalışmadım. O nedenle de tam olarak bir yorum veremeyeceğim. CCS'nin bir dezavantajı da object kod üretmiyor. O nedenle object kodlu yabancı sub programlar CCS rutinleri ile birlikte link edilemiyor. CC5X te bu var.

Alıntı Yap
şunuda belirteyim ki c18 biraz zordur özellikle ccs'nin rahatlığına alıştıktan sonra fakat buna karşılık alacağınız verim çok daha fazla.
18 serisinin maliyetinin yüksek olması talebin azlığından kaynaklanıyor yoksa gerçekte aradaki fiyat farkı çok az. aslında herkes 16 serisini bırakıp 18'e geçse fiyatta ucuzlar bulmakta kolaylaşır. zaten 18'i biraz kullanınca insanın bir daha 16larla uğraşası gelmiyor çünkü çok fark var.

Bu görüşlerinize katılıyorum. Ama 16F84 üzerinde (video çıkışı ve 2 oyun konsolü bağlı) tetris ve tenis oyun programı yapıldığına göre 16 serisinde hala çok kabiliyet var. Yeterki bizde kodlamada optimizasyon alışkanlığı gelişsin.

CCS de sıkıntı da şurada gördüm. Diyelim 16 bit büyüklüğünde bir structure tanımlayacaksınız. Bunun ilk 5 biti integer olsun. Sonraki 4 biti integer olsun diyemiyorsunuz. Çünkü 8 biti aştınız. 5 bitlik tanımdan sonra en fazla 3 bitlik bir değişken tanımlayabiliyorsunuz.

Bir dezavantaj da 24 bitlik değişken tanımlayamıyor olmamız. Tabi bunun avantaj ve dezavantajları var. Bütün programda 32 bitlik aritmetik yapmıyor iseniz 24 bit tanımlar aritmetik işlemlerde hem hız hem boyut açısından avantaj sağlıyor. Ama karışık kullanıyorsanız bu sefer hem 32 bit için hem 24 bit için aritmetik işlem rutinleri programa yerleşiyor ve bu da program alanınızın kapasitesini arttırıyor.
“Önyargıları yıkmak atomu parçalamaktan zordur” A.Einstein

Petek

Alıntı yapılan: "kalman"
Öğrenilmesi kolay denilen bir derleyicinin hatalı olduğu halde tavsiye edilmesi bence doğru değil ve bu açıkca belirtilmesi gerekir

Buna kesinlikle katılmıyorum. Her derleyicide bug olabilir ve sonraki versiyonlarda bu giderilir. Ben ticari olarak pazarlanan LAHEY fortran derleyicisinde bile bug bulmuştum. Aynı program LAHEY f77 de farklı, Linux altındaki g77 farklı sonuç veriyordu. İlginç tir g77 doğru hesaplamıştı (IBM Risc6000 ile kontrol etmiştim).

Senin programın için CCS nin neresi hatalı olduğunu söyleyebilirmisiniz? Programın tamamını ve ISIS dosyasını biryere yükleyin, ben bakıp size sizin hatanız göstereyim.
“Önyargıları yıkmak atomu parçalamaktan zordur” A.Einstein

Erkan Gench

Alıntı yapılan: "Petek"sorun 16 serisi işlemcilerin mimarisinden kaynaklanıyor.

buradaki context saving ile interrupt geldiğinde hangisinin servis göreceğinin belirlenmesi ayrı bir şey. int geldiğinde hangisine dallanılmasına karar verme ihtiyacı pic'lerin genelinde var

Fakat benim bahsettiğim ve sizinde değindiğiniz context saving olayı sizin int içine girdiğinizde yapacağınız işlemler eğer register'lardan bazılarını etkileyecekse bunların int'e girmeden kayıt edilmesi ve çıkışta tekrar geri yüklenmesi olayı.

aslında normalde siz int rutininizi yazarsınız int içerisinde etkilenen reg'leri lst dosyasından bulursunuz ve bunları (eğer otomatik save edilmiyorsa) kaydedersiniz ve çıkışta geri yüklersiniz. fakat ccs böyle yapmıyor sizin int içinde hiç bir reg etkilenmese bile hepsini kaydediyor ve çıkışta geri yüklüyor. siz aman int kısa olsun fazla yer kaplamasın diyorken bir sürü zaman kaybediyorsunuz. aslında 16 serisinde bu o kadar büyük bir kodda üretmiyor (nispeten) fakat 18 serisine gelince ciddi miktarda gereksiz zaman kaybına neden oluyor.

buraya dikkat ederseniz aslında ccs'nin böyle yapması hobi amaçlı kullanıcılara en uygun şey çünkü kimse her bir int yazdığında lst dosyasını kurcalayıp zahmete girmek istemez bunu ccs'nin yapması büyük kolaylık fakat iş profesyonel olunca ve mikro saniyeler önem kazanınca dediğim şey anlaşılmaya başlıyor sanırım. bu zaten bir örnek sadece ve ileride bunu düzeltmeleri fikrimi değiştiremez çünkü compiler'ın mantığı belli.

ancak bu anlattıklarım ccs düşmanlığı olarak algılanmasın :) benim amacım büyük sayılabilecek işlere ccs ile girip sıkıntı yaşamamanızı istiyor olmam yoksa ben ccs'yi kullanabiliyor olmaktan memnunum.

bu arada string içerisine 0 yerleştirebilirsiniz fakat bu diziyi karakter dizisi olarak kullanamazsınız çünkü karakter dizilerinde 0 rakamı (aslında NULL karakteri) dizi sonunu gösterir. bu c'nin bir özelliği ayrıca çok kolaylık sağlayan uygulamaları var.
Zorluklar, zamanında yapmamız gerekip de yapmadığımız kolay şeylerin birikmesiyle oluşur. Henry Ford ----------- Ya Rabbi Filistin'deki ve dünyanın her tarafındaki Müslüman kardeşlerime yardım et.

Petek

Alıntı yapılan: "Erkan Gench"
Alıntı yapılan: "Petek"sorun 16 serisi işlemcilerin mimarisinden kaynaklanıyor.
buradaki context saving ile interrupt geldiğinde hangisinin servis göreceğinin belirlenmesi ayrı bir şey. int geldiğinde hangisine dallanılmasına karar verme ihtiyacı pic'lerin genelinde var
Fakat benim bahsettiğim ve sizinde değindiğiniz context saving olayı sizin int içine girdiğinizde yapacağınız işlemler eğer register'lardan bazılarını etkileyecekse bunların int'e girmeden kayıt edilmesi ve çıkışta tekrar geri yüklenmesi olayı.

aslında normalde siz int rutininizi yazarsınız int içerisinde etkilenen reg'leri lst dosyasından bulursunuz ve bunları (eğer otomatik save edilmiyorsa) kaydedersiniz ve çıkışta geri yüklersiniz. fakat ccs böyle yapmıyor sizin int içinde hiç bir reg etkilenmese bile hepsini kaydediyor ve çıkışta geri yüklüyor. siz aman int kısa olsun fazla yer kaplamasın diyorken bir sürü zaman kaybediyorsunuz. aslında 16 serisinde bu o kadar büyük bir kodda üretmiyor (nispeten) fakat 18 serisine gelince ciddi miktarda gereksiz zaman kaybına neden oluyor.

Erkan Bey, biliyorum ikisinin farklı olduğunu. Ben context saving haricinde bir de kullanıcı hangi interrupt için rutin yazmışsa onun şartı oluşmuş mu belirleyen ilave kodlar koyduğundan bahsetmek istemiştim. Bir tek interrupt rutinim var ve onda bile flag set edilmişmi diye bakıyor ve onunla ilgi rutini yerleştirdiği yere goto yapıyor bu da gereksiz yer ve zaman kaybı oluşturuyor demek istiyordum.

Sizin dediğinize katılmadım anlamı çıkmasın. Örneğin context savingde mesela hiç kullanmadığım halde 32 bit integer yada floating point için kullandığı 8 baytı alıp saklıyor ve rutinden çıkarken geri yerleştiriyor. Bunlar gereksiz şeyler bence de. Derleyicinin 32 bit aritmetik kullanıp kullanılmadığını tespit etmesi gerekir ve kullanılmamış ise bu adımları pas geçmesi gerekir. Fazladan gereksiz yere 30un üzerinde adım ve program alanı kaybı oluşuyor. Benzer şekilde interruptta ayrıca fsr ve indf kullanmıyor olsam da bunları saklıyor. Bunda hemfikiriz zaten. İşte bunun için profesyonel kullanıcılara yönelik "#int_global" direktifini eklemişler diyorum. Kullanıcı kendi ihtiyacına göre interrupt rutinlerde context savingini kendisi yapabilmesi için gerekli esnekliği sağlamışlar.

Benzer esneklik (aynısı değil) C18 de de var ve opsiyon olarak kullanıcı hangilerinin saklanmasını istediğini belirtebiliyor.

Alıntı Yap
buraya dikkat ederseniz aslında ccs'nin böyle yapması hobi amaçlı kullanıcılara en uygun şey çünkü kimse her bir int yazdığında lst dosyasını kurcalayıp zahmete girmek istemez bunu ccs'nin yapması büyük kolaylık fakat iş profesyonel olunca ve mikro saniyeler önem kazanınca dediğim şey anlaşılmaya başlıyor sanırım. bu zaten bir örnek sadece ve ileride bunu düzeltmeleri fikrimi değiştiremez çünkü compiler'ın mantığı belli.

ancak bu anlattıklarım ccs düşmanlığı olarak algılanmasın :) benim amacım büyük sayılabilecek işlere ccs ile girip sıkıntı yaşamamanızı istiyor olmam yoksa ben ccs'yi kullanabiliyor olmaktan memnunum.

bu arada string içerisine 0 yerleştirebilirsiniz fakat bu diziyi karakter dizisi olarak kullanamazsınız çünkü karakter dizilerinde 0 rakamı (aslında NULL karakteri) dizi sonunu gösterir. bu c'nin bir özelliği ayrıca çok kolaylık sağlayan uygulamaları var.

Öyle olduğunu biliyorum ve başka yolu denedim.lcd_putc(0) ama o da çalışmıyor. Jal de bunlar hiç sorun olmuyordu.

Bir de CCS de şunu yapamıyorum. örneğin "const char z[10]={4,"al",3,2,"ma"}" yani "Çalışma" kelimesini yükleyeceğim. Ç,ı,ş LCD sembolü olarak tanımlanmış. Bunda ben mi hata yapıyorum, tam olarak anlayamadım. Her birini karakter olarak yüklemek istedim {4,"a","l",3,2,"m","a"} buda olmadı. Oturup ta a, l, m nin ascii karşılıklarını yazsam olacak ama bu durumda da program takibi zorlaşacak. Böyle bir şeyi siz nasıl yapardınız?

Konu dışına mı çıktık acaba ? :D
“Önyargıları yıkmak atomu parçalamaktan zordur” A.Einstein

kalman

@petek

program deneme amaçlı sadece interrupt deneniyor tümü ilk başta yazdığım program zaten onuda ekledim :?  :?
benim amacım ccs de interrupt denemekti sen istersen bunu isis le deneyebilirsin ve çalışan bir programı yazar verirsen buda herkese ulaşır



Arkadaşlar bakıyorum derin konulara girmişsiniz tebrikler fakat problemle
ilgili çözüm pek konuşulmuyor eminim herkes bu konuda merakla çözüm bekliyor CCS bunu becerebiliyormu!!!!  bu konuda Petek e katılmıyorum
eğer ccs bu konuda başarızsa bu bence BUG olayını aşar çünkü MCU lar
genelde ISR kaynaklarıyla değer kazanır ve bir çok konuda ISR kullanlır
eğer bunu CCS tam anlamıyla yapamıyorsa ve diğer derleyicilerdede hatalar var demeniz ve bunu bir tutmanız bence doğru değil hata her derleyicide olabilir önemli olan hatanın hangi şartlarda çıktığı



Saygılarımla

Petek

Alıntı yapılan: "kalman"@petek
program deneme amaçlı sadece interrupt deneniyor tümü ilk başta yazdığım program zaten onuda ekledim :?  :?
benim amacım ccs de interrupt denemekti sen istersen bunu isis le deneyebilirsin ve çalışan bir programı yazar verirsen buda herkese ulaşır

CCS örnek programlarında zaten bir örnek var. Adam klavye yapmış ve hangi tuşa basıldığını tespit ediyor.

Programının başında işlemcinin ne olduğu yazılmamış. Eğer onlar interrupt.h içerisinde ise onu da gönderiver bi zahmet. Öyle kontrol edelim.

Alıntı Yap
Arkadaşlar bakıyorum derin konulara girmişsiniz tebrikler fakat problemle
ilgili çözüm pek konuşulmuyor eminim herkes bu konuda merakla çözüm bekliyor CCS bunu becerebiliyormu!!!!  bu konuda Petek e katılmıyorum
eğer ccs bu konuda başarızsa bu bence BUG olayını aşar çünkü MCU lar
genelde ISR kaynaklarıyla değer kazanır ve bir çok konuda ISR kullanlır
eğer bunu CCS tam anlamıyla yapamıyorsa ve diğer derleyicilerdede hatalar var demeniz ve bunu bir tutmanız bence doğru değil hata her derleyicide olabilir önemli olan hatanın hangi şartlarda çıktığı

Saygılarımla

CCS'nin interrupt rutinlerinde hata olamaz. Defalarca denemiş ve örnek programda paketine eklenmiş. Sen kodun tamamını gönder öyle bir daha bakalım.

Her yeni versiyon çıkmadan önce "test suit" denilen örnek programlar tekrar denenir ve önceki versiyonda çalışan, yeni versiyonda çalışmaz ise çalışıncaya kadar düzeltilir ve piyasaya sürülür. O nedenle CCS'nin interrupt rutinlerinde hata yok. Sadece hantallık var. Ama profesyoneller için de esneklik var diyorum.
“Önyargıları yıkmak atomu parçalamaktan zordur” A.Einstein

z

Alıntı yapılan: "SpeedyX"Tartışmayı alevlendirmek için int içerisindeki kod kısa olmalı kesinlikle delay olmamalıya karşı çıkayım.

Iyi bende alevlendireyim o zaman:

Interrupt olayini gunluk hayatta arkadasinizla konusurken (yada kafa kafaya vermis is yaparken) 3. kisinin gelip konusmaya aradan dalma istegine benzetebiliriz.

Eger 3.kisi lavugun teki ise genelde hastir len deriz. (Hatta cok kizmissak, sana ..k yemek duser diyip bir sure gelmesin diye kapisini kitleriz)

Ama gelen bir mudur ise konusmamizi keser evet efendim sizi dinliyorum gibi yalakalik moduna geceriz.

Mudurun bir an once basimizdan def edilmesi gerekir cunku arkadasimizla yaptigimiz sohbetimiz (is calismasi) engellemistir.

Ancak her an icin ayni yada daha yuksek mevkide bir baska mudurun gelmesi olasidir ve istegi kesinlikle yerine getirilmelidir. Aksi halde kendinizi kapi onunde bulabilirsiniz. Bu durumda araya giren isi en kisa zamanda yapabilmeli yada gorevi birilerinin ustune yikabilmelisiniz. Aksi halde hem asil isinizi hemde yeni angarya isi sizin yapmaniz ve basarili olma zorunlulugunuz bulunmaktadir.

Sirket (Donanim) , mudurleri siraya sokan genel istekleri duzenleme muduru gibi bir mudure sahip değilse (Interrupt priority controller) mudurler zirt pirt basiniza ususur sizden, kendi mevkisine bakmadan  sirf mudur oldugu icin is talebinde bulunur ve hemen yapilmasini ister bu durumda bazi mudurlerin isleri yapsaniz dahi oncelikli mudurlerin isleri yapmadiginiz icin kapi onune konursunuz.

Zira dur bekle su anda ilk mudurun isine basladim ama sonuclanmadi sonuclana kadar cay icecegim (500ms beklemek gibi) sonra gel diyemezsiniz.

---------------------------

Donanimda interrupt kaynaklari cokca ve isteklerin hemen cevaplanmasi gerekiyorsa intterrupt programlari hizli calisan turden yazilmalidir.

Ayrica ayni interrupt kisa zaman araliklariyla pes pese gelebilir. Donanim bunlarin sayisini da tutamiyorsa genelde siz sadece 2 tanesini cevapliyabileceksiniz demektir.

Tabiki yukarda yazdigim senaryo kritik islemeri konu almistir, ancak int kodlarini kisa yazmak genelde ana amac olmali ve aliskanlik haline getirilmelidir.

Kalman, Port A ve Port B icin yazilan programlarin ayri ayri  asm kodlarini gonderseydin su ana kadar sorunun nerde oldugu coktan anlasilacakti.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Petek

Kalman,

sen yazdığın programı gerçek devre üzerinde mi deniyorsun yoksa isis üzerinde mi?

ISIS ta baktım, interrupta giriyor, fakat çıkışta rbif i resetlemiyor. CCS resetlemek için gerekeni yapmış. Bir de ben interrupt rutininde kendim intcon,rbif i resetlemeye çalıştım ama ISIS bu flagi resetlemiyor. ISISte bug var. Zaten ISIS te debug işlemlerinde arasıra hata çıkıyor. 6.2 versiyonunda breakpoint yerlerini bile şaşırıyordu. LED'i pin_b1 e bağlayınca flag resetleniyor.
“Önyargıları yıkmak atomu parçalamaktan zordur” A.Einstein

kalman

@ selam Arkadaşlar

İşte çalışan versiyonu

#include <16F84A.h>
#fuses NOWDT,XT, NOPUT, NOPROTECT
#use delay(clock=4000000)

#define LED PIN_B1 //  Çalisan versiyon


#int_RB // Interrupt
LED_YAK()
{
disable_interrupts(GLOBAL);
output_high(LED);
delay_ms(100);

}

void main() {

set_tris_a(0b00000);
set_tris_b(0b00110000); // RB4 ve RB5 giris

setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
enable_interrupts(INT_RB);
  enable_interrupts(GLOBAL);




while (1)
{
output_low(LED); //LED söndür

}

}




Buda çalışmayan versiyonu

#include <16F84A.h>
#fuses NOWDT,XT, NOPUT, NOPROTECT
#use delay(clock=4000000)

#define LED PIN_A1 //  Çalismayan versiyon


#int_RB // Interrupt
LED_YAK()
{
disable_interrupts(GLOBAL);
output_high(LED);
delay_ms(100);

}

void main() {

set_tris_a(0b00000);
set_tris_b(0b00110000); // RB4 ve RB5 giris

setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
enable_interrupts(INT_RB);
  enable_interrupts(GLOBAL);




while (1)
{
output_low(LED); //LED söndür

}

}



İşte çalışan versiyonun LST file

Filename: G:\testler\interrupt16f84.LST

              ROM used: 113 words (11%)
                        Largest free fragment is 911
              RAM used: 8 (12%) at main() level
                        9 (13%) worst case
              Stack:    2 worst case (0 in main + 2 for interrupts)

*
0000:  MOVLW  00
0001:  MOVWF  0A
0002:  GOTO   050
0003:  NOP
0004:  BTFSC  03.5
0005:  GOTO   00A
0006:  MOVWF  0E
0007:  SWAPF  03,W
0008:  MOVWF  0F
0009:  GOTO   00F
000A:  BCF    03.5
000B:  MOVWF  0E
000C:  SWAPF  03,W
000D:  MOVWF  0F
000E:  BSF    0F.1
000F:  MOVF   0A,W
0010:  MOVWF  13
0011:  CLRF   0A
0012:  BCF    03.7
0013:  SWAPF  0E,F
0014:  MOVF   04,W
0015:  MOVWF  10
0016:  MOVF   0C,W
0017:  MOVWF  11
0018:  MOVF   0D,W
0019:  MOVWF  12
001A:  BCF    03.5
001B:  BTFSS  0B.3
001C:  GOTO   01F
001D:  BTFSC  0B.0
001E:  GOTO   043
001F:  MOVF   10,W
0020:  MOVWF  04
0021:  MOVF   11,W
0022:  MOVWF  0C
0023:  MOVF   12,W
0024:  MOVWF  0D
0025:  MOVF   13,W
0026:  MOVWF  0A
0027:  SWAPF  0F,W
0028:  MOVWF  03
0029:  BCF    03.5
002A:  SWAPF  0E,W
002B:  BTFSC  0F.1
002C:  BSF    03.5
002D:  RETFIE
....................  #include <16F84A.h>
....................  //////// Standard Header file for the PIC16F84A device ////////////////  
.................... #device PIC16F84A  
.................... #list  
....................  
.................... #fuses NOWDT,XT, NOPUT, NOPROTECT  
.................... #use delay(clock=4000000)  
002E:  MOVLW  14
002F:  MOVWF  04
0030:  MOVF   00,W
0031:  BTFSC  03.2
0032:  GOTO   042
0033:  MOVLW  01
0034:  MOVWF  0D
0035:  CLRF   0C
0036:  DECFSZ 0C,F
0037:  GOTO   036
0038:  DECFSZ 0D,F
0039:  GOTO   035
003A:  MOVLW  4A
003B:  MOVWF  0C
003C:  DECFSZ 0C,F
003D:  GOTO   03C
003E:  NOP
003F:  NOP
0040:  DECFSZ 00,F
0041:  GOTO   033
0042:  GOTO   04D (RETURN)
....................  
.................... #define LED PIN_B1 //  Çalisan versiyon  
....................  
....................  
.................... #int_RB // Interrupt  
.................... LED_YAK()  
.................... {  
.................... disable_interrupts(GLOBAL);  
0043:  BCF    0B.7
0044:  BTFSC  0B.7
0045:  GOTO   043
.................... output_high(LED);  
0046:  BSF    03.5
0047:  BCF    06.1
0048:  BCF    03.5
0049:  BSF    06.1
.................... delay_ms(100);  
004A:  MOVLW  64
004B:  MOVWF  14
004C:  GOTO   02E
....................  
.................... }  
....................  
004D:  BCF    0B.0
004E:  BCF    0A.3
004F:  GOTO   01F
.................... void main() {  
....................  
0050:  CLRF   04
0051:  MOVLW  1F
0052:  ANDWF  03,F
.................... set_tris_a(0b00000);  
0053:  MOVLW  00
0054:  TRIS   5
.................... set_tris_b(0b00110000); // RB4 ve RB5 giris  
0055:  MOVLW  30
0056:  TRIS   6
....................  
.................... setup_counters(RTCC_INTERNAL,RTCC_DIV_2);  
0057:  CLRF   0C
0058:  BTFSS  0C.3
0059:  GOTO   062
005A:  MOVLW  07
005B:  CLRF   01
005C:  MOVLW  81
005D:  MOVWF  04
005E:  MOVF   00,W
005F:  ANDLW  C0
0060:  IORLW  0F
0061:  MOVWF  00
0062:  CLRWDT
0063:  MOVLW  81
0064:  MOVWF  04
0065:  MOVF   00,W
0066:  ANDLW  C0
0067:  IORWF  0C,W
0068:  MOVWF  00
....................  enable_interrupts(INT_RB);  
0069:  BSF    0B.3
....................    enable_interrupts(GLOBAL);  
006A:  BSF    0B.7
....................  
....................  
....................  
....................  
.................... while (1)  
.................... {  
.................... output_low(LED); //LED söndür  
006B:  BSF    03.5
006C:  BCF    06.1
006D:  BCF    03.5
006E:  BCF    06.1
....................  
.................... }  
006F:  GOTO   06B
....................  
.................... }  
....................  
0070:  SLEEP

Configuration Fuses:
  Word  1: 3FF9   XT NOWDT NOPUT NOPROTECT




Buda çalışmayan versiyonunun LST File


Filename: G:\testler\interrupt16f84.LST

              ROM used: 113 words (11%)
                        Largest free fragment is 911
              RAM used: 8 (12%) at main() level
                        9 (13%) worst case
              Stack:    2 worst case (0 in main + 2 for interrupts)

*
0000:  MOVLW  00
0001:  MOVWF  0A
0002:  GOTO   050
0003:  NOP
0004:  BTFSC  03.5
0005:  GOTO   00A
0006:  MOVWF  0E
0007:  SWAPF  03,W
0008:  MOVWF  0F
0009:  GOTO   00F
000A:  BCF    03.5
000B:  MOVWF  0E
000C:  SWAPF  03,W
000D:  MOVWF  0F
000E:  BSF    0F.1
000F:  MOVF   0A,W
0010:  MOVWF  13
0011:  CLRF   0A
0012:  BCF    03.7
0013:  SWAPF  0E,F
0014:  MOVF   04,W
0015:  MOVWF  10
0016:  MOVF   0C,W
0017:  MOVWF  11
0018:  MOVF   0D,W
0019:  MOVWF  12
001A:  BCF    03.5
001B:  BTFSS  0B.3
001C:  GOTO   01F
001D:  BTFSC  0B.0
001E:  GOTO   043
001F:  MOVF   10,W
0020:  MOVWF  04
0021:  MOVF   11,W
0022:  MOVWF  0C
0023:  MOVF   12,W
0024:  MOVWF  0D
0025:  MOVF   13,W
0026:  MOVWF  0A
0027:  SWAPF  0F,W
0028:  MOVWF  03
0029:  BCF    03.5
002A:  SWAPF  0E,W
002B:  BTFSC  0F.1
002C:  BSF    03.5
002D:  RETFIE
....................  #include <16F84A.h>
....................  //////// Standard Header file for the PIC16F84A device ////////////////  
.................... #device PIC16F84A  
.................... #list  
....................  
.................... #fuses NOWDT,XT, NOPUT, NOPROTECT  
.................... #use delay(clock=4000000)  
002E:  MOVLW  14
002F:  MOVWF  04
0030:  MOVF   00,W
0031:  BTFSC  03.2
0032:  GOTO   042
0033:  MOVLW  01
0034:  MOVWF  0D
0035:  CLRF   0C
0036:  DECFSZ 0C,F
0037:  GOTO   036
0038:  DECFSZ 0D,F
0039:  GOTO   035
003A:  MOVLW  4A
003B:  MOVWF  0C
003C:  DECFSZ 0C,F
003D:  GOTO   03C
003E:  NOP
003F:  NOP
0040:  DECFSZ 00,F
0041:  GOTO   033
0042:  GOTO   04D (RETURN)
....................  
.................... #define LED PIN_A1 //  Çalismayan versiyon  
....................  
....................  
.................... #int_RB // Interrupt  
.................... LED_YAK()  
.................... {  
.................... disable_interrupts(GLOBAL);  
0043:  BCF    0B.7
0044:  BTFSC  0B.7
0045:  GOTO   043
.................... output_high(LED);  
0046:  BSF    03.5
0047:  BCF    05.1
0048:  BCF    03.5
0049:  BSF    05.1
.................... delay_ms(100);  
004A:  MOVLW  64
004B:  MOVWF  14
004C:  GOTO   02E
....................  
.................... }  
....................  
004D:  BCF    0B.0
004E:  BCF    0A.3
004F:  GOTO   01F
.................... void main() {  
....................  
0050:  CLRF   04
0051:  MOVLW  1F
0052:  ANDWF  03,F
.................... set_tris_a(0b00000);  
0053:  MOVLW  00
0054:  TRIS   5
.................... set_tris_b(0b00110000); // RB4 ve RB5 giris  
0055:  MOVLW  30
0056:  TRIS   6
....................  
.................... setup_counters(RTCC_INTERNAL,RTCC_DIV_2);  
0057:  CLRF   0C
0058:  BTFSS  0C.3
0059:  GOTO   062
005A:  MOVLW  07
005B:  CLRF   01
005C:  MOVLW  81
005D:  MOVWF  04
005E:  MOVF   00,W
005F:  ANDLW  C0
0060:  IORLW  0F
0061:  MOVWF  00
0062:  CLRWDT
0063:  MOVLW  81
0064:  MOVWF  04
0065:  MOVF   00,W
0066:  ANDLW  C0
0067:  IORWF  0C,W
0068:  MOVWF  00
....................  enable_interrupts(INT_RB);  
0069:  BSF    0B.3
....................    enable_interrupts(GLOBAL);  
006A:  BSF    0B.7
....................  
....................  
....................  
....................  
.................... while (1)  
.................... {  
.................... output_low(LED); //LED söndür  
006B:  BSF    03.5
006C:  BCF    05.1
006D:  BCF    03.5
006E:  BCF    05.1
....................  
.................... }  
006F:  GOTO   06B
....................  
.................... }  
....................  
0070:  SLEEP

Configuration Fuses:
  Word  1: 3FF9   XT NOWDT NOPUT NOPROTECT


Hepsi bu kadar umarım bu yeterli gelir

Saygılarımla

SpeedyX

Alıntı yapılan: "bunalmis"Iyi bende alevlendireyim o zaman
...
Tabiki yukarda yazdigim senaryo kritik islemeri konu almistir, ancak int kodlarini kisa yazmak genelde ana amac olmali ve aliskanlik haline getirilmelidir.
Katılıyorum, sadece int içinde delay kesinlikle kullanılmaza karşı çıktım.
Birden fazla int kullanılan bir ortamda tabiki interrupt alt programları olabildiğince kısa olmalıdır. Mantıklı ve doğru olan da budur.

Aslında bu tartışma çok güzel ilerliyor, öğretici bir tartışma oluyor. Birilerinin derin mevzulara girmesi gerekiyor :)
Derslerden ve kedimden vakit buldukça bende katılırım.

Bu resmi niye verdim bilmiyorum

Petek

Alıntı yapılan: "Petek"Kalman,

sen yazdığın programı gerçek devre üzerinde mi deniyorsun yoksa isis üzerinde mi?

ISIS ta baktım, interrupta giriyor, fakat çıkışta rbif i resetlemiyor. CCS resetlemek için gerekeni yapmış. Bir de ben interrupt rutininde kendim intcon,rbif i resetlemeye çalıştım ama ISIS bu flagi resetlemiyor. ISISte bug var. Zaten ISIS te debug işlemlerinde arasıra hata çıkıyor. 6.2 versiyonunda breakpoint yerlerini bile şaşırıyordu. LED'i pin_b1 e bağlayınca flag resetleniyor.

Unuttuğum bir şey daha var eklemek istiyorum. Interrupt rutininde en az debounce süresi kadar bir delay olmalı. Tabi bu portb<7:4> seviye değişimini butonla yapıyorsan gerekli. Yoksa her interrupt dönüşünde (debounce süresince) tekrar tekrar interrupta gitme ihtimalin var.

Bir hata da L_TO_H seviye değişiminde interrupt'a git demişsin. Bu  external interrupt için (pin_b0) gerekli. #Int_rb de port_b<7:4> hem L_TO_H, hem de H_TO_L geçişlerinde interrupt üretir. Butona bastın interrupt, çektin interrupt dallanması olur. Debouns süresince seviye sıkça değiştiği için bu interrupta birkaç defa gidebilirsin. Senin programda bu önemli değil zira 500ms delay koymuşsun, bu arada defalarca flag set edilir ama 25-50 ms kadar sonra (bir de butondan elini çekince) durulur. Zaten 500 ms de herşey bittiği için interrupt dönüşünde CCS tarafından rbif reset ediliyor.
“Önyargıları yıkmak atomu parçalamaktan zordur” A.Einstein

Petek

Kalman,

ISIS te hem pin_b1 e hem de pin_a1 e led bağladım. Simulasyon düzgün çalıştı. her ikisi de yanıp sönüyor. Sorun ISISte.

pin_b4 e clock kaynağı bağla (periyodu 2 saniye olsun). Her çıkşta ve inişte interrupt tetikleniyor.  her iki led de yarım saniye yanıp sönüyor.
“Önyargıları yıkmak atomu parçalamaktan zordur” A.Einstein