Picproje Elektronik Sitesi

DERLEYİCİLER => Proton+ => Konuyu başlatan: dyonizos - 11 Temmuz 2012, 04:38:07

Başlık: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: dyonizos - 11 Temmuz 2012, 04:38:07
selam arkadaslar,
aşağıdaki kodda TRM0 ile ms sayımı yaparken istediğim değerlerde ledleri yakıp söndürmek istiyorum ancak
IS-ELSE sorgusunu kesme içinde kullanmamak gerekir diye öğrenmiştim. Ancak IF-ELSE kesme dışına koyunca değerleri yakalayamıyorum sayım sırasında ve led yakıp söndürme olayı gerçekleşmiyor. Kesme içinde kullanmadan bu değerleri yakalamak mümkün değilmi?

Declare FLOAT_DISPLAY_TYPE = LARGE
Device = 16F876
        Config HS_OSC,WDT_OFF,PWRTE_OFF,BODEN_OFF,LVP_OFF,DEBUG_OFF,CP_ALL
        XTAL = 20
LCD_RSPIN = PORTA.0
LCD_ENPIN = PORTA.1
LCD_DTPIN = PORTC.4
LCD_INTERFACE = 4 ' 4-bit Interface
LCD_LINES = 4
LCD_TYPE = 0
   
        ALL_DIGITAL = TRUE ' Set PORTA and PORTE to all digital


       
TRISA=%00000000
TRISB=%00000000
TRISC=%00000000
PORTA=0
PORTB=0
PORTC=0

Symbol led1     PORTC.0
Symbol led2     PORTC.2
Dim sayac As Float
Dim int As DWord

On_Hardware_Interrupt GoTo KESME
OPTION_REG=%10000100 
INTCON=%10100000     'Kesmeler aktif,"-", ve TMR0 kesmesi aktif
TMR0=101
Clear  'tüm değişkenler sıfırlandı

Cls

basla:
sayac=int/1000
Print At 1,1,DEC3 sayac
'Print At 2,1,Dec int
'DelayMS 1

If int=220 Then High led1
If int=1660 Then Low led1
If int=550 Then High led2
If int=1800 Then Low led2


GoTo basla

KESME:
Context SAVE
Inc int    
INTCON.2=0
TMR0=101
Context Restore

End


Bu şekilde olursa istediğim değerlerde ledleri yakıp söndürebiliyorum ama kesme içinde IF-ELSE kullanmam gerekiyor.

Declare FLOAT_DISPLAY_TYPE = LARGE
Device = 16F876
        Config HS_OSC,WDT_OFF,PWRTE_OFF,BODEN_OFF,LVP_OFF,DEBUG_OFF,CP_ALL
        XTAL = 20
LCD_RSPIN = PORTA.0
LCD_ENPIN = PORTA.1
LCD_DTPIN = PORTC.4
LCD_INTERFACE = 4 ' 4-bit Interface
LCD_LINES = 4
LCD_TYPE = 0
   
        ALL_DIGITAL = TRUE ' Set PORTA and PORTE to all digital


       
TRISA=%00000000
TRISB=%00000000
TRISC=%00000000
PORTA=0
PORTB=0
PORTC=0

Symbol led1     PORTC.0
Symbol led2     PORTC.2
Dim sayac As Float
Dim int As DWord

On_Hardware_Interrupt GoTo KESME
OPTION_REG=%10000100 
INTCON=%10100000     'Kesmeler aktif,"-", ve TMR0 kesmesi aktif
TMR0=101
Clear  'tüm değişkenler sıfırlandı

Cls

basla:
sayac=int/1000
Print At 1,1,DEC3 sayac
'Print At 2,1,Dec int
'DelayMS 1

GoTo basla

KESME:
Context SAVE
Inc int

If int=220 Then High led1
If int=1660 Then Low led1
If int=550 Then High led2
If int=1800 Then Low led2
   
INTCON.2=0
TMR0=101
Context Restore

End
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: Tagli - 11 Temmuz 2012, 07:32:32
Esitligin tutmamasi normal. Anlik bir olay sonucta, yakalasan sasardim. Senin de dedigin gibi, kesme icinde karsilastirma yapmak da hem yanlis hem de anlamsiz.

Cozum, disarida esitlik degil aralik kontrol etmek. Duruma gore sadece buyukluk veya kucukluk de kontrol edebilirsin.
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: serhat1990 - 11 Temmuz 2012, 08:35:35
@Tagli Hocamın dediği gibi ,

