.................... #int_TIMER1
.................... void TIMER1_isr()
.................... {
.................... if(msaniye<100){
*
0035: MOVF 29,W
0036: SUBLW 63
0037: BTFSS 03.0
0038: GOTO 03B
.................... msaniye++;}
0039: INCF 29,F
.................... else{
003A: GOTO 05B
.................... saniye++;
003B: INCF 2A,F
.................... msaniye=0;
003C: CLRF 29
.................... if(a==0)
003D: BTFSC 33.0
003E: GOTO 045
.................... {output_low(led);
003F: BSF 03.5
0040: BCF 05.3
0041: BCF 03.5
0042: BCF 05.3
.................... a=1;
0043: BSF 33.0
.................... }
.................... else{
0044: GOTO 04A
.................... output_high(led);
0045: BSF 03.5
0046: BCF 05.3
0047: BCF 03.5
0048: BSF 05.3
.................... a=0;
0049: BCF 33.0
.................... }
.................... if(saniye==60){
004A: MOVF 2A,W
004B: SUBLW 3C
004C: BTFSS 03.2
004D: GOTO 050
.................... saniye=0;
004E: CLRF 2A
.................... dakika++;}
004F: INCF 2D,F
.................... if(dakika==60){
0050: MOVF 2D,W
0051: SUBLW 3C
0052: BTFSS 03.2
0053: GOTO 056
.................... dakika=0;
0054: CLRF 2D
.................... saat++;}
0055: INCF 30,F
.................... if(saat==24){
0056: MOVF 30,W
0057: SUBLW 18
0058: BTFSS 03.2
0059: GOTO 05B
.................... saat=0;
005A: CLRF 30
.................... }
.................... }
....................
.................... set_timer1(55536);
005B: MOVLW D8
005C: MOVWF 0F
005D: MOVLW F0
005E: MOVWF 0E
.................... }
timer1 4 mhz lik osilatörde 10 ms de bir kesme için ayarlandı.Fakat bildigim kadarıyla timer1 içindeki işlemleri yaparkende bir takım gecikmeler meydana geliyor.Ben bu koddaki kesme ile 1 sn elde etmeye çalışıyorum.Gözle görülür bir gecikme yok.Öğrenme amaçlı kesme içindeki gecikmeleri de hesap etmek için ne yapmalıyız? Nasıl bir yöntem izlenebilir.İlgilenen arkadaşlara şimdiden teşekkürler..
şimdi açıp bakmadım fakat daha önceki baktıklarımdan hatırladığım ccs nin o kısmından tüm asm kodalarını göremiyorsun .hex editörü ile açıp baktığında asıl kodu görüyorsun farklı olarak w yazmacını vbg. saklayan bazı ek komutlar var.bunlarıda hesaba katarsan hesap tam olur sanırım.
Merhaba,
Alıntı YapÖğrenme amaçlı kesme içindeki gecikmeleri de hesap etmek için ne yapmalıyız? Nasıl bir yöntem izlenebilir.İlgilenen arkadaşlara şimdiden teşekkürler..
Merhaba,
Bunu öğrenmenin en basit yolu devreyi proteusta simulasyon yapmak olacaktır. Kesme olan alt program breakpointler koyarak altaki zaman sayacından olayı incelebilirsiniz.
Selamlar
Selam,
Kodları tam inceleyemedim ancak Zero-Drift olayına yakalanmış olabilirsiniz. 4 mhz, tam olarak sekize bölünemediği için zamanlamalarda çok hafif sapmalar olabiliyor. Kristali 4.096 mhz ile değiştirip denemenizi tavs. ederim.
Analyzer
Mod Edit:
3.2768 Mhz lik kristal PIC ile saat yapımına çok uygun :)
4 MHz için
CCP1 modülünü compare moduna al. Reset on Compare seçeneğini seç.
CCP_1=1000; //1 ms için. 10 ms için 10000 yapacaksın.
yaz. Timer1'i etkinleştir.
ccp1 ve global kesme durumlarını etkinleştir.
#int_ccp1
kesme rutininde istediğini yap.
.Öncelikle şunu belirteyim matematiksel olarak sorunum yok yani 2^16- (0.01/(4/20000000)) = 15536
timer1 kurma değerim 15536 olarak buluyorum.Osialtör 20 Mhz.Bu şekilde 10 ms de bir kesme üretiyorum.Sonucta 1 sn elde ediyorum.Fakat bu değeri kullanmama rağmen dakikada 0.343 saniye saatim ileriye gidiyor.İşin ilginç tarafı ileri gitmesi.
Ayrıca bu sorunun dışarıdan sinyal almak osilatörü değiştirmek gibi çözümlerini olduğunu biliyorum.Fakat inat işte :) Doğru birşeyin çalışmaması insanı meraka sürüklüyor.
Tabi timer değerini ayarlayıp geriye çekerek sistemi düzeltmek mümkün fakat doğru değer niye çalışmıyor olabilir?
20Mhz osilatör ile pic 10ms de 50.000 komut işletebilirki herbir kesmede işletilen komut sayısı (döngüler dallanmalarda hesaba katıldığında) bu değerden küçük ise kesme kaçırma gibi bir durumun olmaz
bu durumda osilatör frekansındaki değişimlerden dolayı saatin ileri gidiyor olabilir
Bazı komutlar 1 cycle bazıları 2 cycle da çalıştığı için ne kadarda hasas yapmaya çalışsan, uzun süre çalıştıktan sonra timerda ileri geri kaymalar meydana geliyor. En garantilisi timer1 e 32768 hz lik saat kristali bağlamak.
timer ile yapılan zamanlama devrelerinde zaman kaymasının nedeni kesme gecikmesi değildir. Kesme isteği geldikten sonra , kesme hizmetinin işletilebilmesi için o an işletilen kodun durumuna göre bir miktar gecikme yaşanabilmektedir. Ancak bu esnada timer durmadığı için, hizmet programı geç çalışmış da olsa bir sonraki kesme tam zamanında gelmekte. Kesme gecikmesi sadece iki kesme arasında zaman farkı olmasına neden olmakla birlikte toplamda bir kaymaya neden olmaz. Bu sebeple zaman içerisinde kesme kaynaklı bir kayma olmaz. Kaymanın tek sebebi kristalin frekansındaki doğal sapmalar ve ısıya bağlı kaymalardır. Kayma istenmeyen durumda en iyi alternatif 32.768 saat kristalleri olabilir. Tabi sıcaklık kayması düşük herhangi bir kristal de olabilir.
Alıntı yapılan: "erdinch".Öncelikle şunu belirteyim matematiksel olarak sorunum yok yani 2^16- (0.01/(4/20000000)) = 15536
timer1 kurma değerim 15536 olarak buluyorum.Osialtör 20 Mhz.Bu şekilde 10 ms de bir kesme üretiyorum.Sonucta 1 sn elde ediyorum.Fakat bu değeri kullanmama rağmen dakikada 0.343 saniye saatim ileriye gidiyor.İşin ilginç tarafı ileri gitmesi.
Ayrıca bu sorunun dışarıdan sinyal almak osilatörü değiştirmek gibi çözümlerini olduğunu biliyorum.Fakat inat işte :) Doğru birşeyin çalışmaması insanı meraka sürüklüyor.
Tabi timer değerini ayarlayıp geriye çekerek sistemi düzeltmek mümkün fakat doğru değer niye çalışmıyor olabilir?
Hocam yazdığım çok mu karmaşık, yoksa kendi düşünce yapından sıyrılıp başkalarının ne demek istediğini anlamak mı istemiyorsun. Benim bahsettiğim yöntem her 1000 veya 10000 komut adımında (4 MHz dediğin için) kesme üretir ve timer sıfırlanır (65535'e kadar gitmez). Timer1'e gidip te 15536 yüklemene gerek kalmaz (Onu da yanlış hesaplamışsın). Hele CCS'nin context saving kısımlarına bakarsan ne demek istediğimi anlarsın. Hele bir de mcu değiştir, programın her mcu için (12F, 16F, 18F) farklı sonuç verir. CCP modülleri acaba ne için boşuna duruyor orada? Compare kullanmayacaksan CP olur...
Alıntı yapılan: "Ziya"Alıntı yapılan: "erdinch".Öncelikle şunu belirteyim matematiksel olarak sorunum yok yani 2^16- (0.01/(4/20000000)) = 15536
timer1 kurma değerim 15536 olarak buluyorum.Osialtör 20 Mhz.Bu şekilde 10 ms de bir kesme üretiyorum.Sonucta 1 sn elde ediyorum.Fakat bu değeri kullanmama rağmen dakikada 0.343 saniye saatim ileriye gidiyor.İşin ilginç tarafı ileri gitmesi.
Ayrıca bu sorunun dışarıdan sinyal almak osilatörü değiştirmek gibi çözümlerini olduğunu biliyorum.Fakat inat işte :) Doğru birşeyin çalışmaması insanı meraka sürüklüyor.
Tabi timer değerini ayarlayıp geriye çekerek sistemi düzeltmek mümkün fakat doğru değer niye çalışmıyor olabilir?
Hocam yazdığım çok mu karmaşık, yoksa kendi düşünce yapından sıyrılıp başkalarının ne demek istediğini anlamak mı istemiyorsun. Benim bahsettiğim yöntem her 1000 veya 10000 komut adımında (4 MHz dediğin için) kesme üretir ve timer sıfırlanır (65535'e kadar gitmez). Timer1'e gidip te 15536 yüklemene gerek kalmaz (Onu da yanlış hesaplamışsın). Hele CCS'nin context saving kısımlarına bakarsan ne demek istediğimi anlarsın. Hele bir de mcu değiştir, programın her mcu için (12F, 16F, 18F) farklı sonuç verir. CCP modülleri acaba ne için boşuna duruyor orada? Compare kullanmayacaksan CP olur...
Hocam CCP modulu daha once kullanmadığım için dediklerinizi şu anda deneyemedim.Ayrıca neden böyle birşey olduğunu merak ettiğim için de bu kadar üstüne gittim sorunun.
yanlış hesaplamışssınız dediğiniz değer de 15535 olacak anladığım kadarıyla..
İyi çalışmalar dilerim..
İlgilendiğiniz için teşekkür ederim.
Xtaliniz 20.1 Mhz de titresiyor olabilir.
Elinizde guvenebileceginiz hic bir olcu aleti yoksa TV ile 20Mhz xtal oscnizin gercekte hangi frekansda titrestigini ogrenebilirsiniz.
Ihtiyaciniz olan sey TV ve biraz elektronik malzeme.......
Alıntı yapılan: "erdinch"Öncelikle şunu belirteyim matematiksel olarak sorunum yok yani 2^16- (0.01/(4/20000000)) = 15536
Eğer kesme geldiği anda ms sayacını arttırırsanız dediğiniz doğru. Ama kesme geldikten sonra ms sayacınızı arttırıp, timer a yeni değer yükleyeceğiniz yere gelinceye kadar en az 50 komut adımı kadar daha işlem yapar. Bu işlemler önemli değişkenlerin saklanması içindir. Yaklaşık 40-50 komut adımı kadar sürer. Bu süreyi timer1 e yükleyeceğiniz rakama eklemeniz gerekir.Yani 15586 gibi bir rakam yüklemeniz gerekir.
Saatinizin ileri gitmesi ilginç. Normalde bu hesabınızla geri kalması lazım.
Merhaba,
Timer1 in sürekli aynı zamanı vermesi için interrupt işleminde gözden kacan bir konu var. Sürekli aynı süreyi vermesi için interrupt alt program işleminde ilk önce timer1 sorgusunu yaparsanız o zaman sürekli aynı değeri elde ederseniz.
Eğer timer1 sorgusu başka interruptlardan sonra gelmiş ise. O zaman bu interrup timer süresini etkiler. Mesela ben timer1 kullanrak frekans metre yapmıştım. Harici kesme ile timer1 interruptu vardı. timer interruptu harici kesmeden sonra sorgulatığımda süreler de sapma oluyordu. Ama timer sorgunu en başa aldığımda cok karalı çalışmaya başladı.
Nedenine gelince rb0 int geldiğinde alt programda uzun bir işlem yapiyor. Ama o esnada timer da interrupt oluşmuş ise rb0 int işlemi bitirmeden timer int. alt programına girmeyeceği için fazladan saykıllar saymaya başlayacak. o da sürenin yanlış olmasına sebeb olacak.
Selamlar
arkadaşlar öncelikle ilgilendiğiniz için teşekkürler. benim timer1 alt rutinim şu şekilde
#int_TIMER1
void TIMER1_isr()
{
if(msaniye<100){
msaniye++;}
else{
saniye++;
msaniye=0;
if(a==0)
{output_low(led);
a=1;
}
else{
output_high(led);
a=0;
}
if(saniye==59){
saniye=0;
dakika++;}
if(dakika==60){
dakika=0;
saat++;
}
if(saat==24){
saat=0;
}
tarih_kontrol();
}
set_timer1(15246);
}
Ziya hocamin dedigi gibi normalde geri kalması gerekirken ileri gitmesi osilatörden kaynaklanan bir sorun heralde.Ben de belirli ölçümler alarak timer1 değerini yukarıdaki gibi hesapladım.Bunda da küçük sapmalar var ama iyileştirilebilir.
Olay sanırım donanımsal bir sorun..