TIMER0 Kesme Süre Hesabını Bir Türlü Tutturamadım

Başlatan M.A.A, 10 Ocak 2016, 00:04:39


ete

Hata, muhtemelen Dword (32 bit) olarak tanımladığın  ve ekranda yine Dword olarak yazdırmaya çalıştığın değişkenlerin çok fazla gecikme yaratmasından kaynaklanıyor. Bunları WORD olarak tanumla yeniden dene istersen.
Sırf merakımdan senin programını PBP ya çevirdim. Sonuç normal çıkıyor yaklaşık 5985 gibi bir rakam elde ediyorum ki buda komut gecikmesi yada benim tuşa basma hızımdan kaynaklanıyor olabilir zira doğru sonuç 6000 çıkması lazım ama tam gereken anda tuşlara basarsan bu sonucu görebilirsin teorik olarak.

İki ayrı deneme yaptım. Ekrana yazma kısmını kaldırdım ve sıfırlama yaptıktan sonra tam 1 dak dolunca diğer tuşa basınca son değeri ekrana yazdırdım. Bu şekilde mükemmele yakın sonuç alınıyor. İkinci denemede ,
Senin yaptığın gibi sürekli olarak sayac değerini ekrana yazdırırsam 5600-5700 aralığında bir değer yakalayabiliyorum. Buda ekrana yazdırmanın bile bu işte ne kadar etkili olduğunu gösteriyor.

Programlar lişiktedir. En azından asıl devrende hex'i deneyebilirsin.

Ete

M.A.A

Hocam şimdi deneme fırsatım oldu. Sizin hazırladığınız hex i gerçek devrede denedim. 6000 e yakın değerler çıktı.
Söylediğiniz gibi DWORD leri WORD yapınca benim yazdığım kod da 6000 e yakın değerler çıkardı. İlk fırsatta TMR0H=0 ın bu durumda etkisi olup olmadığını falan deneyeceğim. Sonuçları yazarım.

İlginiz için çok teşekkür ederim

Hattuşa

ete hocam Dword değişkeni yüzünden sıkıntı yapıyorsa,
2 word değerinden Dword oluşturarak çözüm üretilemez mi? yeni kesme içerisinde;

dim sayac1 as word
dim sayac2 as word
dim sayac as Dword


sayac1 =sayac1 +1
if sayac 1=65535 then sayac2 =sayac2 +1

yazılıp ana döngüde ekrana print ederken

sayac =(sayac2 *65535) +sayac1

print at 4,1,dec6 sayac

şeklinde yazarsak hata ortadan kalkabilir diye düşünüyorum. doğru mu?

ete

Bana kalırsa bu işte Dword hiç gerekli değil. Tabiiki bu iş söylenen sınırla riçinde çalışıyor ise.
Bu bakımdan boşuna komut gecikmesi yaratmamak için dword işine hiç girilmemesi daha uygun olacaktır.

Senin sunduğun çözüm aslında çözüm de değil. Zira sen word değişkenleri ile dword yaratmaya çalışıyorsun. Dword kullanınca bunu derleyici yaptıracak zaten. Sorun o değişkenlerin ekrana yazdırılmasında. Yoksa Dword sayması sorun teşkil etmez diye düşünüyorum.
Ama en iyi çözün Dword yerine Word değişkeni kullanmak v ebunuda ispatlamış olduk zaten.

Ete

M.A.A

pro-Tr ilgin için çok teşekkür ederim. Dword değişkeninin değerini artırmak değil, LCD ekrana bastırırken geçikme oluyor. Ben baştan sınırları geniş tutmak için DWORD tanımlamıştır. 6000 civarı sayacağı için şuanlık WORD işimi görüyor. Senin daha önce söylediğin gibi 16Bit ile hassasiyeti artıracağım ilerde.

Ete hocam DWORD yazdırırken yaşanan gecikme Proton Basic in LCD ekrana yazarken kesmeleri kapattığı anlamına gelmiyor mu. Böyle ise az veya çok mutlaka kesme süresini etkiler. Sizin yukarıda bahsettiğiniz 2. deneme yi (sadece sonuç basmak için LCD ekranın kullanılması) gerçek devrede yapıp farkı bildireceğim.

Diğer programlama dillerinde de bu durum var mıdır ?

ete

Diğer programlama dillerinde varmıdır yokmudur bilemiyeceğim. Kullanmıyorum çünki.
İmkanı olan birisi C dilinde deneyebilirse anlayabiliriz.

Ete

Hattuşa