Bu durumu büyüktür , küçüktür , büyük eşittir , küçük eşittir , gibi koşullarla görebilirsin. Kolay gelsin ...
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: Maxim - 11 Temmuz 2012, 09:07:19
kesme içinde if-else kullansak ne sorun olabilir ?
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: dyonizos - 11 Temmuz 2012, 09:10:27
eşitlik yakalamam lazım cünkü bu degerlerin aralıkları önemli. 1-2ms farklar sorun olabilir. O nedenle eşitlik olması gerekiyor.
Maxim hocam kesme içinde çok kalmadan çıkın denildiği için çıkmaya çalışıyorum. Yoksa orada işlem yapmak daha kolay valla :)
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: Tagli - 11 Temmuz 2012, 09:21:57
Alıntı yapılan: Maxim - 11 Temmuz 2012, 09:07:19
kesme içinde if-else kullansak ne sorun olabilir ?
Aslında yanlış ifade etmişim. Yanlış olan kesme içinde karşılaştırma yapmak değil. Gerektiğinde yapılır tabi, neden yapılmasın.. Ama burada kesme içinde o karşılaştırmanın yapılması, timer'ın kullanım amacına ters. Yoksa dyonizos'un da belirttiği gibi kesme içinde çok zaman alan işler yapılmadığı sürece sorun yok. Birkaç karşılaştırma çok zaman almaz.
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: LukeSkywalker - 11 Temmuz 2012, 10:28:29
Hocam yaptığınız iş kesmenin kullanımına aykırı. Kesmeyi istediğiniz süreye göre oluşturup her kesme oluştuğunda dışarıdaki bir değişkeni arttırarak o değeri kontrol edip ledleri yakıp söndürün.
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: CLR - 11 Temmuz 2012, 13:49:16
Alıntı yapılan: dyonizos - 11 Temmuz 2012, 09:10:27
eşitlik yakalamam lazım cünkü bu degerlerin aralıkları önemli. 1-2ms farklar sorun olabilir. O nedenle eşitlik olması gerekiyor.
Maxim hocam kesme içinde çok kalmadan çıkın denildiği için çıkmaya çalışıyorum. Yoksa orada işlem yapmak daha kolay valla :)


Tmr'ı hazırlarken tam istediğin zaman için programlayabilirsin. Tmr'ın sayan registerine başlangıç değerini ver interrupt geldiğinde senin istediğin zaman olacaktır interrupt içinde tekrar sayan registere aynı değerleri verirsen hiç şaşmaz her defasında aynı zamanda interrupt oluşur. Bu durumda if kullanmanada gerek kalmaz.

Örnek vereyim anlaşılması kolay olsundiye xtal 4mhz olsun. Bu durumda timerlar 1mhzde sayar(ilgili timerın prescalerı 1/1 ise) Amacımız 200us de bir interrupt oluşturmak olsun.TMR0 için örnek vereyim
TMR0=0xff-200;
TMR0ON=1;

int içinde
TMR0=0xff-200;  // tekrar yükle
flags.tmr0=1;    // int geldiğini alayacağımız flag
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: dyonizos - 11 Temmuz 2012, 18:02:53
Yaklasik 13-15 arasi degisken zaman degerleri var. Zaman ilerlerken (sayac sayarken) her bir degere geldiginde sirasi ile o degerde yapmasi gereken islemleri yapmasi gerekiyor. Tmr a tek bir deger verebildigimizi varsayarsak sizin dediginiz yontemle tum degiskenlerde islem yapmasini saglayabilirmiyiz?
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: CLR - 11 Temmuz 2012, 18:11:12
Evet yapabilirsin yeterki hepsinin zaman aralığını baştan belirle, sonra bu belirlediğin zamanları bir diziye yerleştir, sırasıyla timera ilk değer olarak yüklersen hepsinde tam zamanında işlemleri yaparsın, biri gelince sonraki değeri vereceksin
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: camby - 11 Temmuz 2012, 18:27:41
@uicroarm,

Dediğin şekilde aynı anda 1 tane zaman takibi yapabilirsin. Birini yapıyorsun sonra diğerini yapıyorsun işlemler sıralı oluyor.

----

Şu şekilde olabilir :

Soru :

Diyelim 4 farklı çıkışta 4 farklı led var. Bunlar 1ms , 7ms , 17ms , 29ms 'lik periyotlarda yanması gerekiyor. Ve bu işin timer ile yapılıp 1.0000000ms hassasiyet ile yapılması gerekiyor.

