Timer'ı kusursuz hesaplamak

Başlatan erdinch, 20 Ağustos 2007, 21:02:30

erdinch

.................... #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..

mcan

ş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.

arslan74

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

Analyzer

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
Üşeniyorum, öyleyse yarın!

erdinch


Mod Edit:

3.2768 Mhz lik kristal PIC ile saat yapımına çok uygun :)

Ziya

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.
Bu günden sonra hiç kimse sarayda, divanda, meclislerde ve seyranda Türk dilinden başka dil kullanmaya. (13 Mayıs 1277) Karamanoğlu Mehmet Bey

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?

CaFFeiNe

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

sigmoid

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.

Klein

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.

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...
Bu günden sonra hiç kimse sarayda, divanda, meclislerde ve seyranda Türk dilinden başka dil kullanmaya. (13 Mayıs 1277) Karamanoğlu Mehmet Bey

erdinch

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.

z

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.......
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Ziya

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.
Bu günden sonra hiç kimse sarayda, divanda, meclislerde ve seyranda Türk dilinden başka dil kullanmaya. (13 Mayıs 1277) Karamanoğlu Mehmet Bey

arslan74

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