slm ete hocam;
ben bu konu ile ilgili GLCD de defalarca sorun yaşadım. bir türlü çözemedim en son çözümüm ise print edeceğim değerleri imkanım varsa byte yoksa word tipi değişkenlere atayarak aşmaya çalıştım. aşağıda bir görüntü ekledim. yaptığım işlem ise şu;
4 farklı değişken belirledim.
1.float
2.dword
3.word
4.byte

belirlediğim bu değerleri ana programda saydırıp, tek tek ekrana print ettim. ekrana print ederkende osilaskop girişlerini işlemcinin belirli pinlerine bağlayarak printten hemen önce bir pini high yapıp, print işlemi bittiğinde o pini lowa çektim. sonuç şu;
float ve dword değişkenlerinin print süreleri 20ms, word ve byte değişkenlerinin print süreleri 980uS

kod şu şekilde;
Dim Sayi As Float
Dim SaY As Dword
Dim Sa As Word
Dim Ss As Byte
Dim ZAMAN As Byte

SaY =0
Sa =0
Ss =0

BASLA:
Inc Sayi
Inc SaY
Inc Sa
Inc Ss
PORTB.0 =1
Print At 1,1,Dec Sayi,"  "
PORTB.0 =0
PORTB.1 =1
Print At 2,1,Dec SaY,"  "
PORTB.1 =0
PORTB.2 =1
Print At 3,1,Dec Sa,"  "
PORTB.2 =0
PORTB.3 =1
Print At 4,1,Dec Ss,"  "
PORTB.3 =0
DelayMS 200




GoTo BASLA


ekran görüntüsüde bu şekilde, sanrım lcdler ile işlemciler seriladen haberleştiği için float ve dword değişkenlerini 4 byte şeklinde yolladığı için süre uzuyor. yanlışmıyım hocam?

ete

10 ms de bir kesme oluşturacak bir programın bir değişken değerini 20 ms de göstermesi demek bu tür gecikmelerin olması kaçınılmaz demek oluyor. Elbette Dword 4 adet byte değişkeninden oluşuyor. Aslında 2 adedi 980us de gönderen sistem neden 2 tane daha eklenince bunu 2 ms de yapmıyorda 20 ms de yapıyor bunuda anlamak imkansız. 2 tane word gibi yollasa 2 ms de işlem tamamlanacak ama olmuyor demekki.

Ete

M.A.A

Değişik denemeler yaptım.
Öncelikle dahili osilatör yerine 8Mhz Kristal ve 22pF bağladım. İki tuş arası sayımdaki çevresel etkileri aza indirmek için 5 dk bekleyerek sayaç değerlerini aldım.


Ana Çevrimde - Print At 4,1, Dec SINYALSAYAC  ,"        " , Dec SINYALSAYAC2    'Değişkenler Dword iken 5980
Ana Çevrimde - Print At 4,1, Dec SINYALSAYAC  ,"        " , Dec SINYALSAYAC2   'Değişkenler Word iken 26840
Ana Çevrimde - Print At 3,1, "dddddddd1234567890" ' Var iken 29055
Ana Çevrimde - Print At 3,1, "d" :Print At 3,2, "d" :Print At 3,3, "d" :Print At 3,4, "d" :Print At 3,5, "d"
                         Print At 3,6, "d" :Print At 3,7, "d" :Print At 3,8, "d" :Print At 3,9, "d" :Print At 3,10, "d"
                         Print At 3,11, "d" :Print At 3,12, "d" :Print At 3,13, "d" :Print At 3,14, "d" :Print At 3,15, "d"     'Var iken 29565
Ana Çevrimde Sadece tuş kontrol var iken 29840
Değerlerini aldım.

Sonuç olarak Proton Basic de LCD ekranın çalışması TIMER0 kesmesini etkiliyor. En az etkileyen ise her harf için ayrı kod satırı yazmamız.


M.A.A

Bir önceki yazımdaki denemelerdeki ideale yakın olanı dikkate alarak aşağıdaki kodu yazdım. 5 dakika da 29609 saydım.

Device = 18F4620


Config_Start
   OSC = HS ; Internal oscillator block, port function on RA6 and RA7
   PWRT = OFF ; PWRT disabled
   BOREN = OFF ; Brown-out Reset disabled in hardware and software
   BORV = 0 ; Maximum setting
   WDT = OFF ; WDT disabled (control is placed on the SWDTEN bit)
   MCLRE = OFF ; RE3 input pin enabled; MCLR disabled
   PBADEN = OFF ; PORTB<4:0> pins are configured as digital I/O on Reset
   LVP = OFF ; Single-Supply ICSP disabled
   CP0 = On ; Block 0 (000800-001FFFh) code-protected
   CP1 = On ; Block 1 (002000-003FFFh) code-protected
   CP2 = On ; Block 2 (004000-005FFFh) code-protected
   CP3 = On ; Block 3 (006000-007FFFh) code-protected
   CPB = On ; Boot block (000000-0007FFh) code-protected
   WRTD = OFF ; Data EEPROM not write-protected
