avatar_elektro77

kesme içinde pause komutu kullanım zorunluluğu

Başlatan elektro77, 22 Eylül 2023, 09:45:44

elektro77

Aşağıdaki örnekte ana döngüde yaktığım bir ledi, program gerisayım kesmesinde girdiğinde de yakıp söndürmek istiyorum. Bunun için pause 50 komutu kullanmak zorunda kaldım.
Bu durumda 61 olan tmr0 sayac döngüsünü kaça ayarlarsam saniye bazında 1sn yi tam yakalarım?
Formülü nedir?
Basla:
if buton1=1 then
gerisayimledi=1
endif
if buton2=1 then
zaman_say=1
endif
goto basla
'----------------------
DISABLE
KESME:
IF zaman_say=1 THEN
gerisayimledi=0 
SAYAC=SAYAC +1 
IF SAYAC=61 then 
SAYAC=0
SN=SN-1
gerisayimledi=1  
PAUSE 50
 IF SN>=59 THEN 
    SN=59
      DAK=DAK -1  
        IF DAK>=59 THEN
          DAK=59
             DAK=0
             SN=0
             zaman_say=0
             gerisayimledi=0
             ENDIF
    ENDIF
INTCON.2=0  
RESUME
ENABLE
"Eğer bir konuyu öğrenmek istiyorsan o konunun öğretmeni ol; daha iyi öğrenmek istiyorsan o konuda bir kitap yaz; daha da iyi öğrenmek istiyorsan yazdığın kitabi oku"

aRci

Merhaba pause kullanmadan yapmanın yolunu arasan daha iyi olur.kesme rutinindeki pause 50 yi ve gerisayimledi=0 kısmını silmelisin.

Bekle adlı değişken sana sistemi durdurmadan gecikme yapmanı sağlayacak. sistemin hızına göre buradaki değeri değiştirerek gecikme süreni ayarla.

Bekle var word
Basla:
if buton1=1 then
toggle gerisayimledi
endif
if buton2=1 then
zaman_say=1
endif
Bekle = 0
while Bekle < 1000:Bekle=Bekle + 1:wend
goto basla

'----------------------
DISABLE
KESME:
IF zaman_say=1 THEN
gerisayimledi=0 
SAYAC=SAYAC +1 
IF SAYAC=61 then 
SAYAC=0
SN=SN-1
 IF SN>=59 THEN 
    SN=59
      DAK=DAK -1  
        IF DAK>=59 THEN
          DAK=59
             DAK=0
             SN=0
             zaman_say=0
             gerisayimledi=0
             ENDIF
    ENDIF
INTCON.2=0  
RESUME
ENABLE

elektro77

@aRci
Bunu yapamam, pause kullanma zorunluluğum var.
Asıl program verdiğim örnek değil.
Bu nedenle seni yanıltmış olabilir.
"Eğer bir konuyu öğrenmek istiyorsan o konunun öğretmeni ol; daha iyi öğrenmek istiyorsan o konuda bir kitap yaz; daha da iyi öğrenmek istiyorsan yazdığın kitabi oku"

ete

