8051(At89s52) de kesme içinde kesme gelirse ne olur ?

Başlatan AsHeS, 12 Haziran 2013, 15:14:56

AsHeS

C51 de tanımladığım timer0 ve int0 düşen kenar kesmesini  kullanıyorum. Timer0 kesmesine girdiğimde int0 kesmesine girebilecek şekilde registerleri ayarlasam , timer0 kesmesi işlenirken int0 kesmesi gelse buradan tekrar timer0 kesmesinde kaldığı yere ve buradan da main e geri dönebilir mi?
Sorumun dayanağı 89s52 de stack in 1 bytedan fazla olması ve kesme vektörlerinin 1 den çok olması.

magnetron

8051 de interrupt priority IP registeri var

buradan kesmelerin biribirine üstünlüğü ayarlanabiliyor

ya high ya da low priority olabiliyor
böylece bir kesme işleniyorken diğeri gelirse yeni gelene zıplayabilir

ama 8051 de kesme routinlerinde kesmenin kullandığı bütün registerleri stack'e push ve çıkarken pop yapman lazım

otomatik yapmıyor

AsHeS

Alıntı yapılan: magnetron - 12 Haziran 2013, 15:23:52
8051 de interrupt priority IP registeri var

buradan kesmelerin biribirine üstünlüğü ayarlanabiliyor

ya high ya da low priority olabiliyor
böylece bir kesme işleniyorken diğeri gelirse yeni gelene zıplayabilir

ama 8051 de kesme routinlerinde kesmenin kullandığı bütün registerleri stack'e push ve çıkarken pop yapman lazım

otomatik yapmıyor
c51 de kendi hallediyor diye biliyorum.

magnetron

ben 8051 Assembler ile programladığım için push pop yapman lazım dedim

C51 de sen haklı olabilirsin C51 ile çalışmadım

fgokcegoz

Alıntı yapılan: magnetron - 12 Haziran 2013, 15:23:52
8051 de interrupt priority IP registeri var

buradan kesmelerin biribirine üstünlüğü ayarlanabiliyor

ya high ya da low priority olabiliyor
böylece bir kesme işleniyorken diğeri gelirse yeni gelene zıplayabilir

ama 8051 de kesme routinlerinde kesmenin kullandığı bütün registerleri stack'e push ve çıkarken pop yapman lazım

otomatik yapmıyor

8051 deki priority, aynı anda kesme gelmesi durumunda önem kazanır. Yani aynı anda iki kesme gelirse önceliği olan kesmeye dallanılır. Eğer öncelik(priorty) ayarlanmamışsa, default kesme önceliğine göre hareket eder. Kesme içinde kesme gelirsede muhtemelen ikinci kesme kaçırılacaktır. Yada içerisinde bulunulan kesme alt programı tamamlandığında diğerine gidebilir...
"Vicdanın ziyası, ulûm-u diniyedir. Aklın nuru, fünun-u medeniyedir. İkisinin imtizacıyla hakikat tecelli eder." (Bediüzzaman Said Nursi)

AsHeS

Alıntı yapılan: fgokcegoz - 12 Haziran 2013, 17:29:22
8051 deki priority, aynı anda kesme gelmesi durumunda önem kazanır. Yani aynı anda iki kesme gelirse önceliği olan kesmeye dallanılır. Eğer öncelik(priorty) ayarlanmamışsa, default kesme önceliğine göre hareket eder. Kesme içinde kesme gelirsede muhtemelen ikinci kesme kaçırılacaktır. Yada içerisinde bulunulan kesme alt programı tamamlandığında diğerine gidebilir...
Şimdi durum şu hocam 1 saniye geçtiğini anlamak için 50 ms de bir kesmeye gönderiyorum(timer0) fakat sayılacak saniye sayısını da INT0 ucuna gelen düşen kenardan artırıyorum yani timer0 kesmesindeyken INT0 düşen kenarı gelmesi sistemin en kötü durumu oluyor.

fgokcegoz

Alıntı yapılan: AsHeS35 - 12 Haziran 2013, 18:45:16
Şimdi durum şu hocam 1 saniye geçtiğini anlamak için 50 ms de bir kesmeye gönderiyorum(timer0) fakat sayılacak saniye sayısını da INT0 ucuna gelen düşen kenardan artırıyorum yani timer0 kesmesindeyken INT0 düşen kenarı gelmesi sistemin en kötü durumu oluyor.