Çözüm : Birim zaman burada 1ms , 1ms'de bir kesme olacak şekilde bir kesme oluşturulacak şekilde Timerlar'dan birini kurulacak. Bu iş için timer0 değil de , taşma değeri belirlenebilen  TMR2 gibi ( daha doğrusu donanımsal PWM'e hizmet etmek için hazırlanmış ) bir timer kullanılmalı. Ön bölücü , son bölücü , taşma değeri ayarlanıp birim zaman ayarlandıktan sonra ( bu örnekte 1 ms ) her kesmeye gidişte bir sayaç değeri arrıtırılacak ve bu sayaç değeri her arttırmadan sonra :

1 , 7 - 17 - 29 değerlerinin katları ile karşılaştırılacak . Değeri tutan var ise işlem yapılacak. Birim zaman EBOB , timer resetleme zamanı EKOK.


Takip edilmesi gereken değişken sayısı "N"'lerle ifade edildiğinde daha iyi algoritmalar da çıkabilir

PLC'lerde bu iş nasıl yapılıyor ?

------

@uicroarm, sen de bunu kastetmiş ama ben anlamamış olabilirim.
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: CLR - 11 Temmuz 2012, 18:41:04
Alıntı yapılan: camby - 11 Temmuz 2012, 18:27:41
@uicroarm,

Dediğin şekilde aynı anda 1 tane zaman takibi yapabilirsin. Birini yapıyorsun sonra diğerini yapıyorsun işlemler sıralı oluyor.

----

Şu şekilde olabilir :

Soru :

Diyelim 4 farklı çıkışta 4 farklı led var. Bunlar 1ms , 7ms , 17ms , 29ms 'lik periyotlarda yanması gerekiyor. Ve bu işin timer ile yapılıp 1.0000000ms hassasiyet ile yapılması gerekiyor.

Çözüm : Birim zaman burada 1ms , 1ms'de bir kesme olacak şekilde bir kesme oluşturulacak şekilde Timerlar'dan birini kurulacak. Bu iş için timer0 değil de , taşma değeri belirlenebilen  TMR2 gibi ( daha doğrusu donanımsal PWM'e hizmet etmek için hazırlanmış ) bir timer kullanılmalı. Ön bölücü , son bölücü , taşma değeri ayarlanıp birim zaman ayarlandıktan sonra ( bu örnekte 1 ms ) her kesmeye gidişte bir sayaç değeri arrıtırılacak ve bu sayaç değeri her arttırmadan sonra :

1 , 7 - 17 - 29 değerlerinin katları ile karşılaştırılacak . Değeri tutan var ise işlem yapılacak. Birim zaman EBOB , timer resetleme zamanı EKOK.


Takip edilmesi gereken değişken sayısı "N"'lerle ifade edildiğinde daha iyi algoritmalar da çıkabilir

PLC'lerde bu iş nasıl yapılıyor ?

------

@uicroarm, sen de bunu kastetmiş ama ben anlamamış olabilirim.


Elbette sırasıyla yapacaksın, 7ms dediğim zaman birimi 1ms'den sonra gelmiyor mu? Okekini alır sayıcı koyar sayarsın veya benim bahzettiğim yönlemle, ben sayıcı yöntemini kullanmam çünkü karşılaştırmalar çok zaman kaybı olur. Karşılaştırma yapmayalım diye pointer vs kullanıyoruz. işlemler hızlansın diye yani
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: dyonizos - 11 Temmuz 2012, 22:03:36
Alıntı yapılan: uicroarm - 11 Temmuz 2012, 13:49:16
Tmr'ı hazırlarken tam istediğin zaman için programlayabilirsin. Tmr'ın sayan registerine başlangıç değerini ver interrupt geldiğinde senin istediğin zaman olacaktır interrupt içinde tekrar sayan registere aynı değerleri verirsen hiç şaşmaz her defasında aynı zamanda interrupt oluşur. Bu durumda if kullanmanada gerek kalmaz.

Örnek vereyim anlaşılması kolay olsundiye xtal 4mhz olsun. Bu durumda timerlar 1mhzde sayar(ilgili timerın prescalerı 1/1 ise) Amacımız 200us de bir interrupt oluşturmak olsun.TMR0 için örnek vereyim
TMR0=0xff-200;
TMR0ON=1;

int içinde
TMR0=0xff-200;  // tekrar yükle
flags.tmr0=1;    // int geldiğini alayacağımız flag


Bu sistemde kesme oluştuğunda o kesmenin hangi işleme bağlı olduğunu anlamak ve gereken led leri yakıp söndürmek için yine kesme içine if-else karşılaştırması koymamız gerekmiycekmi?
yani 200ms de LED1 yanacak. 202 ci ms de sönecek. 208 de LED2 yanıp 212 de LED2 sönecek.
ayrıca 200 de kesme oluşturdum ve LED1 i yaktım diyelim ( bunuda hangi ledin yanması gerektiğini anlamak için if-else ile bulmak gerekir diye düşünüyorum. yada case ile) bu durumda 202 ms sonunda LED1 in sönmesi için timer degerini 202 değilde 2 vermek gerekecek yanılıyormuyum? ve yine kesme içinde sönmesi gereken LED in hangisi olduğunu bulabilmek için bir yol izlemem gerekir.
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: camby - 11 Temmuz 2012, 22:45:53
Alıntı yapılan: uicroarm - 11 Temmuz 2012, 18:41:04
Elbette sırasıyla yapacaksın, 7ms dediğim zaman birimi 1ms'den sonra gelmiyor mu? Okekini alır sayıcı koyar sayarsın veya benim bahzettiğim yönlemle, ben sayıcı yöntemini kullanmam çünkü karşılaştırmalar çok zaman kaybı olur. Karşılaştırma yapmayalım diye pointer vs kullanıyoruz. işlemler hızlansın diye yani

- 1 Adet kontrol işlemi 8bitte dallanmasıyla beraber 4 cycle.

- Pointer'ın açıklayabilir misin ? Pointer ile yapılan işlemlerde arka planda yapılan nedir ?
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: CLR - 12 Temmuz 2012, 14:07:16
Alıntı yapılan: camby - 11 Temmuz 2012, 22:45:53
- 1 Adet kontrol işlemi 8bitte dallanmasıyla beraber 4 cycle.

- Pointer'ın açıklayabilir misin ? Pointer ile yapılan işlemlerde arka planda yapılan nedir ?

Pointer, arka arkaya yapacağın adımları hızlandıran bir işlemdir. Sonraki yapacağın işi pointer'a gösterirsin işlem zamanı geldiğinde doğrudan o işi yaparsın bu defa daha sonraki işlemi pointer'a gösterirsin. Eğer bahsettiğin gibi karşılaştırma kullanırsan her defasında tüm karşılaştırmaları yapman gerekir bu nedenle, 2den fazla if-else veya veya switch case durumları fazla ise pointerla yapmak en hızlısıdır, Sanırım bu senin için açıklayıcı olmuştur.

Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: z - 12 Temmuz 2012, 14:32:42
Hangi dili kullanırsan kullan sonuçta bir değişkene erişmek istediğinde

1. Değişkenin adresini registere yükle
2. Bu registerin içerdiği adrese erişerek oku yada yaz

Eğer bu iki adımı tek komutta (tek komut olsa bile 1 yada 2 cycleda işlemesi de önemli) işletemeyen işlemci ile çalışıyorsan (işlemcilerin çoğu bunu yapamaz) bu durumda değişkene erişim, en az 2 CPU komutunda (yada 3 cycle da) olacak demektir. Çünkü, 1. komut genelde 2  nolu komutun en az 2 katı zamanda işleyen bir komuttur.

Bu durumda farklı farklı değişkenlere erişim gerekiyorsa her defasında 1 ve 2 komutun işletilmesi gerekir.

Pointer erişiminde Baz adresi bir kereliğine yüklersin. bu 1. komutdur.
Bundan sonra sadece 2 komutu işletirsin. Farklı bir adrese erişmek istediğinde
durum değişir.

Eğer bir sonraki adrese erişeceksen;

Pointerin 1,2,4 gibi artırılması gerekir. Bu çoğu işlemcide zaman kaybına neden olur. Ancak işlemcinin komut kümesinde, adrese eriş (oku yada yaz) ve hemen ardından adres reğister içeriğini N artır komutu varsa bu kayıp zamandan kurtulursun. Çünkü bu komut pointer artırımını da aynı cycle'da otomatik yapar.

Eğer ardışıl adrese erişilmeyip daha uzaktaki bir değişkene erişim sözkonusu ise bu durumda;

Komut kümesinde; Adresdeki veriye erişen komutda ofset adres tanımlanabiliyorsa ve ofset adres bu komuta gömülebiliyorsa bu durumda sözkonusu adrese erişim de tek cycle da yapılır.

Ancak komut listesinde bu tip ofset ilavesi yapan komut yoksa değişken adresinin gene 1   tipi komutla yüklenmesi gerekir.

Eğer bu tip komutlar yoksa pointer kullanımının hız açısından hiçbir getirisi olmaz. Sonuçta bu tür işlemleri, index registerlere ait komutların yetenekleri belirler.




Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: CLR - 12 Temmuz 2012, 15:01:33
PIC serisinde index registerler var adresi ayrı tutuyor ve adres içeriğini ayrı ve istediğin adrese  dallanıp içeriğini okuyup yazabiliyorsun. Demek istedğimi kısa örnek vereyim


// karşılaştırma yöntemi: basit bişey yaptım çok mantık aramayın, basitlik için saniye kullanalım
// aşağıda görüldüğü gibi tüm karşılaştırmaları yapmak zorundayız, her if işlemi sallıyorum 5us olsa 40-50us zaman harcadık, bir tanesi çalışınca 5usnden fazla zaman harcıyacak
interrutp :
     if(tmr0 > 10) {....} //
     if(tmr0 > 20) {....} //
     if(tmr0 > 30) {....} //
     if(tmr0 > 40) {....} //
     if(tmr0 > 50) {....} //
     if(tmr0 > 60) {....} //
     if(tmr0 > 70) {....} //
     if(tmr0 > 80) {....} //



// pointer ile aynı işlemi 2 işlemde yapabiliyoruz 1. timer0'ı karşılaştırırsın sonra dizi taşmışmı onu karşılaştırsın
const u8  Times[]={10,20,30,40,50,60,70,80};
interrutp :
     static vu8 *TmrPtr=(static vu8 *)Times;
     if(Tmr0>(*TmrPtrPtr)){bu işlemi yap };


Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: z - 12 Temmuz 2012, 15:30:29
Elbette şekil itibariyle pointer kullanımı yazılımı sade gösteriyor. Fakat interrupt rutini gibi rutinlerde hız önemli olduğundan pointer işlemi ile pointersiz işlemin CPU komutlarından oluşan asm dosyasına bir bakmak lazım.

Mesela ARM, 80x86 gibi aileler, verilere yada verialanlarına pointer erişimi için mükemmel makine komutları sunmuşlar.
C işlemciden bağımsız olarak pointer erişimi imkanını sunuyor.  Ben genel konuştum ve pointer ile erişiminin her zaman hızlı olacağı yanılgısının altını çizdim.

Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: CLR - 12 Temmuz 2012, 15:37:05
Bende öyle anladım zaten, işlemcide index register yetenekli değilse veya sayısı azsa ve biz çok sayıda pointer kullanırsak işlemci olmayan bir özelliği kullanacak değil dolayısıyla sırasıyla point eder ve yavaş olur tabii ama pic18de aynı anda enaz 3 pointer kullanılabilir(working registerle 4), yeni serileri incelemedim belki arttırmışlardır. 
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: Tagli - 12 Temmuz 2012, 15:40:46
PIC18'lerde zaten donanımsal olarak yanlış hatırlamıyorsam 3, PIC16'larda ise 1 pointer var. Bunları derleyici de kullanıyor olabilir. C18'in bu pointer'lardan ikisini kendi software stack'i için kullandığını biliyorum. Üçüncüyü de galiba fonksiyon dönüş değerleri için kullanıyordu. O zaman geriye pointer kalmıyor... Normal pointer işlemlerini ne şekilde yaptığını bilmiyorum, ama muhtemelen bu 3 pointer'dan en az birini yedekleyip kullanıyor, işi bitince de eski değeri geri yazıyordur belki. Tamamen yanılıyor da olabilirim ama tahminim bu yönde. Eğer durum böyle ise, pointer kullanmanın işleri hızlandıracağını söyleyemeyiz.

z'nin de dediği gibi, durum işlemciden işlemciye değişir. ASM koduna bakmadan bilinemez.
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: camby - 12 Temmuz 2012, 16:05:07
Şu işlemi pointer ile ( Pointer dediğiniz aslında dolaylı adresleme registerları ) daha hızlı yapabilir misiniz ?

Katsayıları hesaba katmadan basit bir örnek yazdım :




KESME ; 1ms'lik kesme
....

incf sayac

....
retfie






..............

ISLEM1

btg PORTB,1

RETURN

..............

ISLEM2



..............



Ana_Program

movlw .10
CPFSEQ d1
GOTO NEXT2
CALL ISLEM1

NEXT2 movlw .20
CPFSEQ d2
GOTO NEXT2
CALL ISLEM2

NEXT3 movlw .30
CPFSEQ d3
GOTO NEXT4
CALL ISLEM3

NEXTN
...............


GOTO ANA_Program

END





Ek :

- Eğer Ana program bu kontrol işlemleri dışında başka işlemler ile dolu ise zamanlamayı kaçırmadan bu işlemler nasıl yapılır ,    Hadi bunu da açıklayın C'ciler soruyorum size   : ))

mesaj birleştirme:: 12 Temmuz 2012, 16:10:51

Alıntı yapılan: Tagli - 12 Temmuz 2012, 15:40:46
PIC18'lerde zaten donanımsal olarak yanlış hatırlamıyorsam 3, PIC16'larda ise 1 pointer var. Bunları derleyici de kullanıyor olabilir. C18'in bu pointer'lardan ikisini kendi software stack'i için kullandığını biliyorum. Üçüncüyü de galiba fonksiyon dönüş değerleri için kullanıyordu. O zaman geriye pointer kalmıyor... Normal pointer işlemlerini ne şekilde yaptığını bilmiyorum, ama muhtemelen bu 3 pointer'dan en az birini yedekleyip kullanıyor, işi bitince de eski değeri geri yazıyordur belki. Tamamen yanılıyor da olabilirim ama tahminim bu yönde. Eğer durum böyle ise, pointer kullanmanın işleri hızlandıracağını söyleyemeyiz.

z'nin de dediği gibi, durum işlemciden işlemciye değişir. ASM koduna bakmadan bilinemez.

Evet , basit işlemlerde bile ( normalda asm'de dolaylı adresleme yapmadan yaptığımız işlemler ) hi-tech arka planda FSR ve INDF registerlarını kullanarak yapılıyordu C18'de öyledir diye tahmin ediyorum.
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: Tagli - 12 Temmuz 2012, 16:17:43
Bence değişen birşey yok, ASM olsa da yine kaçırabilirsin. Çünkü yine eşitlik kontrolü yapıyorsun.

Uygulamanın bu kadar hassas zamanlama gereksinimleri olmaması lazım. Burada yöntem hatası var bence. Yine de en hassas sonuca uicroarm'ın başta önerdiği gibi, her kesmede yeni bir değerle timer'ı yeniden kurarak ulaşabilirsin.
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: LukeSkywalker - 12 Temmuz 2012, 16:21:00
@Camby
Asm tabiki çok daha hızlı çalışacaktır. Bunu bilmeyen yok fakat kulağı tersten tutmanın da anlamı yok arkadaşın sorununda.
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: camby - 12 Temmuz 2012, 16:26:24
Alıntı yapılan: Tagli - 12 Temmuz 2012, 16:17:43
Bence değişen birşey yok, ASM olsa da yine kaçırabilirsin. Çünkü yine eşitlik kontrolü yapıyorsun.

Uygulamanın bu kadar hassas zamanlama gereksinimleri olmaması lazım. Burada yöntem hatası var bence. Yine de en hassas sonuca uicroarm'ın başta önerdiği gibi, her kesmede yeni bir değerle timer'ı yeniden kurarak ulaşabilirsin.

- Yukarıdaki program kaçırmıyor , daha doğrusu kaçırıyor fakat hatalar üst üste binmiyor..

- Zamanlama gereksinimi hassas'dan ziyade öncelikli olabilir , yani kesmeden döndükten 400ms sonra eşitlik kontrolüne bakılırsa zamanlama baya bi şaşar , hatta kesmelerin anlamı kalmaz ( çünkü 1 ms yapmıştık bu örnekte ).

Örneğin bir fonksiyon işletiliyor ( bu bir hesaplama olabilir ) herhangi bir anda timer kesmesi geldi , kesme işletilip fonksiyona geri dönüldü ve fonksiyona devam edildi. Fonksiyondan çıkışa daha 400ms daha süre olabilir. Kesme dönüşü , kesmeden çıktıktan sonra araya işlem alınması gerekir.


- Timer'ı yeniden kurarsak paralel işlem yapamayız diyorum ben de. ( yada anlayamıyorum demek istenileni ) 1 sn timer kuruldu işlem yapıldı , 3 sn timer  kuruldu işlem yapıldı , 2 sn timer kuruldu işlem yapıldı . Toplam 6 sn süre geçti.

4 tane led olsun bu ledleri 1t , 3t , 5t , 7t periyotlarda açıp kapatalım . Bu işlemi her kesmede tekrar timer değeri girerek nasıl yaparız. Yaparız ama bu işlem parametrik olur mu ?  Diyelim bu uygulama bir PLC ve kullanıcı bu parametreleri dışarıdan kendisi giriyor.



mesaj birleştirme:: 12 Temmuz 2012, 16:31:13

Alıntı yapılan: maytere - 12 Temmuz 2012, 16:21:00
@Camby
Asm tabiki çok daha hızlı çalışacaktır. Bunu bilmeyen yok fakat kulağı tersten tutmanın da anlamı yok arkadaşın sorununda.

evet :) , ben tam onu yazacaktım arkadaşa. O konuya çözüm getirildi zaten belki arkadaş çoktan programını yazmıştır.

Ama şu an pointer işlemi ve sırayla karşılaştırmayı tartışıyoruz sadece.

Bu işlem tek başına çok basit gibi gözüküyor ancak başka işlemler ve fonksiyonlar ile birlikte kullanılmaya başlandığında çok önemli bir hale gelebilir.
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: Tagli - 12 Temmuz 2012, 16:48:02
Alıntı yapılan: camby - 12 Temmuz 2012, 16:26:24
- Yukarıdaki program kaçırmıyor , daha doğrusu kaçırıyor fakat hatalar üst üste binmiyor..
Prescaler'e bağlı. Büyük olursa kaçmaz. Ama 1:1 ise kesin kaçar.

Alıntı yapılan: camby - 12 Temmuz 2012, 16:26:244 tane led olsun bu ledleri 1t , 3t , 5t , 7t periyotlarda açıp kapatalım . Bu işlemi her kesmede tekrar timer değeri girerek nasıl yaparız. Yaparız ama bu işlem parametrik olur mu ?  Diyelim bu uygulama bir PLC ve kullanıcı bu parametreleri dışarıdan kendisi giriyor.
Bekleme süreleri bir dizide saklanabilir. Çok kabaca yazarsak:

int periyod[] = {10, 30, 50, 70}
int index = 0;
void interrupt kesme(void){
    switch (indeks){
    case 0:
        //0 nolu isi yap
        break;
    case 1:
        .....
    }
    TMR0 = 255 - periyod[indeks];
    if (++index == 4) index = 0;
    TMR0IF = 0;
    return;
}

Tabi burada yapılacak işlerin LED yakmak gibi, kısa süreli işler olması gerekir. Zamanlama kesme sonundaki birkaç komut sebebiyle tam tutmayacak olsa da, oldukça yakın olabilir. Gerektiğinde dizi içindeki değerlerle oynanarak zamanlama tam olarak ayarlanabilir. uicroarm'ın dediği buydu zaten sanırım.

Tam anlamıyla bir çözüm üretebilmek için gereksinimleri, yani programın yapması gereken işleri ve kod akışının nasıl olması gerektiğini bilmek lazım. Tahminlere dayanarak her durum için en iyi sonuç veren çözüm çıkamaz ortaya. Duruma göre çözüm üretilir.
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: CLR - 12 Temmuz 2012, 17:47:49
Alıntı yapılan: camby - 12 Temmuz 2012, 16:05:07
Şu işlemi pointer ile ( Pointer dediğiniz aslında dolaylı adresleme registerları ) daha hızlı yapabilir misiniz ?

Katsayıları hesaba katmadan basit bir örnek yazdım :




KESME ; 1ms'lik kesme
....

incf sayac

....
retfie






..............

ISLEM1

btg PORTB,1

RETURN

..............

ISLEM2



..............



Ana_Program

movlw .10
CPFSEQ d1
GOTO NEXT2
CALL ISLEM1

NEXT2 movlw .20
CPFSEQ d2
GOTO NEXT2
CALL ISLEM2

NEXT3 movlw .30
CPFSEQ d3
GOTO NEXT4
CALL ISLEM3

NEXTN
...............


GOTO ANA_Program

END





Ek :

- Eğer Ana program bu kontrol işlemleri dışında başka işlemler ile dolu ise zamanlamayı kaçırmadan bu işlemler nasıl yapılır ,    Hadi bunu da açıklayın C'ciler soruyorum size   : ))

mesaj birleştirme:: 12 Temmuz 2012, 16:10:51

Evet , basit işlemlerde bile ( normalda asm'de dolaylı adresleme yapmadan yaptığımız işlemler ) hi-tech arka planda FSR ve INDF registerlarını kullanarak yapılıyordu C18'de öyledir diye tahmin ediyorum.

Merhaba ,

Camby , Yaşlaşık 10yıl kadar asm kod yazdım,  halende yeterince iyi biliyorum diyebilirim. Ama bir C derleyicisini yazan adamlar kadar iyi biliyorum diyemem çünkü onlar aşmışlar o nedenle birincisi senin yazdığın 2 satırlık asm kod ile C derleyicisininkini karşılaştırma, mesela yaz matematik gereken veya mantıksal ifadeler gereken orta büyüklükte bir program(mesela asm ile 10Kbyte'lık(yaklaşık 10bin satır) kod ama dolu kod olacak) sonra derleyici ile karşılaştır kim hatasız ve stable kod yazmış olacak bakalım yoksa 2 led, 3 butonla karşılaştırılmaz.   

Senin yazdığın asm koda gelelim ile bu kodla hassas timer zaten yazamazsın çünkü interupt içinde bir değişkenin değerini arttıyorsun sonra ana programa gidip orada karşılaştırıyorsun eğer ana program içinde azda olda bir delay işlemi olursa tüm zamanlar şaşar. Ki program büyüdükçe kesin olur. Bu yazdığın mantık sistem mantığı benzeridir yani interrupt geldiğinden haberim olsun ve geciksede çalışsın şeklindedir.   Mesela işlem1 içindeki yaptıkların uzun sürerse işlem2 gecikir. Diyorsanki benim hassas zaman dediğim ms'ler düzeyinde bu şekilde çalışabilirsin ama ana programda yine ms düzeyinde delay kullanmaman veya gecikmemen gerekir.
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: carirt - 12 Temmuz 2012, 18:01:50
uicroarm


diziye pointer atamak  ile interrupt bayrağı nasıl kontol edilebilir bir örnek verebilirmisiniz ben kafamda canlardıramadım bir türlü
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: camby - 12 Temmuz 2012, 18:37:58
Alıntı yapılan: uicroarm - 12 Temmuz 2012, 17:47:49

...eğer ana program içinde azda olda bir delay işlemi olursa tüm zamanlar şaşar. Ki program büyüdükçe kesin olur. Bu yazdığın mantık sistem mantığı benzeridir yani interrupt geldiğinden haberim olsun ve geciksede çalışsın şeklindedir.  Mesela işlem1 içindeki yaptıkların uzun sürerse işlem2 gecikir.

- Ben aşağıdaki mesajlarımın ikisinde de bundan bahsettim. Şimdi siz ben aynısını söylememişim gibi yazıyorsunuz.


- Offset her zaman olur , kesmeye girip içine hiç kod yazmadan çıksak bile 4 cycle süre geçer. Bu bir gecikme olarak sayılabilir , ama timer sürekli çalıştığı için biliyorsunuz ki hatalar üst üste binmez.

- Yapılan işlemlerde kesmeler üst üste binip kaçırmadığımız sürece sapma olmaz.

Yazdığım basit kodların altında ,

Alıntı Yap
Ek :
- Eğer Ana program bu kontrol işlemleri dışında başka işlemler ile dolu ise zamanlamayı kaçırmadan bu işlemler nasıl yapılır ,    Hadi bunu da açıklayın C'ciler soruyorum size   : ))

Diyerek programın yetersizliğine de değindim.

- Bu şaşmanın olmaması için ne yapılır diye sordum ama cevap alamadım. Bunu da ben beraber tartışalım , kendi yöntemimi sizinkilerle karşılaştırayım diye sordum.


Sonuç olarak :

Alıntı Yap......tüm zamanlar şaşar. Ki program büyüdükçe kesin olur....

- Buna katılmıyorum.
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: CLR - 12 Temmuz 2012, 19:16:56
Camby, 4 saykıldan bahsetmiyorum ben, mesela timer interrupt'ı kurdun 1ms'ye ve işlem2ye gitmek istiyorsun, işlem2den önce çalışan altprogramların var diyelim (program büyüdükçe dediğim bu nokta) burada 250us'lik işlemin olsun işlem2 interruptı oluştuktan maximum 250us sonra işlem2yi yapabilirsin.Eğer tam işlem2ye gelmeden interrupt oluşursa o zaman 1ms aralık olmuş olur ama bu zamanlar hep düzensiz olacaktır.

Ek :
- Eğer Ana program bu kontrol işlemleri dışında başka işlemler ile dolu ise zamanlamayı kaçırmadan bu işlemler nasıl yapılır ,    Hadi bunu da açıklayın C'ciler soruyorum size   : ))

Bu soruna cevap vereyim , kritik zaman gerektiren şeyler uzun sürmez mesela adc okursun veya birkaç pini set edersin veya okursun gibi bu işlemleri bahsettiğim gibi pointerle yaparsan daha az zamanda büyük işlem yaparsın.
Veya ana program içinde tüm yapılacakları hazırlarsın interrupt oluştuğunda işlemi sadece başlatırsın. Mesela işlem büyükse alıcıya veri göndereceksen, 10byte olsun ve kritik zamanlara gerektiriyorsa eğer donanımda öncelikle dma varsa onu kullanırsın o yoksa transmit interrupt kullan ki işlemci transfer ederken sende başka işleri halledersin. Transmit interrupt içinde de pointer veya array kullanırsan ardışık kolayca gönderebilirsin.
C'nin gücü asm'den gelir çünkü asmye yakındır, C'nin gücü pointerdan gelir bunun asm karşılı index registerlardır. Asm'cilerin çoğu kullanmaz kattığı avantajı göremezler. Bir işlemcide ne kadar çok index register varsa o kadar güçlüdür.   

Demek ki, kritik işlemler gerekiyorsa C içinde while, do-while, for gibi ifadelerden uzak durmak gerekiyor, Asm içinde sürekli bit/byte testleri gerçekleştirinceye kadar, verielr gönderilinceye kadar vs. beklemek gibi, mesela yukarıda sen eşit oluncaya kadar buda dön dur demişsin işlemciye. İşte gelinceye kadar bekle diye kod yazarsan ve o şart hiç gelmezse işlemcin kilitlenir bu yöntem yanlış kodlamadır mutlaka timeout koyman gerekir. (sadece örnek için yazdım yoksa gerçekte belki böyle yazmıyorsundur asm'yi)
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: Tagli - 12 Temmuz 2012, 19:42:24
Çok bulanık ifadelerle konuşuyoruz. Bir senaryo belirleyelim, gerçekçi bir senaryo olsun. Sonra bunu çözmek için program yapısının nasıl olması gerektiğini tartışalım.
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: dyonizos - 12 Temmuz 2012, 23:33:03
Bir gün girmedim konu nerelere gitmiş :)
bu kadar bilgili arkadaşları saygıyla selamlıyorum ancak ben hala bu pointer olayını Proton ile nasıl yapabileceğimi eğerki pointer değilde her bir değişken için ayrıca timer a değer vermem gerekirse daha önce sorduğum gibi ilk deger 200 ms ise ve ikinci 202ms ise sonraki timer değerini 2ms olarak vermek gerekmeyecekmi? 
bu durumda 13-14 degiskenlerde bu zaman farklarını hesaplatmak için baya bir aritmetik işlem gerekir gibi geliyor.
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: camby - 12 Temmuz 2012, 23:49:55
taglı ve uicroarm,

aslında c ve asm kodlarını kapıstırmamıza gerek yok , bılıyoruz avantajlarını ve dezavantajlarını. Aslında C'yı kullanmak ıcın fırsat arıyorum ve c yazan arkadaslar , c'yı yazarken asmde oldugunu dusundugum avantajları kullanabılıyorlarmı onu merak edıyordum.

Ben cok krıtık ıslerde kesme cıkısı stackleri degıstııp kesme donusu farklı yere gıdıyorum. Ornegın modbus byte kesmesı ve aynı anda modbus frame kesmesı beklerken buyuk bı fonksıyonun ıcındekı ısı yarım bırakıp baska yerden devam etmem gerekıyor.

Benzer olarak sızın ındex benımde dolaylı adresleme elemanları olarak adlandırdıgım donanımı 3ünü bırden aynı zamanda kullanmam gerekıyor. Hatta 3. Yetmıyor , baska yerde kullandıgım bı ındexı yedekleyıp tekrar kullanıp yedegı gerı yuklemem gerekbılıyor. Bu durumda stack yedeklemeye benzer olara tek bır donanımsal ındex ıle yedekleyerek n sayıda ındex kullanabılecıgımı de farkettım. Mesela c'de de 3ten fazla bu elemanı kullanınca nasıl sonuclar uretecek endıselendırıyor benı. Yoksa ındexı de kullanıcı mı yedeklıyor.

Genel olarak c'de yazacagım kodun arka planda ureteceklerı endıselendırıyor benı.

Uicroarm.
10 sene asm yazdıysan sende bu cekınce muhakkak olmustur dıye tahmın edıyorum.

Bi yandan konuyu acan arkadasa da yardımcı olmamız lazım: ).





Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: CLR - 13 Temmuz 2012, 14:22:04
Camby, Asmyi yeterine öğrendiysen bırak yoksa ileride C öğrendiğinde üzülürsün niye erken öğrenmedim diye. Asm programcıları biraz zaman konusunda cimridir ve çok detaycıyızdır. Ama sana en önemli kuralı söylüyeyim ne kadar çok detaya takılırsan asıl amacını unutursun ve başarısız olursun. Önemli olan en az komut sayısı ile en iyi programı yazmak değil, Amaç hatasız , kararlı, anlaşılır, taşınabilir bir kod yazmaksa C dili doğru tercihtir.
Mesela asmde işi ilerlettiğimde paso macro kullanıyordum macro'da lüx istersen asm komut sayından feregat etmen gerekir, C'de bir çeşit asm'nin macrosu gibi düşünebilirsin, asm'ye göre bir kaç satır asm kod fazla çalışabilir ama sana kazandırlıkları yanında kaybettiklerin hiç bişey.
Başlık: Ynt: TMR0 kesmesinde sayımı if else ile yakalayamamak
Gönderen: Tagli - 13 Temmuz 2012, 16:24:07
Yukarıda değinmiştim gerçi ama tekrar vurgulama gereği hissettim: 3 - 5 cycle'ın hesabı yapılır hale gelinmişse ya program yanlış bir mantıkla yazılmış ya da işlemci yanlış seçilmiş demektir.