Config_End


'LCD TANIMLAMALARI,,,,,,,,,,,,,,,,,,,,
Declare LCD_Type Alphanumeric        '
Declare LCD_DTPin PORTD.0            '
Declare LCD_ENPin PORTC.0     'e     '
Declare LCD_RSPin PORTC.1     'rs    '
Declare LCD_Interface 4              '
Declare LCD_Lines 4                  '
'''''''''''''''''''''''''''''''''''''
Declare All_Digital = True
SDA var PORTC.4                     ' RTC data
SCL var PORTC.3                     ' RTC clock

CIKIS VAR PORTA.0

UZ1 VAR PORTB.7  'GİRİŞ
UZ2 VAR PORTB.6  'GİRİŞ
TRISB.7=1  'GİRİŞ
TRISB.6=1  'GİRİŞ
TRISA.0=0  'ÇIKIŞ

'Değişkenler,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

Dim SINYALSAYAC As Word
Dim SINYALSAYAC2 As Word
Dim SEGMENGSAYAC As Word 
Dim ZAMAN As Byte
Dim S As Byte
Dim S1 As Byte
Dim S2 As Byte
Dim S3 As Byte
Dim S4 As Byte
Dim S5 As Byte




ZAMAN=99
TMR0H=0


'interrupt,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
On Interrupt GoTo KESME
INTCON=%11100000
'timer,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
T0CON=%11000110
TMR0L=ZAMAN
INTCON.2=0

ADCON1=%00001111
CMCON=07h

SINYALSAYAC=0


BASLA:

If UZ1=0 Then  SINYALSAYAC=0
If UZ2=0 Then  SINYALSAYAC2=SINYALSAYAC

S1=SINYALSAYAC/10000
S=S1+48
Print At 3,1, S
S2= (SINYALSAYAC-(S1*10000))/1000
S=S2+48
Print At 3,2, S
S3= (SINYALSAYAC-(S1*10000)-(S2*1000))/100
S=S3+48
Print At 3,3, S
S4= (SINYALSAYAC-(S1*10000)-(S2*1000)-(S3*100))/10
S=S4+48
Print At 3,4, S
S5= SINYALSAYAC-(S1*10000)-(S2*1000)-(S3*100)-(S4*10)
S=S5+48
Print At 3,5, S

S1=SINYALSAYAC2/10000
S=S1+48
Print At 3,9, S
S2= (SINYALSAYAC2-(S1*10000))/1000
S=S2+48
Print At 3,10, S
S3= (SINYALSAYAC2-(S1*10000)-(S2*1000))/100
S=S3+48
Print At 3,11, S
S4= (SINYALSAYAC2-(S1*10000)-(S2*1000)-(S3*100))/10
S=S4+48
Print At 3,12, S
S5= SINYALSAYAC2-(S1*10000)-(S2*1000)-(S3*100)-(S4*10)
S=S5+48
Print At 3,13, S

     
GoTo BASLA


Disable
KESME:     
     SINYALSAYAC=SINYALSAYAC+1


     TMR0L=ZAMAN       
     INTCON.2=0        'TMR0 Kesme bayrağı sıfırlanıyor
     Resume
     Enable

End

Maxim

proton da lcd ekran komutu yada delayms bekleme komutu interruptı etkilemez!
sizde niye etkiliyor? çünkü siz hardware interrupt komutu yerine basic kesmesi kullanıyorsunuz ondan.

On Interrupt GoTo KESME bu yazılımdan interrupt komutudur
On_Interrupt GoTo KESME bu gerçek hardware interrupt (yazı kırmızı olur)

her ikisinin kullanım kuralları biraz farklıdır

M.A.A

pro-TR daha önce donanımsal kullanmamı söyleyip kod vermişti, kodu denediğimde bendekine benzer sonuç verdiği için üzerine çok düşmemiştim. Düşmemekte hata etmişim. Maxim de yazdıktan sonra kendi kodumu donanımsal kesme ye çevirdim. Proteus ta denedim, Dword bile yazsam doğru zamanda kesmeye giriyor. pro-TR nin yazdığı kodu tekrar denedim, 20ms de bir kesmeye giriyor. Benim ilk yazdığım yazılımsal kesme de de Dword yazdırdığımda 20ms de bir kesmeye girdiği için aynı gibi düşündüm. pro-TR kusura bakmasın. Gerçek devrede de deneyince sonucu yazarım.


Powered by EzPortal