O zaman şöyle olacak. Mantıken düşünüldüğünde INT0 dan gelen kesme daha önemlidir. Ve o kesmeye girse bile işlenecek kodlar çok değildir. Bir değişkeni artırıp çıkacaksın. Diğer timer kesmesinde ise 1 sn dolduğunda bir değişkeni set edeceksin. Main de, bu set ettiğin değişkeni kontrol edip, saniyedeki tick sayısından frekansı veya periyodu hesaplayacaksın. Kesmelere aşırı yüklenmemelisin yani..
"Vicdanın ziyası, ulûm-u diniyedir. Aklın nuru, fünun-u medeniyedir. İkisinin imtizacıyla hakikat tecelli eder." (Bediüzzaman Said Nursi)

z

Aklımda kalanlar sizi yanıltabilir.

1) RETI ile int rutinini terketmediğiniz sürece yeni intlar cevaplanmaz. (???)
2) Timer Int içindeyken Int0 vs gelse bu ilgili flağı set eder. Siz Timer int rutininden çıktığınızda Int0'a ait flag set olduğu için Int0 int rutinine düşersiniz.

Demek istediğim timer int rutini içinde int0 gelse ve gitse bile bu uyarı hafızada kalır timer int rutininden çıktığınızda int0 pini int üretecek sinyale sahip olmasa bile hafızadaki (falgdaki) değerden dolayı int0  rutinine girersiniz.

Dediğim gibi teyide muhtaç bilgiler bunlar. 8051'e elimi sürmeyeli 25 yılı geçti.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

AsHeS

Alıntı yapılan: fgokcegoz - 12 Haziran 2013, 23:56:44
O zaman şöyle olacak. Mantıken düşünüldüğünde INT0 dan gelen kesme daha önemlidir. Ve o kesmeye girse bile işlenecek kodlar çok değildir. Bir değişkeni artırıp çıkacaksın. Diğer timer kesmesinde ise 1 sn dolduğunda bir değişkeni set edeceksin. Main de, bu set ettiğin değişkeni kontrol edip, saniyedeki tick sayısından frekansı veya periyodu hesaplayacaksın. Kesmelere aşırı yüklenmemelisin yani..
Olayı şöyle çözümlemeye karar verdim. Timer0 kesmesi kalsın zaten while(1) döngümde saat kaynağına senkron olarak kenar tespiti yaptım. Şöyle ki ;
unsigned char is__accepted(unsigned char pin_name)
{
	static unsigned char pin_reg=1;
	if (pin_reg!=0&&pin_name==0)
		{
		pin_reg=pin_name;
		return 1;
		}
	else 
	{
		pin_reg=pin_name;
		return 0;
	}
}

Başlangıcın lojik '1' olmasının amacı hatta uyarı gelmediğin sürece '1' de kalıyor. Sistemi uyarı veren cismi bir sıçramasız buton olarak kabul edebiliriz ve bu cihaza başlangıçta kimsenin basamayacağını düşündüm. while(1) döngüm içerisinde bu kontrolü yaptırarak ekleme yapılıp yapılmayacağını kontrol ediyorum. Sorunu çözdüğümü düşünüyorum ama 2.bir göz benden daha iyi bakacaktır koda.

flashabu

Alıntı yapılan: fgokcegoz - 12 Haziran 2013, 17:29:22
8051 deki priority, aynı anda kesme gelmesi durumunda önem kazanır. Yani aynı anda iki kesme gelirse önceliği olan kesmeye dallanılır. Eğer öncelik(priorty) ayarlanmamışsa, default kesme önceliğine göre hareket eder. Kesme içinde kesme gelirsede muhtemelen ikinci kesme kaçırılacaktır. Yada içerisinde bulunulan kesme alt programı tamamlandığında diğerine gidebilir...

Eksik bilgiyi düzelteyim.
Öncelikle "kesme" yerine "interrupt" kullanıcam, türkçe terimlerin neye karşılık geldiğini anlamak için canım çıktı:)

8051'de default olarak tanımlı interrupt vector tablosu şu şekildedir:
http://www.electroons.com/8051/electroons/images/int8051.gif

Ama bu tablo demek olmuyor ki aynı anda ya da birbiri içerisinde gelen interrupt'lar kaçırılsın. Bu tablo tüm interrupt'ların öncelikleri (priority) nin aynı olması durumunda aynı anda gelen interruptların servis edilme önceliğini belirtir. Öncelik seviyeleri farklıysa önceliği fazla olanı ilk yapar, birazdan daha detaylı bahsedeceğim.

