Pic kesme dallanması

Başlatan salih18200, 19 Ocak 2010, 19:11:20

salih18200

Merhaba arkadaşlar,
Pic uygulamamda üst üste kaç kez kesme içine girebilirim.
mesela rs232 kesme rutini işlendiği sırada i2c kesmesi geldi diyelim bu kesme ilendiği sıradada timer0 kesmesi geldi varsayalım.

Bu şekilde kesme şçşnde kesmeye girmek mümkünmüdür?

aliveli

en fazla bir kesme içerisine girebilirsin
mevcut kesme fonksiyonu bitmeden diğerlerine bakmaz işlemci

FullMetal

Stack pointer dolana kadar.

salih18200

hanginize inanayım  :lol:

Tagli

CCS nasıl çalışıyor bilmiyorum ama olayı assembly ile düşünüp işin özüne inersek normalde kesme geldiğinde GIE kendisi otomatik olarak 0 olur, yani diğer kesmeleri askıda tutar ve iç içe girmeyi önler. Bu sırada diğer kesmeler gelirse kendi bayrakları 1 olur, ama tabi GIE 0 olduğundan askıda kalırlar. Kesme bittiğinde retfie komutu ile çıkarsın genelde ve böylece GIE tekrar 1 olur ve kod tekrardan kesme adresine gider. Peki diyelim ki biz önceki kesmeyi işlerken iki kesme daha geldi farklı kaynaklardan. Hangisini önce yapar? Bu tamamen kesme kodundaki dallanma yapına bağlı. Ama eğer aynı kaynaktan 2 kesme gelmiş olsaydı birini kaçırmış olacaktın. Belki kesme kodunun içinde bir register'ı ayırarak o anda hangi tür kesmelerin işlendiğini kayıt altında tutabilir ve kesme girişinde bu byte'ı kontrol ederek buna göre öncelikleri belirleyebilir, istediğin kesmeyi askıda tutup istediğini önden alabilirsin. Ama hiç tavsiye etmiyorum böyle bir yapıyı. Mutlaka daha sade bir çözümü vardır. Yoksa da daha gelişmiş bir PIC'e geçme zamanı gelmiş demektir.

Ama sen gider de kesme kodu içinde GIE'i 1 yaparsan o zaman iç içe kesme de alırsın. Bu durumda son gelen kesme öncelikli olur. Yığın (stack) dolana kadar da bu işlemi yapabilirsin, sonra PIC sapıtır. Biraz zorlarsan bir sayacı her kesme geldiğinde 1 arttırırsın ve sadece belli sayıda iç içe kesmeye izin verirsin. Ama 16 serisinde yığının neresinde olduğunu sana gösterebilecek bir yapı (stack pointer) yok, eğer kesmenin gelebileceği yerlerde yığının seviyesini kesin olarak bilmen mümkün değilse hiç bulaşma bu işe. Ayrıca zaten son gelen kesmenin öncelikli olması da mantıklı değil. Bir öncekinin işi bitmeden yenisine başlamış olursun.

Biraz da kafadan atmak gerekirse CCS muhtemelen kesmeye girerken GIE'yi 0 yapıyordur (gerçi zaten donanımsal olarak 0 olur, yazılımsal olarak açılmazsa da öyle kalır). Yani iç içe kesme alabileceğini sanmıyorum. 18 serisi falan kullanıyorsan o zaman işler değişir tabi.
Gökçe Tağlıoğlu

salih18200

18f452 kullanıyorum peki kesme içinde kesmeye girdiğimde son girilen kesme işlemi bittiğinde eski kesmede kaldığı yere dönermi..

Tagli

Eğer 18 serisi bir PIC'i yüksek ve düşük öncelikli kesmelerin olduğu modda kullanıyorsan, düşük öncelikli bir kesme işlenirken yüksek öncelikli bir kesme gelirse önce yükseği yapar, sonra düşükte kaldığı yere geri döner. Tam tersi olursa sonra gelen düşük öncelikli kesme askıda kalır, yüksek önceliklinin işi bitince devreye girer.

Uyumluluk modunda çalıştırırsan bir önceki mesajımdaki gibi olur. Kesme ayarlarını yaparken uyumluluk modunda olmadığından emin olmalısın eğer kesme öncelikleri özelliğini kullanmak istiyorsan.
Gökçe Tağlıoğlu

aliveli

Alıntı YapBir kesme meydana geldiğinde o kesme fonksiyonu icra edilirken başka bir kesme meydana gelse dahi aktif olmaz. İlk başta icra edilen kesme fonksiyonunun bitmesi gereklidir. Fakat aynı anda gelen kesmelerde hangi kesmenin geçerli olacağını belirlemek için kesmelere öncelik verilmelidir.

Stack pointer normal fonksiyonlar içindir sanırım 8 adet kadardı. (kesme içinde başka fonksiyonlar çağırıyorsan bunu göz önünde bulundurmalısın)
GEI aktif edilen kesmelere izin vermek için ( #enable_interrupt(kesme adı); )
Kesme meydana geldiğinde program sayıcı o anki değerini stack kaydedicisine atar ve kesme dönüşünde de buradaki adrese bakarak ana programda kaldığı komuttan devam eder.