Ben olsam o ledi her kesmeye girişinde toggle olarak yakıp söndürürdüm.
Açıklama aşağıda,
Öncelikle 61 sayısının nereden geldiğine bakmak lazım. TMR0 bölme oranın 1/64 ve sayac sıfırdan itibaren sayıyor yani saydığı rakam 256. O halde 256 sayılan x 64 (prescaler)=16384 sayılan değer bunu 61 kez yaptığında 61 x 16384=999.424 ki bunu yaklaşık 1000 kabul ediyoruz komut gecikmeleri ile birlikte. O halde, senin mümkün olduğunca daha az kesme sayısı ile bu süreyi yakalaman gerekiyor. Çünki 50 ms lik gecikme her kesmede kullanılıyor. Bu iş epeyce karmaşık. Neden dersen 61 kesmede 61*50=3.050 ms yani yaklaşık 3 sn lik bir gecikme yaratıyorsun zaten. Buna birde 1 sn lik asıl gecikmeyi eklersen sen her sn için 4 sn harcıyorsun demektir.
Bu sıkıntıdan kurtulmanın tek yolu 50 lik gecikmeden kurutulmaktır. Çünki hiç bir rakam sana uygun gecikme değerini sağlamayacaktır. Mantık yolu ile düşünürsek öyle bir kesme süresi olması lazımki 50ms den büyük olacak (mevcut durumda 16,3ms) bu gecikmeden 50 yi çıkartıp kalanı için tmr0 sayacı çalıştırman gerekir. Örnek vereyim 50ms pause den geliyor buna 15ms lik kesme süresi eklersek ve her kesme 15 ms de bir yapılırsa toplamda 65ms lik bir süre elde edersin 1000/65=15 kesme sonunda yaklaşık 1000 ms ye ulaşırsın.
O halde 15 ms lik TMR0 kesme gecikmesi yaratacaksın her kesmede buna pause 50 eklenecek ve toplamda 65ms lik kesme gecikmesi yaratmış olacaksın.
15 ms lik kesme ayarı için;
OPTION_REG ayarı eskisi gibi 1/64 bölme oranında kalacak.
TMR0 ön yükleme değeri 21 olacak her kesme sonunda kesmeden çıkmadan önce TMR0=21 komutunu vermen gerekir.
Kesme kısmındaki 61 sayısı ise 15 olacak hepsi bu kadar.

Ete

mehmet

Eğer aynı led farklı durumlarda, farklı
yanıp-sönmesi isteniyorsa; kesme içine
bir kaç if bloğu ve her if bloğu içinde
de ayrı for döngüsü ile yapılır. Tek sayaç
ile yanma ve sönme süreleri ayarlanır.

Örneğin;
0-99 arası sayan sayaç olduğunu düşünelim.
0-19 yanık, 20-99 sönük,
0-49 yanık, 50-99 sönük,
0-79 yanık, 80-99 sönük olarak ayarlanabilir.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
http://www.mehmetbilgi.net.tr
CC BY

ete

Mehmetin fikrinden yola çıkarak SAYAC değerinin 3 ün katları (48,9ms gecikme)sayılarda led çıkışının toggle yaptırılması yaptırılması veya 4 ün katları (65,2ms) sayılarda led çıkışının toggle yaptırılmasıda bir çözüm olarak düşünülebilir.
Bu durumda kesme kısmını aşağıdaki şekilde düzenlemek gerekir.
DISABLE
	KESME:
	IF zaman_say=1 THEN
	  SAYAC=SAYAC +1 
          IF SAYAC//3=0 THEN toggle gerisayimledi
          IF SAYAC=61 then 
	    SAYAC=0
	    SN=SN-1
	    IF SN=255 THEN 
	      SN=59
              DAK=DAK -1  
              IF DAK=255 THEN
	         DAK=59
	         zaman_say=0
	      ENDIF
	    ENDIF
	INTCON.2=0  
	RESUME
	ENABLE
SN ve DAK değerleri geri sayım yaptırıldığı için yukardaki gibi olmalı.
Ete


elektro77

Evet toggle yakıp söndürmek pause kullanmaktan çok çok iyi oldu.
SAYAC=SAYAC +1 
IF SAYAC//3=0 THEN toggle gerisayimledi
Bu kod çok güzel çalıştı. Hızlı hızlı yanıp sönmesi de cuk oturdu...
Cevap yazan herkese Teşekkür ederim.
"Eğer bir konuyu öğrenmek istiyorsan o konunun öğretmeni ol; daha iyi öğrenmek istiyorsan o konuda bir kitap yaz; daha da iyi öğrenmek istiyorsan yazdığın kitabi oku"

Powered by EzPortal