Şimdi öncelikle mcu interrupt geldiğine dair ilgili flag bitini (bayrak biti) '1' yapar. Örneğin serial interrupt gelirse (karşıdan veri geldi) RI biti 1 olur. İster aynı anda ister program zaten herhangi bir Interrupt Routine'i işlerken başka bir interrupt da gelirse örneğin Timer0; onun flag biti (TF0) de '1' olur ve bu bekler. Öncelikli olan ya da zaten devam etmekte olan Interrupt Routine tamamlandıktan sonra işlemci bakar ki bir interrupt daha sırada bekliyor, ilkinden çıkar çıkmaz buna geçer ve bitirir.

Bu flag'ları Serial Interrupt Haricinde sıfırlamanız gerekmez çünkü mcu ISR'a (Interrupt Service Routine) girer girmez (RETI komutunu gördükten sonra değil, ISR'a girdiği ilk anda) ilgili flag bitini temizler (0 yapar) Sadece Serial Interrupt'ta Rı ya da TI bitlerini elle temizlemek gerekir. Temizlenmezse ISR tamamlandıktan sonra işlemci bakar ki RI ya da TI biti var ve tekrar girer, sonsuz döngü.

Peki ne bu priorty, öncelik. Yukarıda bir arkadaşın da bahsettiği gibi IP register'ı interruptların hangilerinin diğerlerinden üstün olduğunu belirtmemize yarar. Donanımsal olarak 2 kademeli öncelik sistemi vardır (0 ya da 1. Yazılım ile daha çok seviye yapılabilir) IP register'ında 1 olarak belirlenmiş interrupt'lar 0 olanları yarıda kesip önce kendilerinin tamamlanmasını sağlayabilirler. Kendileri tamamlandıktan sonra önceliği düşük olanla devam edilir. 0'lar birbirlerini, 1'ler de birbirlerini yarıda kesemezler; yalnızca 1'ler 0'ları yarıda kesebilirler. Aynı anda geldilerse yine önce 1'ler yapılır. Gelenlerin priority seviyeleri aynı ise yine en başta anlattığım gibi interrup vector table'a bakılır.

AsHeS

Alıntı yapılan: flashabu - 22 Haziran 2013, 20:41:47
Şimdi öncelikle mcu interrupt geldiğine dair ilgili flag bitini (bayrak biti) '1' yapar. Örneğin serial interrupt gelirse (karşıdan veri geldi) RI biti 1 olur. İster aynı anda ister program zaten herhangi bir Interrupt Routine'i işlerken başka bir interrupt da gelirse örneğin Timer0; onun flag biti (TF0) de '1' olur ve bu bekler. Öncelikli olan ya da zaten devam etmekte olan Interrupt Routine tamamlandıktan sonra işlemci bakar ki bir interrupt daha sırada bekliyor, ilkinden çıkar çıkmaz buna geçer ve bitirir.
Cevabınız için teşekkür ederim bu bilgiyi Atmel datasheetlerinde bulamadım Intel datasheetlerinde mi yazıyor acaba ?


OptimusPrime

Alıntı yapılan: AsHeS35 - 23 Haziran 2013, 04:34:42
Cevabınız için teşekkür ederim bu bilgiyi Atmel datasheetlerinde bulamadım Intel datasheetlerinde mi yazıyor acaba ?

intel de de böyle bir bilgiyi bulamayabilirsin çünkü kesme içinde kesmenin işlenmesi olayına nesting deniyor. 8051 zamanında olmayan bir kavram bu. eğer bir datasheette nesting e yer verilmiyorsa olası senaryo arkadaşın anlattığı gibi dir (aşağıya kopyaladım)...

Şimdi öncelikle mcu interrupt geldiğine dair ilgili flag bitini (bayrak biti) '1' yapar. Örneğin serial interrupt gelirse (karşıdan veri geldi) RI biti 1 olur. İster aynı anda ister program zaten herhangi bir Interrupt Routine'i işlerken başka bir interrupt da gelirse örneğin Timer0; onun flag biti (TF0) de '1' olur ve bu bekler. Öncelikli olan ya da zaten devam etmekte olan Interrupt Routine tamamlandıktan sonra işlemci bakar ki bir interrupt daha sırada bekliyor, ilkinden çıkar çıkmaz buna geçer ve bitirir.
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||